/[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 53 by schoenebeck, Mon Apr 26 17:15:51 2004 UTC revision 157 by senkov, Tue Jun 29 00:50:38 2004 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck         *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *                                                                         *   *                                                                         *
7   *   This program is free software; you can redistribute it and/or modify  *   *   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  *   *   it under the terms of the GNU General Public License as published by  *
# 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) : 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");
         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");  
         }  
   
         if (AutoConnectPortID) ConnectToAlsaMidiSource(AutoConnectPortID);  
36      }      }
37    
38      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {      MidiInputDeviceAlsa::~MidiInputDeviceAlsa() {
39          //TODO: close Alsa seq              snd_seq_close(hAlsaSeq);
40        }
41    
42        MidiInputDeviceAlsa::MidiInputPortAlsa::MidiInputPortAlsa(MidiInputDeviceAlsa* pDevice, int alsaPort) : MidiInputPort(pDevice, alsaPort) {
43                Parameters["alsa_seq_bindings"] = new ParameterAlsaSeqBindings(this);
44        }
45    
46        MidiInputDeviceAlsa::MidiInputPortAlsa::~MidiInputPortAlsa() {
47                snd_seq_delete_simple_port(pDevice->hAlsaSeq, portNumber);
48        }
49    
50        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      void MidiInputDeviceAlsa::Listen() {      void MidiInputDeviceAlsa::Listen() {
# Line 70  namespace LinuxSampler { Line 72  namespace LinuxSampler {
72      *                (e.g. "64:0")      *                (e.g. "64:0")
73      * @throws MidiInputException  if connection cannot be established      * @throws MidiInputException  if connection cannot be established
74      */      */
75      void MidiInputDeviceAlsa::ConnectToAlsaMidiSource(const char* MidiSource) {      void MidiInputDeviceAlsa::MidiInputPortAlsa::ConnectToAlsaMidiSource(const char* MidiSource) {
76          snd_seq_addr_t sender, dest;          snd_seq_addr_t sender, dest;
77          snd_seq_port_subscribe_t* subs;          snd_seq_port_subscribe_t* subs;
78          int hExtClient, hExtPort;          int hExtClient, hExtPort;
# Line 78  namespace LinuxSampler { Line 80  namespace LinuxSampler {
80          sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort);          sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort);
81          sender.client = (char) hExtClient;          sender.client = (char) hExtClient;
82          sender.port   = (char) hExtPort;          sender.port   = (char) hExtPort;
83          dest.client   = (char) this->hAlsaSeqClient;          dest.client   = (char) pDevice->hAlsaSeqClient;
84          dest.port     = (char) this->hAlsaSeqPort;          dest.port     = (char) portNumber;
85          snd_seq_port_subscribe_alloca(&subs);          snd_seq_port_subscribe_alloca(&subs);
86          snd_seq_port_subscribe_set_sender(subs, &sender);          snd_seq_port_subscribe_set_sender(subs, &sender);
87          snd_seq_port_subscribe_set_dest(subs, &dest);          snd_seq_port_subscribe_set_dest(subs, &dest);
88          snd_seq_port_subscribe_set_queue(subs, 1);          snd_seq_port_subscribe_set_queue(subs, 1);
89          snd_seq_port_subscribe_set_time_update(subs, 1);          snd_seq_port_subscribe_set_time_update(subs, 1);
90          snd_seq_port_subscribe_set_time_real(subs, 1);          snd_seq_port_subscribe_set_time_real(subs, 1);
91          if (snd_seq_subscribe_port(this->hAlsaSeq, subs) < 0)          if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0)
92              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) + ")");
93      }      }
94    
95        String MidiInputDeviceAlsa::Description() {
96                return "Advanced Linux Sound Architecture";
97        }
98    
99        String MidiInputDeviceAlsa::Version() {
100                String s = "$Revision: 1.6 $";
101                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      int MidiInputDeviceAlsa::Main() {      int MidiInputDeviceAlsa::Main() {
112          int npfd;          int npfd;
113          struct pollfd* pfd;          struct pollfd* pfd;
# Line 102  namespace LinuxSampler { Line 120  namespace LinuxSampler {
120              if (poll(pfd, npfd, 100000) > 0) {              if (poll(pfd, npfd, 100000) > 0) {
121                  do {                  do {
122                      snd_seq_event_input(hAlsaSeq, &ev);                      snd_seq_event_input(hAlsaSeq, &ev);
123                        int port = (int) ev->dest.port;
124                        MidiInputPort* pMidiInputPort = Ports[port];
125    
126                      switch (ev->type) {                      switch (ev->type) {
127                          case SND_SEQ_EVENT_CONTROLLER:                          case SND_SEQ_EVENT_CONTROLLER:
128                              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);
129                              break;                              break;
130    
131                          case SND_SEQ_EVENT_PITCHBEND:                          case SND_SEQ_EVENT_PITCHBEND:
132                            //  fprintf(stderr, "Pitchbender event on Channel %2d: %5d   \n",                            //  fprintf(stderr, "Pitchbender event on Channel %2d: %5d   \n",
133                            //          ev->data.control.channel, ev->data.control.value);                            //          ev->data.control.channel, ev->data.control.value);
134                              DispatchPitchbend(ev->data.control.value, ev->data.control.channel);                              pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel);
135                              break;                              break;
136    
137                          case SND_SEQ_EVENT_NOTEON:                          case SND_SEQ_EVENT_NOTEON:
138                              if (ev->data.note.velocity != 0) {                              if (ev->data.note.velocity != 0) {
139                                  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);
140                              }                              }
141                              else {                              else {
142                                  DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);                                  pMidiInputPort->DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel);
143                              }                              }
144                              break;                              break;
145    
146                          case SND_SEQ_EVENT_NOTEOFF:                          case SND_SEQ_EVENT_NOTEOFF:
147                              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);
148                              break;                              break;
149                      }                      }
150                      snd_seq_free_event(ev);                      snd_seq_free_event(ev);

Legend:
Removed from v.53  
changed lines
  Added in v.157

  ViewVC Help
Powered by ViewVC