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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 68 by senkov, Sat May 8 19:03:17 2004 UTC revision 153 by senkov, Mon Jun 28 04:21:11 2004 UTC
# Line 21  Line 21 
21   ***************************************************************************/   ***************************************************************************/
22    
23  #include "MidiInputDeviceAlsa.h"  #include "MidiInputDeviceAlsa.h"
24    #include "MidiInputDeviceFactory.h"
25    
26  namespace LinuxSampler {  namespace LinuxSampler {
27    
28      /**          REGISTER_MIDI_INPUT_DRIVER("Alsa",MidiInputDeviceAlsa);
29       * Create Alsa MIDI input device for LinuxSampler. Opens and initializes  
30       * Alsa sequencer client and creates one Alsa MIDI input port for      MidiInputDeviceAlsa::MidiInputDeviceAlsa(std::map<String,String> Parameters) : MidiInputDevice(CreateParameters(Parameters)), Thread(true, 1, -1) {
      * LinuxSampler. The optional argument allows to auto connect to a Alsa  
      * MIDI source (e.g. a software sequencer or a hardware MIDI input  
      * port).  
      *  
      * @param AutoConnectPortID - (optional) Alsa client and port ID of a  
      *                            MIDI source we should auto connect to  
      *                            (e.g. "64:0")  
      * @throws MidiInputException  if initialization failed  
      */  
     MidiInputDeviceAlsa::MidiInputDeviceAlsa(char* AutoConnectPortID) : MidiInputDevice(MidiInputDevice::type_alsa), Thread(true, 1, -1) {  
31          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
32              throw MidiInputException("Error opening ALSA sequencer");              throw MidiInputException("Error opening ALSA sequencer");
33          }          }
34          this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);          this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);
35          snd_seq_set_client_name(hAlsaSeq, "LinuxSampler");          snd_seq_set_client_name(hAlsaSeq, "LinuxSampler");
36          if ((this->hAlsaSeqPort = snd_seq_create_simple_port(hAlsaSeq, "LinuxSampler",      }
                                                              SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,  
                                                              SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {  
             throw MidiInputException("Error creating sequencer port");  
         }  
37    
38          if (AutoConnectPortID) ConnectToAlsaMidiSource(AutoConnectPortID);      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {
39                snd_seq_close(hAlsaSeq);
40      }      }
41    
42      void MidiInputDeviceAlsa::SetInputPort(const char * MidiSource) {      MidiInputDeviceAlsa::MidiInputPortAlsa::MidiInputPortAlsa(MidiInputDeviceAlsa* pDevice, int alsaPort) : MidiInputPort(pDevice, alsaPort) {
43              ConnectToAlsaMidiSource(MidiSource);              this->pDevice = pDevice;
44                Parameters = MidiInputDevice::MidiInputPort::AvailableParameters();
45                Parameters["alsa_seq_bindings"] = new ParameterAlsaSeqBindings(this);
46      }      }
47    
48      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {      MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {
49          //TODO: close Alsa seq              snd_seq_delete_simple_port(pDevice->hAlsaSeq, portNumber);
50        }
51    
52        MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {
53                int alsaPort;
54                if ((alsaPort = snd_seq_create_simple_port(hAlsaSeq, "LinuxSampler",
55                                                SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
56                                                SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
57                        throw MidiInputException("Error creating sequencer port");
58                }
59                return ( new MidiInputPortAlsa(this, alsaPort) );
60      }      }
61    
62      void MidiInputDeviceAlsa::Listen() {      void MidiInputDeviceAlsa::Listen() {
# Line 74  namespace LinuxSampler { Line 74  namespace LinuxSampler {
74      *                (e.g. "64:0")      *                (e.g. "64:0")
75      * @throws MidiInputException  if connection cannot be established      * @throws MidiInputException  if connection cannot be established
76      */      */
77      void MidiInputDeviceAlsa::ConnectToAlsaMidiSource(const char* MidiSource) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ConnectToAlsaMidiSource(const char* MidiSource) {
78          snd_seq_addr_t sender, dest;          snd_seq_addr_t sender, dest;
79          snd_seq_port_subscribe_t* subs;          snd_seq_port_subscribe_t* subs;
80          int hExtClient, hExtPort;          int hExtClient, hExtPort;
# Line 82  namespace LinuxSampler { Line 82  namespace LinuxSampler {
82          sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort);          sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort);
83          sender.client = (char) hExtClient;          sender.client = (char) hExtClient;
84          sender.port   = (char) hExtPort;          sender.port   = (char) hExtPort;
85          dest.client   = (char) this->hAlsaSeqClient;          dest.client   = (char) pDevice->hAlsaSeqClient;
86          dest.port     = (char) this->hAlsaSeqPort;          dest.port     = (char) portNumber;
87          snd_seq_port_subscribe_alloca(&subs);          snd_seq_port_subscribe_alloca(&subs);
88          snd_seq_port_subscribe_set_sender(subs, &sender);          snd_seq_port_subscribe_set_sender(subs, &sender);
89          snd_seq_port_subscribe_set_dest(subs, &dest);          snd_seq_port_subscribe_set_dest(subs, &dest);
90          snd_seq_port_subscribe_set_queue(subs, 1);          snd_seq_port_subscribe_set_queue(subs, 1);
91          snd_seq_port_subscribe_set_time_update(subs, 1);          snd_seq_port_subscribe_set_time_update(subs, 1);
92          snd_seq_port_subscribe_set_time_real(subs, 1);          snd_seq_port_subscribe_set_time_real(subs, 1);
93          if (snd_seq_subscribe_port(this->hAlsaSeq, subs) < 0)          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0)
94              throw MidiInputException(String("Unable to connect to Alsa seq client \'") + MidiSource + "\' (" + snd_strerror(errno) + ")");              throw MidiInputException(String("Unable to connect to Alsa seq client \'") + MidiSource + "\' (" + snd_strerror(errno) + ")");
95      }      }
96    
97        String MidiInputDeviceAlsa::Description() {
98                return "Advanced Linux Sound Architecture";
99        }
100    
101        String MidiInputDeviceAlsa::Version() {
102                String s = "$Revision: 1.5 $";
103                return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
104        }
105    
106        std::map<String,DeviceCreationParameter*> MidiInputDeviceAlsa::CreateParameters(std::map<String,String> Parameters) {
107                 std::map<String,DeviceCreationParameter*> result;
108                 result["active"] = OptionalParameter<ParameterActive>::New(this, Parameters["active"]);
109                 result["ports"] = OptionalParameter<ParameterPorts>::New(this, Parameters["ports"]);
110                 return result;
111        }
112    
113      int MidiInputDeviceAlsa::Main() {      int MidiInputDeviceAlsa::Main() {
114          int npfd;          int npfd;
115          struct pollfd* pfd;          struct pollfd* pfd;
# Line 106  namespace LinuxSampler { Line 122  namespace LinuxSampler {
122              if (poll(pfd, npfd, 100000) > 0) {              if (poll(pfd, npfd, 100000) > 0) {
123                  do {                  do {
124                      snd_seq_event_input(hAlsaSeq, &ev);                      snd_seq_event_input(hAlsaSeq, &ev);
125                        int port = (int) ev->dest.port;
126                        MidiInputPort* pMidiInputPort = Ports[port];
127    
128                      switch (ev->type) {                      switch (ev->type) {
129                          case SND_SEQ_EVENT_CONTROLLER:                          case SND_SEQ_EVENT_CONTROLLER:
130                              DispatchControlChange(ev->data.control.param, ev->data.control.value, ev->data.control.channel);                              pMidiInputPort->DispatchControlChange(ev->data.control.param, ev->data.control.value, ev->data.control.channel);
131                              break;                              break;
132    
133                          case SND_SEQ_EVENT_PITCHBEND:                          case SND_SEQ_EVENT_PITCHBEND:
134                            //  fprintf(stderr, "Pitchbender event on Channel %2d: %5d   \n",                            //  fprintf(stderr, "Pitchbender event on Channel %2d: %5d   \n",
135                            //          ev->data.control.channel, ev->data.control.value);                            //          ev->data.control.channel, ev->data.control.value);
136                              DispatchPitchbend(ev->data.control.value, ev->data.control.channel);                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
137                              break;                              break;
138    
139                          case SND_SEQ_EVENT_NOTEON:                          case SND_SEQ_EVENT_NOTEON:
140                              if (ev->data.note.velocity != 0) {                              if (ev->data.note.velocity != 0) {
141                                  DispatchNoteOn(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);                                  pMidiInputPort->DispatchNoteOn(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
142                              }                              }
143                              else {                              else {
144                                  DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);                                  pMidiInputPort->DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);
145                              }                              }
146                              break;                              break;
147    
148                          case SND_SEQ_EVENT_NOTEOFF:                          case SND_SEQ_EVENT_NOTEOFF:
149                              DispatchNoteOff(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);                              pMidiInputPort->DispatchNoteOff(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel);
150                              break;                              break;
151                      }                      }
152                      snd_seq_free_event(ev);                      snd_seq_free_event(ev);

Legend:
Removed from v.68  
changed lines
  Added in v.153

  ViewVC Help
Powered by ViewVC