/[svn]/linuxsampler/trunk/src/mididriver/MidiInputDeviceAlsa.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/mididriver/MidiInputDeviceAlsa.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 157 - (hide annotations) (download)
Tue Jun 29 00:50:38 2004 UTC (19 years, 9 months ago) by senkov
File size: 7263 byte(s)
* Removed/cleaned up some left over stuff
* Fixed midi port name parameter (no longer static)

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 53 * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "MidiInputDeviceAlsa.h"
24 senkov 153 #include "MidiInputDeviceFactory.h"
25 schoenebeck 53
26     namespace LinuxSampler {
27    
28 senkov 153 REGISTER_MIDI_INPUT_DRIVER("Alsa",MidiInputDeviceAlsa);
29    
30     MidiInputDeviceAlsa::MidiInputDeviceAlsa(std::map<String,String> Parameters) : MidiInputDevice(CreateParameters(Parameters)), Thread(true, 1, -1) {
31 schoenebeck 53 if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
32     throw MidiInputException("Error opening ALSA sequencer");
33     }
34     this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);
35     snd_seq_set_client_name(hAlsaSeq, "LinuxSampler");
36 senkov 153 }
37 schoenebeck 53
38 senkov 153 MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {
39     snd_seq_close(hAlsaSeq);
40 schoenebeck 53 }
41    
42 senkov 153 MidiInputDeviceAlsa::MidiInputPortAlsa::MidiInputPortAlsa(MidiInputDeviceAlsa* pDevice, int alsaPort) : MidiInputPort(pDevice, alsaPort) {
43     Parameters["alsa_seq_bindings"] = new ParameterAlsaSeqBindings(this);
44 senkov 68 }
45    
46 senkov 153 MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {
47     snd_seq_delete_simple_port(pDevice->hAlsaSeq, portNumber);
48 schoenebeck 53 }
49    
50 senkov 153 MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {
51     int alsaPort;
52     if ((alsaPort = snd_seq_create_simple_port(hAlsaSeq, "LinuxSampler",
53     SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
54     SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
55     throw MidiInputException("Error creating sequencer port");
56     }
57     return ( new MidiInputPortAlsa(this, alsaPort) );
58     }
59    
60 schoenebeck 53 void MidiInputDeviceAlsa::Listen() {
61     StartThread();
62     }
63    
64     void MidiInputDeviceAlsa::StopListen() {
65     StopThread();
66     }
67    
68     /**
69     * Connects this Alsa midi input device with an Alsa MIDI source.
70     *
71     * @param Client - Alsa sequencer client and port ID of a MIDI source
72     * (e.g. "64:0")
73     * @throws MidiInputException if connection cannot be established
74     */
75 senkov 153 void MidiInputDeviceAlsa::MidiInputPortAlsa::ConnectToAlsaMidiSource(const char* MidiSource) {
76 schoenebeck 53 snd_seq_addr_t sender, dest;
77     snd_seq_port_subscribe_t* subs;
78     int hExtClient, hExtPort;
79    
80     sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort);
81     sender.client = (char) hExtClient;
82     sender.port = (char) hExtPort;
83 senkov 153 dest.client = (char) pDevice->hAlsaSeqClient;
84     dest.port = (char) portNumber;
85 schoenebeck 53 snd_seq_port_subscribe_alloca(&subs);
86     snd_seq_port_subscribe_set_sender(subs, &sender);
87     snd_seq_port_subscribe_set_dest(subs, &dest);
88     snd_seq_port_subscribe_set_queue(subs, 1);
89     snd_seq_port_subscribe_set_time_update(subs, 1);
90     snd_seq_port_subscribe_set_time_real(subs, 1);
91 senkov 153 if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0)
92 schoenebeck 53 throw MidiInputException(String("Unable to connect to Alsa seq client \'") + MidiSource + "\' (" + snd_strerror(errno) + ")");
93     }
94    
95 senkov 153 String MidiInputDeviceAlsa::Description() {
96     return "Advanced Linux Sound Architecture";
97     }
98    
99     String MidiInputDeviceAlsa::Version() {
100 senkov 157 String s = "$Revision: 1.6 $";
101 senkov 153 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
102     }
103    
104     std::map<String,DeviceCreationParameter*> MidiInputDeviceAlsa::CreateParameters(std::map<String,String> Parameters) {
105     std::map<String,DeviceCreationParameter*> result;
106     result["active"] = OptionalParameter<ParameterActive>::New(this, Parameters["active"]);
107     result["ports"] = OptionalParameter<ParameterPorts>::New(this, Parameters["ports"]);
108     return result;
109     }
110    
111 schoenebeck 53 int MidiInputDeviceAlsa::Main() {
112     int npfd;
113     struct pollfd* pfd;
114     snd_seq_event_t* ev;
115    
116     npfd = snd_seq_poll_descriptors_count(hAlsaSeq, POLLIN);
117     pfd = (struct pollfd*) alloca(npfd * sizeof(struct pollfd));
118     snd_seq_poll_descriptors(hAlsaSeq, pfd, npfd, POLLIN);
119     while (true) {
120     if (poll(pfd, npfd, 100000) > 0) {
121     do {
122     snd_seq_event_input(hAlsaSeq, &ev);
123 senkov 153 int port = (int) ev->dest.port;
124     MidiInputPort* pMidiInputPort = Ports[port];
125    
126 schoenebeck 53 switch (ev->type) {
127     case SND_SEQ_EVENT_CONTROLLER:
128 senkov 153 pMidiInputPort->DispatchControlChange(ev->data.control.param, ev->data.control.value, ev->data.control.channel);
129 schoenebeck 53 break;
130    
131     case SND_SEQ_EVENT_PITCHBEND:
132     // fprintf(stderr, "Pitchbender event on Channel %2d: %5d \n",
133     // ev->data.control.channel, ev->data.control.value);
134 senkov 153 pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
135 schoenebeck 53 break;
136    
137     case SND_SEQ_EVENT_NOTEON:
138     if (ev->data.note.velocity != 0) {
139 senkov 153 pMidiInputPort->DispatchNoteOn(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
140 schoenebeck 53 }
141     else {
142 senkov 153 pMidiInputPort->DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);
143 schoenebeck 53 }
144     break;
145    
146     case SND_SEQ_EVENT_NOTEOFF:
147 senkov 153 pMidiInputPort->DispatchNoteOff(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
148 schoenebeck 53 break;
149     }
150     snd_seq_free_event(ev);
151     } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);
152     }
153     }
154     }
155    
156     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC