/[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 551 by schoenebeck, Tue May 17 18:16:54 2005 UTC revision 1993 by schoenebeck, Sun Aug 30 11:27:35 2009 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 Christian Schoenebeck                              *   *   Copyright (C) 2005 - 2009 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 28  Line 28 
28    
29  namespace LinuxSampler {  namespace LinuxSampler {
30    
31        /// number of currently existing ALSA midi input devices in LinuxSampler
32        static int existingAlsaDevices = 0;
33    
34  // *************** ParameterName ***************  // *************** ParameterName ***************
35  // *  // *
36    
37      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())) {
38          OnSetValue(ValueAsString()); // initialize port name          OnSetValue(ValueAsString()); // initialize port name
39      }      }
40    
41      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::OnSetValue(String s) throw (LinuxSamplerException) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterName::OnSetValue(String s) throw (Exception) {
42          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)");
43          snd_seq_port_info_t* hInfo;          snd_seq_port_info_t* hInfo;
44          snd_seq_port_info_malloc(&hInfo);          snd_seq_port_info_malloc(&hInfo);
45          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 85  namespace LinuxSampler { Line 88  namespace LinuxSampler {
88          return res;          return res;
89      }      }
90    
91      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::OnSetValue(std::vector<String> vS) throw (LinuxSamplerException) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::OnSetValue(std::vector<String> vS) throw (Exception) {
92            pPort->UnsubscribeAll();
93    
94          std::vector<String>::iterator iter = vS.begin();          std::vector<String>::iterator iter = vS.begin();
95          for (; iter != vS.end(); iter++) pPort->ConnectToAlsaMidiSource((*iter).c_str());          for (; iter != vS.end(); iter++) pPort->ConnectToAlsaMidiSource((*iter).c_str());
96      }      }
# Line 117  namespace LinuxSampler { Line 122  namespace LinuxSampler {
122    
123    
124    
125    // *************** MidiInputDeviceAlsa::ParameterName ***************
126    // *
127    
128        MidiInputDeviceAlsa::ParameterName::ParameterName() : DeviceCreationParameterString() {
129            InitWithDefault(); // use default name
130        }
131    
132        MidiInputDeviceAlsa::ParameterName::ParameterName(String s) : DeviceCreationParameterString(s) {
133        }
134    
135        String MidiInputDeviceAlsa::ParameterName::Description() {
136            return "Arbitrary ALSA client name";
137        }
138    
139        bool MidiInputDeviceAlsa::ParameterName::Fix() {
140            return true;
141        }
142    
143        bool MidiInputDeviceAlsa::ParameterName::Mandatory() {
144            return false;
145        }
146    
147        std::map<String,DeviceCreationParameter*> MidiInputDeviceAlsa::ParameterName::DependsAsParameters() {
148            return std::map<String,DeviceCreationParameter*>(); // no dependencies
149        }
150    
151        std::vector<String> MidiInputDeviceAlsa::ParameterName::PossibilitiesAsString(std::map<String,String> Parameters) {
152            return std::vector<String>();
153        }
154    
155        optional<String> MidiInputDeviceAlsa::ParameterName::DefaultAsString(std::map<String,String> Parameters) {
156            return (existingAlsaDevices) ? "LinuxSampler" + ToString(existingAlsaDevices) : "LinuxSampler";
157        }
158    
159        void MidiInputDeviceAlsa::ParameterName::OnSetValue(String s) throw (Exception) {
160            // not possible, as parameter is fix
161        }
162    
163        String MidiInputDeviceAlsa::ParameterName::Name() {
164            return "NAME";
165        }
166    
167    
168    
169  // *************** MidiInputPortAlsa ***************  // *************** MidiInputPortAlsa ***************
170  // *  // *
171    
# Line 130  namespace LinuxSampler { Line 179  namespace LinuxSampler {
179          if (alsaPort < 0) throw MidiInputException("Error creating sequencer port");          if (alsaPort < 0) throw MidiInputException("Error creating sequencer port");
180          this->portNumber = alsaPort;          this->portNumber = alsaPort;
181    
182            delete Parameters["NAME"];
183          Parameters["NAME"]              = new ParameterName(this);          Parameters["NAME"]              = new ParameterName(this);
184          Parameters["ALSA_SEQ_BINDINGS"] = new ParameterAlsaSeqBindings(this);          Parameters["ALSA_SEQ_BINDINGS"] = new ParameterAlsaSeqBindings(this);
185          Parameters["ALSA_SEQ_ID"]       = new ParameterAlsaSeqId(this);          Parameters["ALSA_SEQ_ID"]       = new ParameterAlsaSeqId(this);
186      }      }
187    
188      MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {      MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {
189              snd_seq_delete_simple_port(pDevice->hAlsaSeq, portNumber);          UnsubscribeAll();
190            snd_seq_delete_simple_port(pDevice->hAlsaSeq, portNumber);
191      }      }
192    
193      /**      /**
# Line 156  namespace LinuxSampler { Line 207  namespace LinuxSampler {
207          sender.port   = (char) hExtPort;          sender.port   = (char) hExtPort;
208          dest.client   = (char) pDevice->hAlsaSeqClient;          dest.client   = (char) pDevice->hAlsaSeqClient;
209          dest.port     = (char) portNumber;          dest.port     = (char) portNumber;
210          snd_seq_port_subscribe_alloca(&subs);          snd_seq_port_subscribe_malloc(&subs);
211          snd_seq_port_subscribe_set_sender(subs, &sender);          snd_seq_port_subscribe_set_sender(subs, &sender);
212          snd_seq_port_subscribe_set_dest(subs, &dest);          snd_seq_port_subscribe_set_dest(subs, &dest);
213          snd_seq_port_subscribe_set_queue(subs, 1);          snd_seq_port_subscribe_set_queue(subs, 1);
214          snd_seq_port_subscribe_set_time_update(subs, 1);          snd_seq_port_subscribe_set_time_update(subs, 1);
215          snd_seq_port_subscribe_set_time_real(subs, 1);          snd_seq_port_subscribe_set_time_real(subs, 1);
216          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0)          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0) {
217                snd_seq_port_subscribe_free(subs);
218              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) + ")");
219      }          }
220    
221            subscriptions.push_back(subs);
222        }
223    
224        void MidiInputDeviceAlsa::MidiInputPortAlsa::UnsubscribeAll() {
225            for (std::vector<snd_seq_port_subscribe_t*>::iterator it = subscriptions.begin();
226                 it != subscriptions.end(); it++) {
227                if (snd_seq_unsubscribe_port(pDevice->hAlsaSeq, *it)) {
228                    dmsg(1,("MidiInputPortAlsa::UnsubscribeAll: Can't unsubscribe port connection!.\n"));
229                }
230                snd_seq_port_subscribe_free(*it);
231            }
232            subscriptions.clear();
233        }
234    
235  // *************** MidiInputDeviceAlsa ***************  // *************** MidiInputDeviceAlsa ***************
236  // *  // *
# Line 175  namespace LinuxSampler { Line 239  namespace LinuxSampler {
239          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {          if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
240              throw MidiInputException("Error opening ALSA sequencer");              throw MidiInputException("Error opening ALSA sequencer");
241          }          }
242            existingAlsaDevices++;
243          this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);          this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);
244          snd_seq_set_client_name(hAlsaSeq, "LinuxSampler");          snd_seq_set_client_name(hAlsaSeq, ((DeviceCreationParameterString*)Parameters["NAME"])->ValueAsString().c_str());
245          AcquirePorts(((DeviceCreationParameterInt*)Parameters["PORTS"])->ValueAsInt());          AcquirePorts(((DeviceCreationParameterInt*)Parameters["PORTS"])->ValueAsInt());
246          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {          if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
247                  Listen();              Listen();
248          }          }
249      }      }
250    
251      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {
252              snd_seq_close(hAlsaSeq);          // free the midi ports (we can't let the base class do this,
253            // as the MidiInputPortAlsa destructors need access to
254            // hAlsaSeq)
255            for (std::map<int,MidiInputPort*>::iterator iter = Ports.begin(); iter != Ports.end() ; iter++) {
256                delete static_cast<MidiInputPortAlsa*>(iter->second);
257            }
258            Ports.clear();
259    
260            snd_seq_close(hAlsaSeq);
261            existingAlsaDevices--; //FIXME: this is too simple, can lead to multiple clients with the same name
262      }      }
263    
264      MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {      MidiInputDeviceAlsa::MidiInputPortAlsa* MidiInputDeviceAlsa::CreateMidiPort() {
# Line 212  namespace LinuxSampler { Line 286  namespace LinuxSampler {
286      }      }
287    
288      String MidiInputDeviceAlsa::Version() {      String MidiInputDeviceAlsa::Version() {
289              String s = "$Revision: 1.15 $";              String s = "$Revision: 1.24 $";
290              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
291      }      }
292    
# Line 233  namespace LinuxSampler { Line 307  namespace LinuxSampler {
307    
308                      switch (ev->type) {                      switch (ev->type) {
309                          case SND_SEQ_EVENT_CONTROLLER:                          case SND_SEQ_EVENT_CONTROLLER:
310                                if (ev->data.control.param == 0)
311                                    pMidiInputPort->DispatchBankSelectMsb(ev->data.control.value, ev->data.control.channel);
312                                else if (ev->data.control.param == 32)
313                                    pMidiInputPort->DispatchBankSelectLsb(ev->data.control.value, ev->data.control.channel);
314                              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);
315                              break;                              break;
316    
317                            case SND_SEQ_EVENT_CHANPRESS:
318                                pMidiInputPort->DispatchControlChange(128, ev->data.control.value, ev->data.control.channel);
319                                break;
320    
321                          case SND_SEQ_EVENT_PITCHBEND:                          case SND_SEQ_EVENT_PITCHBEND:
322                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
323                              break;                              break;
# Line 265  namespace LinuxSampler { Line 347  namespace LinuxSampler {
347                  } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);                  } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0);
348              }              }
349          }          }
350            // just to avoid a compiler warning
351            return EXIT_FAILURE;
352      }      }
353    
354  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.551  
changed lines
  Added in v.1993

  ViewVC Help
Powered by ViewVC