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

Diff of /linuxsampler/trunk/src/drivers/midi/MidiInputDeviceAlsa.cpp

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

revision 221 by schoenebeck, Fri Aug 20 17:25:19 2004 UTC revision 1715 by schoenebeck, Tue Mar 11 15:20:46 2008 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 - 2008 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 23  Line 24 
24  #include "MidiInputDeviceAlsa.h"  #include "MidiInputDeviceAlsa.h"
25  #include "MidiInputDeviceFactory.h"  #include "MidiInputDeviceFactory.h"
26    
27  namespace LinuxSampler {  #define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
   
     REGISTER_MIDI_INPUT_DRIVER(MidiInputDeviceAlsa);  
   
     /* Common parameters */  
     REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceAlsa, ParameterActive);  
     REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDeviceAlsa, ParameterPorts);  
   
28    
29    namespace LinuxSampler {
30    
31  // *************** ParameterName ***************  // *************** ParameterName ***************
32  // *  // *
33    
34      MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::ParameterName(MidiInputPort* pPort) throw (LinuxSamplerException) : MidiInputPort::ParameterName(pPort, "Port " + ToString(pPort->GetPortNumber())) {      MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::ParameterName(MidiInputPort* pPort) throw (Exception) : MidiInputPort::ParameterName(pPort, "Port " + ToString(pPort->GetPortNumber())) {
35          OnSetValue(ValueAsString()); // initialize port name          OnSetValue(ValueAsString()); // initialize port name
36      }      }
37    
38      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::OnSetValue(String s) throw (LinuxSamplerException) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::OnSetValue(String s) throw (Exception) {
39          if (s.size() > 16) throw LinuxSamplerException("Name too long for ALSA MIDI input port (max. 16 characters)");          if (s.size() > 16) throw Exception("Name too long for ALSA MIDI input port (max. 16 characters)");
40          snd_seq_port_info_t* hInfo;          snd_seq_port_info_t* hInfo;
41          snd_seq_port_info_malloc(&hInfo);          snd_seq_port_info_malloc(&hInfo);
42          snd_seq_get_port_info(((MidiInputDeviceAlsa*)pPort->GetDevice())->hAlsaSeq, pPort->GetPortNumber(), hInfo);          snd_seq_get_port_info(((MidiInputDeviceAlsa*)pPort->GetDevice())->hAlsaSeq, pPort->GetPortNumber(), hInfo);
# Line 68  namespace LinuxSampler { Line 63  namespace LinuxSampler {
63      }      }
64    
65      std::vector<String> MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::PossibilitiesAsString() {      std::vector<String> MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::PossibilitiesAsString() {
66          return std::vector<String>(); //TODO          std::vector<String> res;
67            snd_seq_client_info_t* cinfo;
68            snd_seq_port_info_t* pinfo;
69    
70            snd_seq_client_info_alloca(&cinfo);
71            snd_seq_port_info_alloca(&pinfo);
72            snd_seq_client_info_set_client(cinfo, -1);
73            while (snd_seq_query_next_client(pPort->pDevice->hAlsaSeq, cinfo) >= 0) {
74                snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
75                snd_seq_port_info_set_port(pinfo, -1);
76                while (snd_seq_query_next_port(pPort->pDevice->hAlsaSeq, pinfo) >= 0) {
77                    if (perm_ok(pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) {
78                            String seq_id = ToString(snd_seq_client_info_get_client(cinfo)) + ":" +
79                                            ToString(snd_seq_port_info_get_port(pinfo));
80                            res.push_back(seq_id);
81                    }
82                }
83            }
84    
85            return res;
86      }      }
87    
88      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::OnSetValue(std::vector<String> vS) throw (LinuxSamplerException) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::OnSetValue(std::vector<String> vS) throw (Exception) {
89            std::vector<snd_seq_port_subscribe_t*>::iterator it = pPort->subscriptions.begin();
90            for (; it != pPort->subscriptions.end(); it++) {
91                if(snd_seq_unsubscribe_port(pPort->pDevice->hAlsaSeq, *it)) {
92                    dmsg(1,("ParameterAlsaSeqBindings::OnSetValue: Can't unsubscribe port connection!.\n"));
93                }
94                snd_seq_port_subscribe_free(*it);
95            }
96            pPort->subscriptions.clear();
97    
98          std::vector<String>::iterator iter = vS.begin();          std::vector<String>::iterator iter = vS.begin();
99          for (; iter != vS.end(); iter++) pPort->ConnectToAlsaMidiSource((*iter).c_str());          for (; iter != vS.end(); iter++) pPort->ConnectToAlsaMidiSource((*iter).c_str());
100      }      }
101    
102    
103    
104    // *************** ParameterAlsaSeqId ***************
105    // *
106    
107        MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqId::ParameterAlsaSeqId(MidiInputPortAlsa* pPort)
108            : DeviceRuntimeParameterString(ToString(pPort->pDevice->hAlsaSeqClient) + ":" + ToString(pPort->portNumber)) {
109        }
110    
111        String MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqId::Description() {
112            return "ALSA Sequencer ID";
113        }
114    
115        bool MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqId::Fix() {
116            return true;
117        }
118    
119        std::vector<String> MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqId::PossibilitiesAsString() {
120            return std::vector<String>(); // nothing
121        }
122    
123        void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqId::OnSetValue(String s) {
124            // not possible as parameter is 'fix'
125        }
126    
127    
128    
129  // *************** MidiInputPortAlsa ***************  // *************** MidiInputPortAlsa ***************
130  // *  // *
131    
# Line 91  namespace LinuxSampler { Line 139  namespace LinuxSampler {
139          if (alsaPort < 0) throw MidiInputException("Error creating sequencer port");          if (alsaPort < 0) throw MidiInputException("Error creating sequencer port");
140          this->portNumber = alsaPort;          this->portNumber = alsaPort;
141    
142            delete Parameters["NAME"];
143          Parameters["NAME"]              = new ParameterName(this);          Parameters["NAME"]              = new ParameterName(this);
144          Parameters["ALSA_SEQ_BINDINGS"] = new ParameterAlsaSeqBindings(this);          Parameters["ALSA_SEQ_BINDINGS"] = new ParameterAlsaSeqBindings(this);
145            Parameters["ALSA_SEQ_ID"]       = new ParameterAlsaSeqId(this);
146      }      }
147    
148      MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {      MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {
# Line 116  namespace LinuxSampler { Line 166  namespace LinuxSampler {
166          sender.port   = (char) hExtPort;          sender.port   = (char) hExtPort;
167          dest.client   = (char) pDevice->hAlsaSeqClient;          dest.client   = (char) pDevice->hAlsaSeqClient;
168          dest.port     = (char) portNumber;          dest.port     = (char) portNumber;
169          snd_seq_port_subscribe_alloca(&subs);          snd_seq_port_subscribe_malloc(&subs);
170          snd_seq_port_subscribe_set_sender(subs, &sender);          snd_seq_port_subscribe_set_sender(subs, &sender);
171          snd_seq_port_subscribe_set_dest(subs, &dest);          snd_seq_port_subscribe_set_dest(subs, &dest);
172          snd_seq_port_subscribe_set_queue(subs, 1);          snd_seq_port_subscribe_set_queue(subs, 1);
173          snd_seq_port_subscribe_set_time_update(subs, 1);          snd_seq_port_subscribe_set_time_update(subs, 1);
174          snd_seq_port_subscribe_set_time_real(subs, 1);          snd_seq_port_subscribe_set_time_real(subs, 1);
175          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0)          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0) {
176                snd_seq_port_subscribe_free(subs);
177              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) + ")");
178            }
179    
180            subscriptions.push_back(subs);
181      }      }
182    
183    
# Line 131  namespace LinuxSampler { Line 185  namespace LinuxSampler {
185  // *************** MidiInputDeviceAlsa ***************  // *************** MidiInputDeviceAlsa ***************
186  // *  // *
187    
188      MidiInputDeviceAlsa::MidiInputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters) : MidiInputDevice(Parameters), Thread(true, 1, -1) {      MidiInputDeviceAlsa::MidiInputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters, void* pSampler) : MidiInputDevice(Parameters, pSampler), Thread(true, true, 1, -1) {
189          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
190              throw MidiInputException("Error opening ALSA sequencer");              throw MidiInputException("Error opening ALSA sequencer");
191          }          }
# Line 144  namespace LinuxSampler { Line 198  namespace LinuxSampler {
198      }      }
199    
200      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {
201              snd_seq_close(hAlsaSeq);          // free the midi ports (we can't let the base class do this,
202            // as the MidiInputPortAlsa destructors need access to
203            // hAlsaSeq)
204            for (std::map<int,MidiInputPort*>::iterator iter = Ports.begin(); iter != Ports.end() ; iter++) {
205                delete static_cast<MidiInputPortAlsa*>(iter->second);
206            }
207            Ports.clear();
208    
209            snd_seq_close(hAlsaSeq);
210      }      }
211    
212      MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {      MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {
# Line 172  namespace LinuxSampler { Line 234  namespace LinuxSampler {
234      }      }
235    
236      String MidiInputDeviceAlsa::Version() {      String MidiInputDeviceAlsa::Version() {
237              String s = "$Revision: 1.9 $";              String s = "$Revision: 1.22 $";
238              return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword              return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
239      }      }
240    
# Line 193  namespace LinuxSampler { Line 255  namespace LinuxSampler {
255    
256                      switch (ev->type) {                      switch (ev->type) {
257                          case SND_SEQ_EVENT_CONTROLLER:                          case SND_SEQ_EVENT_CONTROLLER:
258                                if (ev->data.control.param == 0)
259                                    pMidiInputPort->DispatchBankSelectMsb(ev->data.control.value, ev->data.control.channel);
260                                else if (ev->data.control.param == 32)
261                                    pMidiInputPort->DispatchBankSelectLsb(ev->data.control.value, ev->data.control.channel);
262                              pMidiInputPort->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);
263                              break;                              break;
264    
265                            case SND_SEQ_EVENT_CHANPRESS:
266                                pMidiInputPort->DispatchControlChange(128, ev->data.control.value, ev->data.control.channel);
267                                break;
268    
269                          case SND_SEQ_EVENT_PITCHBEND:                          case SND_SEQ_EVENT_PITCHBEND:
                           //  fprintf(stderr, "Pitchbender event on Channel %2d: %5d   \n",  
                           //          ev->data.control.channel, ev->data.control.value);  
270                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
271                              break;                              break;
272    
# Line 214  namespace LinuxSampler { Line 282  namespace LinuxSampler {
282                          case SND_SEQ_EVENT_NOTEOFF:                          case SND_SEQ_EVENT_NOTEOFF:
283                              pMidiInputPort->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);
284                              break;                              break;
285    
286                            case SND_SEQ_EVENT_SYSEX:
287                                pMidiInputPort->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);
288                                break;
289    
290                            case SND_SEQ_EVENT_PGMCHANGE:
291                                pMidiInputPort->DispatchProgramChange(ev->data.control.value, ev->data.control.channel);
292                                break;
293                      }                      }
294                      snd_seq_free_event(ev);                      snd_seq_free_event(ev);
295                  } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);                  } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);
296              }              }
297          }          }
298            // just to avoid a compiler warning
299            return EXIT_FAILURE;
300      }      }
301    
302  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.221  
changed lines
  Added in v.1715

  ViewVC Help
Powered by ViewVC