/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/network/lscpserver.cpp

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

revision 226 by schoenebeck, Wed Aug 25 22:00:33 2004 UTC revision 1047 by schoenebeck, Mon Feb 19 19:38:04 2007 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 - 2007 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This library 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  *
10   *   the Free Software Foundation; either version 2 of the License, or     *   *   the Free Software Foundation; either version 2 of the License, or     *
11   *   (at your option) any later version.                                   *   *   (at your option) any later version.                                   *
12   *                                                                         *   *                                                                         *
13   *   This program is distributed in the hope that it will be useful,       *   *   This library is distributed in the hope that it will be useful,       *
14   *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *   *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16   *   GNU General Public License for more details.                          *   *   GNU General Public License for more details.                          *
17   *                                                                         *   *                                                                         *
18   *   You should have received a copy of the GNU General Public License     *   *   You should have received a copy of the GNU General Public License     *
19   *   along with this program; if not, write to the Free Software           *   *   along with this library; if not, write to the Free Software           *
20   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21   *   MA  02111-1307  USA                                                   *   *   MA  02111-1307  USA                                                   *
22   ***************************************************************************/   ***************************************************************************/
# Line 23  Line 24 
24  #include "lscpserver.h"  #include "lscpserver.h"
25  #include "lscpresultset.h"  #include "lscpresultset.h"
26  #include "lscpevent.h"  #include "lscpevent.h"
27    #include "../common/global.h"
28    
29  #include "../engines/gig/Engine.h"  #include <fcntl.h>
30    
31    #if HAVE_SQLITE3
32    # include "sqlite3.h"
33    #endif
34    
35    #include "../engines/EngineFactory.h"
36    #include "../engines/EngineChannelFactory.h"
37  #include "../drivers/audio/AudioOutputDeviceFactory.h"  #include "../drivers/audio/AudioOutputDeviceFactory.h"
38  #include "../drivers/midi/MidiInputDeviceFactory.h"  #include "../drivers/midi/MidiInputDeviceFactory.h"
39    
# Line 50  std::map< LSCPEvent::event_t, std::list< Line 59  std::map< LSCPEvent::event_t, std::list<
59  Mutex LSCPServer::NotifyMutex = Mutex();  Mutex LSCPServer::NotifyMutex = Mutex();
60  Mutex LSCPServer::NotifyBufferMutex = Mutex();  Mutex LSCPServer::NotifyBufferMutex = Mutex();
61  Mutex LSCPServer::SubscriptionMutex = Mutex();  Mutex LSCPServer::SubscriptionMutex = Mutex();
62    Mutex LSCPServer::RTNotifyMutex = Mutex();
63    
64  LSCPServer::LSCPServer(Sampler* pSampler) : Thread(false, 0, -4) {  LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4) {
65        SocketAddress.sin_family      = AF_INET;
66        SocketAddress.sin_addr.s_addr = addr;
67        SocketAddress.sin_port        = port;
68      this->pSampler = pSampler;      this->pSampler = pSampler;
69      LSCPEvent::RegisterEvent(LSCPEvent::event_channels, "CHANNELS");      LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
70        LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
71        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_count, "MIDI_INPUT_DEVICE_COUNT");
72        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_info, "MIDI_INPUT_DEVICE_INFO");
73        LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");
74      LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
75      LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
76      LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");      LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
77      LSCPEvent::RegisterEvent(LSCPEvent::event_info, "INFO");      LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");
78        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_count, "MIDI_INSTRUMENT_MAP_COUNT");
79        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_info, "MIDI_INSTRUMENT_MAP_INFO");
80        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_count, "MIDI_INSTRUMENT_COUNT");
81        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_info, "MIDI_INSTRUMENT_INFO");
82      LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");      LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
83        LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");
84        hSocket = -1;
85    }
86    
87    LSCPServer::~LSCPServer() {
88        if (hSocket >= 0) close(hSocket);
89  }  }
90    
91  /**  /**
# Line 76  int LSCPServer::WaitUntilInitialized(lon Line 103  int LSCPServer::WaitUntilInitialized(lon
103  }  }
104    
105  int LSCPServer::Main() {  int LSCPServer::Main() {
106      int hSocket = socket(AF_INET, SOCK_STREAM, 0);      hSocket = socket(AF_INET, SOCK_STREAM, 0);
107      if (hSocket < 0) {      if (hSocket < 0) {
108          std::cerr << "LSCPServer: Could not create server socket." << std::endl;          std::cerr << "LSCPServer: Could not create server socket." << std::endl;
109          //return -1;          //return -1;
110          exit(EXIT_FAILURE);          exit(EXIT_FAILURE);
111      }      }
112    
     SocketAddress.sin_family      = AF_INET;  
     SocketAddress.sin_port        = htons(LSCP_PORT);  
     SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);  
   
113      if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {      if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
114          std::cerr << "LSCPServer: Could not bind server socket." << std::endl;          std::cerr << "LSCPServer: Could not bind server socket, retrying for " << ToString(LSCP_SERVER_BIND_TIMEOUT) << " seconds...";
115          close(hSocket);          for (int trial = 0; true; trial++) { // retry for LSCP_SERVER_BIND_TIMEOUT seconds
116          //return -1;              if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
117          exit(EXIT_FAILURE);                  if (trial > LSCP_SERVER_BIND_TIMEOUT) {
118                        std::cerr << "gave up!" << std::endl;
119                        close(hSocket);
120                        //return -1;
121                        exit(EXIT_FAILURE);
122                    }
123                    else sleep(1); // sleep 1s
124                }
125                else break; // success
126            }
127      }      }
128    
129      listen(hSocket, 1);      listen(hSocket, 1);
# Line 104  int LSCPServer::Main() { Line 136  int LSCPServer::Main() {
136      FD_SET(hSocket, &fdSet);      FD_SET(hSocket, &fdSet);
137      int maxSessions = hSocket;      int maxSessions = hSocket;
138    
139        timeval timeout;
140    
141      while (true) {      while (true) {
142          fd_set selectSet = fdSet;          // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers
143          int retval = select(maxSessions+1, &selectSet, NULL, NULL, NULL);          {
144                std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
145                std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
146                std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();
147                for (; itEngineChannel != itEnd; ++itEngineChannel) {
148                    if ((*itEngineChannel)->StatusChanged()) {
149                        SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));
150                    }
151                }
152            }
153    
154            //Now let's deliver late notifies (if any)
155            NotifyBufferMutex.Lock();
156            for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
157    #ifdef MSG_NOSIGNAL
158                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), MSG_NOSIGNAL);
159    #else
160                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
161    #endif
162            }
163            bufferedNotifies.clear();
164            NotifyBufferMutex.Unlock();
165    
166            fd_set selectSet = fdSet;
167            timeout.tv_sec  = 0;
168            timeout.tv_usec = 100000;
169    
170            int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
171    
172          if (retval == 0)          if (retval == 0)
173                  continue; //Nothing try again                  continue; //Nothing try again
174          if (retval == -1) {          if (retval == -1) {
# Line 150  int LSCPServer::Main() { Line 212  int LSCPServer::Main() {
212                                  int dummy; // just a temporary hack to fulfill the restart() function prototype                                  int dummy; // just a temporary hack to fulfill the restart() function prototype
213                                  restart(NULL, dummy); // restart the 'scanner'                                  restart(NULL, dummy); // restart the 'scanner'
214                                  currentSocket = (*iter).hSession;  //a hack                                  currentSocket = (*iter).hSession;  //a hack
215                                    dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
216                                  if ((*iter).bVerbose) { // if echo mode enabled                                  if ((*iter).bVerbose) { // if echo mode enabled
217                                      AnswerClient(bufferedCommands[currentSocket]);                                      AnswerClient(bufferedCommands[currentSocket]);
218                                  }                                  }
# Line 165  int LSCPServer::Main() { Line 228  int LSCPServer::Main() {
228                          break;                          break;
229                  }                  }
230          }          }
   
         //Now let's deliver late notifies (if any)  
         NotifyBufferMutex.Lock();  
         for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {  
                 send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);  
                 bufferedNotifies.erase(iterNotify);  
         }  
         NotifyBufferMutex.Unlock();  
231      }      }
232  }  }
233    
# Line 194  void LSCPServer::CloseConnection( std::v Line 249  void LSCPServer::CloseConnection( std::v
249          NotifyMutex.Unlock();          NotifyMutex.Unlock();
250  }  }
251    
252    int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
253            int subs = 0;
254            SubscriptionMutex.Lock();
255            for( std::list<LSCPEvent::event_t>::iterator iter = events.begin();
256                            iter != events.end(); iter++)
257            {
258                    subs += eventSubscriptions.count(*iter);
259            }
260            SubscriptionMutex.Unlock();
261            return subs;
262    }
263    
264  void LSCPServer::SendLSCPNotify( LSCPEvent event ) {  void LSCPServer::SendLSCPNotify( LSCPEvent event ) {
265          SubscriptionMutex.Lock();          SubscriptionMutex.Lock();
266          if (eventSubscriptions.count(event.GetType()) == 0) {          if (eventSubscriptions.count(event.GetType()) == 0) {
# Line 207  void LSCPServer::SendLSCPNotify( LSCPEve Line 274  void LSCPServer::SendLSCPNotify( LSCPEve
274          while (true) {          while (true) {
275                  if (NotifyMutex.Trylock()) {                  if (NotifyMutex.Trylock()) {
276                          for(;iter != end; iter++)                          for(;iter != end; iter++)
277    #ifdef MSG_NOSIGNAL
278                                    send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);
279    #else
280                                  send(*iter, notify.c_str(), notify.size(), 0);                                  send(*iter, notify.c_str(), notify.size(), 0);
281    #endif
282                          NotifyMutex.Unlock();                          NotifyMutex.Unlock();
283                          break;                          break;
284                  } else {                  } else {
# Line 259  bool LSCPServer::GetLSCPCommand( std::ve Line 330  bool LSCPServer::GetLSCPCommand( std::ve
330                                  continue; //Ignore CR                                  continue; //Ignore CR
331                          if (c == '\n') {                          if (c == '\n') {
332                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
333                                  bufferedCommands[socket] += "\n";                                  bufferedCommands[socket] += "\r\n";
334                                  return true; //Complete command was read                                  return true; //Complete command was read
335                          }                          }
336                          bufferedCommands[socket] += c;                          bufferedCommands[socket] += c;
# Line 316  void LSCPServer::AnswerClient(String Ret Line 387  void LSCPServer::AnswerClient(String Ret
387      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
388      if (currentSocket != -1) {      if (currentSocket != -1) {
389              NotifyMutex.Lock();              NotifyMutex.Lock();
390    #ifdef MSG_NOSIGNAL
391                send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
392    #else
393              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
394    #endif
395              NotifyMutex.Unlock();              NotifyMutex.Unlock();
396      }      }
397  }  }
# Line 360  String LSCPServer::CreateAudioOutputDevi Line 435  String LSCPServer::CreateAudioOutputDevi
435          AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);          AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
436          // search for the created device to get its index          // search for the created device to get its index
437          int index = GetAudioOutputDeviceIndex(pDevice);          int index = GetAudioOutputDeviceIndex(pDevice);
438          if (index == -1) throw LinuxSamplerException("Internal error: could not find created audio output device.");          if (index == -1) throw Exception("Internal error: could not find created audio output device.");
439          result = index; // success          result = index; // success
440      }      }
441      catch (LinuxSamplerException e) {      catch (Exception e) {
442          result.Error(e);          result.Error(e);
443      }      }
444      return result.Produce();      return result.Produce();
# Line 376  String LSCPServer::CreateMidiInputDevice Line 451  String LSCPServer::CreateMidiInputDevice
451          MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);          MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
452          // search for the created device to get its index          // search for the created device to get its index
453          int index = GetMidiInputDeviceIndex(pDevice);          int index = GetMidiInputDeviceIndex(pDevice);
454          if (index == -1) throw LinuxSamplerException("Internal error: could not find created midi input device.");          if (index == -1) throw Exception("Internal error: could not find created midi input device.");
455          result = index; // success          result = index; // success
456      }      }
457      catch (LinuxSamplerException e) {      catch (Exception e) {
458          result.Error(e);          result.Error(e);
459      }      }
460      return result.Produce();      return result.Produce();
# Line 390  String LSCPServer::DestroyAudioOutputDev Line 465  String LSCPServer::DestroyAudioOutputDev
465      LSCPResultSet result;      LSCPResultSet result;
466      try {      try {
467          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
468          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
469          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
470          pSampler->DestroyAudioOutputDevice(pDevice);          pSampler->DestroyAudioOutputDevice(pDevice);
471      }      }
472      catch (LinuxSamplerException e) {      catch (Exception e) {
473          result.Error(e);          result.Error(e);
474      }      }
475      return result.Produce();      return result.Produce();
# Line 405  String LSCPServer::DestroyMidiInputDevic Line 480  String LSCPServer::DestroyMidiInputDevic
480      LSCPResultSet result;      LSCPResultSet result;
481      try {      try {
482          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
483          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
484          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
485          pSampler->DestroyMidiInputDevice(pDevice);          pSampler->DestroyMidiInputDevice(pDevice);
486      }      }
487      catch (LinuxSamplerException e) {      catch (Exception e) {
488          result.Error(e);          result.Error(e);
489      }      }
490      return result.Produce();      return result.Produce();
# Line 423  String LSCPServer::LoadInstrument(String Line 498  String LSCPServer::LoadInstrument(String
498      LSCPResultSet result;      LSCPResultSet result;
499      try {      try {
500          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
501          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
502          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
503          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
504          if (!pSamplerChannel->GetAudioOutputDevice())          if (!pSamplerChannel->GetAudioOutputDevice())
505              throw LinuxSamplerException("No audio output device on channel");              throw Exception("No audio output device connected to sampler channel");
506          if (bBackground) {          if (bBackground) {
507              LSCPLoadInstrument *pLoadInstrument = new LSCPLoadInstrument(pEngine, Filename.c_str(), uiInstrument);              InstrumentManager::instrument_id_t id;
508              pLoadInstrument->StartThread();              id.FileName = Filename;
509                id.Index    = uiInstrument;
510                InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
511            }
512            else {
513                // tell the engine channel which instrument to load
514                pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrument);
515                // actually start to load the instrument (blocks until completed)
516                pEngineChannel->LoadInstrument();
517          }          }
         else pEngine->LoadInstrument(Filename.c_str(), uiInstrument);  
518      }      }
519      catch (LinuxSamplerException e) {      catch (Exception e) {
520           result.Error(e);           result.Error(e);
521      }      }
522      return result.Produce();      return result.Produce();
523  }  }
524    
525  /**  /**
526   * Will be called by the parser to load and deploy an engine.   * Will be called by the parser to assign a sampler engine type to a
527     * sampler channel.
528   */   */
529  String LSCPServer::LoadEngine(String EngineName, uint uiSamplerChannel) {  String LSCPServer::SetEngineType(String EngineName, uint uiSamplerChannel) {
530      dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));      dmsg(2,("LSCPServer: SetEngineType(EngineName=%s,uiSamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
531      LSCPResultSet result;      LSCPResultSet result;
532      try {      try {
         Engine::type_t type;  
         if ((EngineName == "GigEngine") || (EngineName == "gig")) type = Engine::type_gig;  
         else throw LinuxSamplerException("Unknown engine type");  
533          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
534          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
535          pSamplerChannel->LoadEngine(type);          LockRTNotify();
536            pSamplerChannel->SetEngineType(EngineName);
537            if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
538            UnlockRTNotify();
539      }      }
540      catch (LinuxSamplerException e) {      catch (Exception e) {
541           result.Error(e);           result.Error(e);
542      }      }
543      return result.Produce();      return result.Produce();
# Line 492  String LSCPServer::ListChannels() { Line 575  String LSCPServer::ListChannels() {
575   */   */
576  String LSCPServer::AddChannel() {  String LSCPServer::AddChannel() {
577      dmsg(2,("LSCPServer: AddChannel()\n"));      dmsg(2,("LSCPServer: AddChannel()\n"));
578        LockRTNotify();
579      SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();      SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
580        UnlockRTNotify();
581      LSCPResultSet result(pSamplerChannel->Index());      LSCPResultSet result(pSamplerChannel->Index());
582      return result.Produce();      return result.Produce();
583  }  }
# Line 503  String LSCPServer::AddChannel() { Line 588  String LSCPServer::AddChannel() {
588  String LSCPServer::RemoveChannel(uint uiSamplerChannel) {  String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
589      dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));      dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
590      LSCPResultSet result;      LSCPResultSet result;
591        LockRTNotify();
592      pSampler->RemoveSamplerChannel(uiSamplerChannel);      pSampler->RemoveSamplerChannel(uiSamplerChannel);
593        UnlockRTNotify();
594      return result.Produce();      return result.Produce();
595  }  }
596    
597  /**  /**
598   * Will be called by the parser to get all available engines.   * Will be called by the parser to get the amount of all available engines.
599   */   */
600  String LSCPServer::GetAvailableEngines() {  String LSCPServer::GetAvailableEngines() {
601      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
602      LSCPResultSet result("GigEngine");      LSCPResultSet result;
603        try {
604            int n = EngineFactory::AvailableEngineTypes().size();
605            result.Add(n);
606        }
607        catch (Exception e) {
608            result.Error(e);
609        }
610        return result.Produce();
611    }
612    
613    /**
614     * Will be called by the parser to get a list of all available engines.
615     */
616    String LSCPServer::ListAvailableEngines() {
617        dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
618        LSCPResultSet result;
619        try {
620            String s = EngineFactory::AvailableEngineTypesAsString();
621            result.Add(s);
622        }
623        catch (Exception e) {
624            result.Error(e);
625        }
626      return result.Produce();      return result.Produce();
627  }  }
628    
629  /**  /**
630   * Will be called by the parser to get descriptions for a particular engine.   * Will be called by the parser to get descriptions for a particular
631     * sampler engine.
632   */   */
633  String LSCPServer::GetEngineInfo(String EngineName) {  String LSCPServer::GetEngineInfo(String EngineName) {
634      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
635      LSCPResultSet result;      LSCPResultSet result;
636        LockRTNotify();
637      try {      try {
638          if ((EngineName == "GigEngine") || (EngineName == "gig")) {          Engine* pEngine = EngineFactory::Create(EngineName);
639              Engine* pEngine = new LinuxSampler::gig::Engine;          result.Add("DESCRIPTION", pEngine->Description());
640              result.Add("DESCRIPTION", pEngine->Description());          result.Add("VERSION",     pEngine->Version());
641              result.Add("VERSION",     pEngine->Version());          EngineFactory::Destroy(pEngine);
             delete pEngine;  
         }  
         else throw LinuxSamplerException("Unknown engine type");  
642      }      }
643      catch (LinuxSamplerException e) {      catch (Exception e) {
644           result.Error(e);           result.Error(e);
645      }      }
646        UnlockRTNotify();
647      return result.Produce();      return result.Produce();
648  }  }
649    
# Line 546  String LSCPServer::GetChannelInfo(uint u Line 656  String LSCPServer::GetChannelInfo(uint u
656      LSCPResultSet result;      LSCPResultSet result;
657      try {      try {
658          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
659          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
660          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
661    
662          //Defaults values          //Defaults values
663          String EngineName = "NONE";          String EngineName = "NONE";
664          float Volume = 0.0f;          float Volume = 0.0f;
665          String InstrumentFileName = "NONE";          String InstrumentFileName = "NONE";
666            String InstrumentName = "NONE";
667          int InstrumentIndex = -1;          int InstrumentIndex = -1;
668          int InstrumentStatus = -1;          int InstrumentStatus = -1;
669          int AudioOutputChannels = 0;          int AudioOutputChannels = 0;
670          String AudioRouting;          String AudioRouting;
671            int Mute = 0;
672          if (pEngine) {          bool Solo = false;
673              EngineName =  pEngine->EngineName();          String MidiInstrumentMap;
674              AudioOutputChannels = pEngine->Channels();  
675              Volume = pEngine->Volume();          if (pEngineChannel) {
676              InstrumentStatus = pEngine->InstrumentStatus();              EngineName          = pEngineChannel->EngineName();
677              InstrumentIndex = pEngine->InstrumentIndex();              AudioOutputChannels = pEngineChannel->Channels();
678              if (InstrumentIndex != -1)              Volume              = pEngineChannel->Volume();
679                  InstrumentFileName = pEngine->InstrumentFileName();              InstrumentStatus    = pEngineChannel->InstrumentStatus();
680              for (int chan = 0; chan < pEngine->Channels(); chan++) {              InstrumentIndex     = pEngineChannel->InstrumentIndex();
681                if (InstrumentIndex != -1) {
682                    InstrumentFileName = pEngineChannel->InstrumentFileName();
683                    InstrumentName     = pEngineChannel->InstrumentName();
684                }
685                for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
686                  if (AudioRouting != "") AudioRouting += ",";                  if (AudioRouting != "") AudioRouting += ",";
687                  AudioRouting += ToString(pEngine->OutputChannel(chan));                  AudioRouting += ToString(pEngineChannel->OutputChannel(chan));
688              }              }
689                Mute = pEngineChannel->GetMute();
690                Solo = pEngineChannel->GetSolo();
691                if (pEngineChannel->UsesNoMidiInstrumentMap())
692                    MidiInstrumentMap = "NONE";
693                else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
694                    MidiInstrumentMap = "DEFAULT";
695                else
696                    MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
697          }          }
698    
699          result.Add("ENGINE_NAME", EngineName);          result.Add("ENGINE_NAME", EngineName);
# Line 582  String LSCPServer::GetChannelInfo(uint u Line 706  String LSCPServer::GetChannelInfo(uint u
706    
707          result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));          result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
708          result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());          result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
709          if (pSamplerChannel->GetMidiInputChannel()) result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());          if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
710          else                                        result.Add("MIDI_INPUT_CHANNEL", "ALL");          else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
711    
712          result.Add("INSTRUMENT_FILE", InstrumentFileName);          result.Add("INSTRUMENT_FILE", InstrumentFileName);
713          result.Add("INSTRUMENT_NR", InstrumentIndex);          result.Add("INSTRUMENT_NR", InstrumentIndex);
714            result.Add("INSTRUMENT_NAME", InstrumentName);
715          result.Add("INSTRUMENT_STATUS", InstrumentStatus);          result.Add("INSTRUMENT_STATUS", InstrumentStatus);
716            result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
717            result.Add("SOLO", Solo);
718            result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
719      }      }
720      catch (LinuxSamplerException e) {      catch (Exception e) {
721           result.Error(e);           result.Error(e);
722      }      }
723      return result.Produce();      return result.Produce();
# Line 604  String LSCPServer::GetVoiceCount(uint ui Line 732  String LSCPServer::GetVoiceCount(uint ui
732      LSCPResultSet result;      LSCPResultSet result;
733      try {      try {
734          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
735          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
736          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
737          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");
738          result.Add(pEngine->VoiceCount());          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
739            result.Add(pEngineChannel->GetEngine()->VoiceCount());
740      }      }
741      catch (LinuxSamplerException e) {      catch (Exception e) {
742           result.Error(e);           result.Error(e);
743      }      }
744      return result.Produce();      return result.Produce();
# Line 624  String LSCPServer::GetStreamCount(uint u Line 753  String LSCPServer::GetStreamCount(uint u
753      LSCPResultSet result;      LSCPResultSet result;
754      try {      try {
755          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
756          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
757          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
758          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
759          result.Add(pEngine->DiskStreamCount());          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
760            result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
761      }      }
762      catch (LinuxSamplerException e) {      catch (Exception e) {
763           result.Error(e);           result.Error(e);
764      }      }
765      return result.Produce();      return result.Produce();
# Line 644  String LSCPServer::GetBufferFill(fill_re Line 774  String LSCPServer::GetBufferFill(fill_re
774      LSCPResultSet result;      LSCPResultSet result;
775      try {      try {
776          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
777          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
778          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
779          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
780          if (!pEngine->DiskStreamSupported())          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
781              result.Add("NA");          if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
782          else {          else {
783              switch (ResponseType) {              switch (ResponseType) {
784                  case fill_response_bytes:                  case fill_response_bytes:
785                      result.Add(pEngine->DiskStreamBufferFillBytes());                      result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillBytes());
786                      break;                      break;
787                  case fill_response_percentage:                  case fill_response_percentage:
788                      result.Add(pEngine->DiskStreamBufferFillPercentage());                      result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
789                      break;                      break;
790                  default:                  default:
791                      throw LinuxSamplerException("Unknown fill response type");                      throw Exception("Unknown fill response type");
792              }              }
793          }          }
794      }      }
795      catch (LinuxSamplerException e) {      catch (Exception e) {
796           result.Error(e);           result.Error(e);
797      }      }
798      return result.Produce();      return result.Produce();
# Line 672  String LSCPServer::GetAvailableAudioOutp Line 802  String LSCPServer::GetAvailableAudioOutp
802      dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));      dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
803      LSCPResultSet result;      LSCPResultSet result;
804      try {      try {
805            int n = AudioOutputDeviceFactory::AvailableDrivers().size();
806            result.Add(n);
807        }
808        catch (Exception e) {
809            result.Error(e);
810        }
811        return result.Produce();
812    }
813    
814    String LSCPServer::ListAvailableAudioOutputDrivers() {
815        dmsg(2,("LSCPServer: ListAvailableAudioOutputDrivers()\n"));
816        LSCPResultSet result;
817        try {
818          String s = AudioOutputDeviceFactory::AvailableDriversAsString();          String s = AudioOutputDeviceFactory::AvailableDriversAsString();
819          result.Add(s);          result.Add(s);
820      }      }
821      catch (LinuxSamplerException e) {      catch (Exception e) {
822          result.Error(e);          result.Error(e);
823      }      }
824      return result.Produce();      return result.Produce();
# Line 685  String LSCPServer::GetAvailableMidiInput Line 828  String LSCPServer::GetAvailableMidiInput
828      dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));      dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
829      LSCPResultSet result;      LSCPResultSet result;
830      try {      try {
831            int n = MidiInputDeviceFactory::AvailableDrivers().size();
832            result.Add(n);
833        }
834        catch (Exception e) {
835            result.Error(e);
836        }
837        return result.Produce();
838    }
839    
840    String LSCPServer::ListAvailableMidiInputDrivers() {
841        dmsg(2,("LSCPServer: ListAvailableMidiInputDrivers()\n"));
842        LSCPResultSet result;
843        try {
844          String s = MidiInputDeviceFactory::AvailableDriversAsString();          String s = MidiInputDeviceFactory::AvailableDriversAsString();
845          result.Add(s);          result.Add(s);
846      }      }
847      catch (LinuxSamplerException e) {      catch (Exception e) {
848          result.Error(e);          result.Error(e);
849      }      }
850      return result.Produce();      return result.Produce();
# Line 712  String LSCPServer::GetMidiInputDriverInf Line 868  String LSCPServer::GetMidiInputDriverInf
868              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
869          }          }
870      }      }
871      catch (LinuxSamplerException e) {      catch (Exception e) {
872          result.Error(e);          result.Error(e);
873      }      }
874      return result.Produce();      return result.Produce();
# Line 736  String LSCPServer::GetAudioOutputDriverI Line 892  String LSCPServer::GetAudioOutputDriverI
892              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
893          }          }
894      }      }
895      catch (LinuxSamplerException e) {      catch (Exception e) {
896          result.Error(e);          result.Error(e);
897      }      }
898      return result.Produce();      return result.Produce();
# Line 763  String LSCPServer::GetMidiInputDriverPar Line 919  String LSCPServer::GetMidiInputDriverPar
919          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
920          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
921      }      }
922      catch (LinuxSamplerException e) {      catch (Exception e) {
923          result.Error(e);          result.Error(e);
924      }      }
925      return result.Produce();      return result.Produce();
# Line 790  String LSCPServer::GetAudioOutputDriverP Line 946  String LSCPServer::GetAudioOutputDriverP
946          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
947          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
948      }      }
949      catch (LinuxSamplerException e) {      catch (Exception e) {
950          result.Error(e);          result.Error(e);
951      }      }
952      return result.Produce();      return result.Produce();
# Line 803  String LSCPServer::GetAudioOutputDeviceC Line 959  String LSCPServer::GetAudioOutputDeviceC
959          uint count = pSampler->AudioOutputDevices();          uint count = pSampler->AudioOutputDevices();
960          result.Add(count); // success          result.Add(count); // success
961      }      }
962      catch (LinuxSamplerException e) {      catch (Exception e) {
963          result.Error(e);          result.Error(e);
964      }      }
965      return result.Produce();      return result.Produce();
# Line 816  String LSCPServer::GetMidiInputDeviceCou Line 972  String LSCPServer::GetMidiInputDeviceCou
972          uint count = pSampler->MidiInputDevices();          uint count = pSampler->MidiInputDevices();
973          result.Add(count); // success          result.Add(count); // success
974      }      }
975      catch (LinuxSamplerException e) {      catch (Exception e) {
976          result.Error(e);          result.Error(e);
977      }      }
978      return result.Produce();      return result.Produce();
# Line 835  String LSCPServer::GetAudioOutputDevices Line 991  String LSCPServer::GetAudioOutputDevices
991          }          }
992          result.Add(s);          result.Add(s);
993      }      }
994      catch (LinuxSamplerException e) {      catch (Exception e) {
995          result.Error(e);          result.Error(e);
996      }      }
997      return result.Produce();      return result.Produce();
# Line 854  String LSCPServer::GetMidiInputDevices() Line 1010  String LSCPServer::GetMidiInputDevices()
1010          }          }
1011          result.Add(s);          result.Add(s);
1012      }      }
1013      catch (LinuxSamplerException e) {      catch (Exception e) {
1014          result.Error(e);          result.Error(e);
1015      }      }
1016      return result.Produce();      return result.Produce();
# Line 865  String LSCPServer::GetAudioOutputDeviceI Line 1021  String LSCPServer::GetAudioOutputDeviceI
1021      LSCPResultSet result;      LSCPResultSet result;
1022      try {      try {
1023          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1024          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1025          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
1026          result.Add("DRIVER", pDevice->Driver());          result.Add("DRIVER", pDevice->Driver());
1027          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
# Line 874  String LSCPServer::GetAudioOutputDeviceI Line 1030  String LSCPServer::GetAudioOutputDeviceI
1030              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1031          }          }
1032      }      }
1033      catch (LinuxSamplerException e) {      catch (Exception e) {
1034          result.Error(e);          result.Error(e);
1035      }      }
1036      return result.Produce();      return result.Produce();
# Line 885  String LSCPServer::GetMidiInputDeviceInf Line 1041  String LSCPServer::GetMidiInputDeviceInf
1041      LSCPResultSet result;      LSCPResultSet result;
1042      try {      try {
1043          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1044          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1045          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1046          result.Add("DRIVER", pDevice->Driver());          result.Add("DRIVER", pDevice->Driver());
1047          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
# Line 894  String LSCPServer::GetMidiInputDeviceInf Line 1050  String LSCPServer::GetMidiInputDeviceInf
1050              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1051          }          }
1052      }      }
1053      catch (LinuxSamplerException e) {      catch (Exception e) {
1054          result.Error(e);          result.Error(e);
1055      }      }
1056      return result.Produce();      return result.Produce();
# Line 905  String LSCPServer::GetMidiInputPortInfo( Line 1061  String LSCPServer::GetMidiInputPortInfo(
1061      try {      try {
1062          // get MIDI input device          // get MIDI input device
1063          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1064          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1065          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1066    
1067          // get MIDI port          // get MIDI port
1068          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1069          if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");          if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1070    
1071          // return the values of all MIDI port parameters          // return the values of all MIDI port parameters
1072          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
# Line 919  String LSCPServer::GetMidiInputPortInfo( Line 1075  String LSCPServer::GetMidiInputPortInfo(
1075              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1076          }          }
1077      }      }
1078      catch (LinuxSamplerException e) {      catch (Exception e) {
1079          result.Error(e);          result.Error(e);
1080      }      }
1081      return result.Produce();      return result.Produce();
# Line 931  String LSCPServer::GetAudioOutputChannel Line 1087  String LSCPServer::GetAudioOutputChannel
1087      try {      try {
1088          // get audio output device          // get audio output device
1089          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1090          if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");          if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1091          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1092    
1093          // get audio channel          // get audio channel
1094          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1095          if (!pChannel) throw LinuxSamplerException("Audio ouotput device does not have channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1096    
1097          // return the values of all audio channel parameters          // return the values of all audio channel parameters
1098          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
# Line 945  String LSCPServer::GetAudioOutputChannel Line 1101  String LSCPServer::GetAudioOutputChannel
1101              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1102          }          }
1103      }      }
1104      catch (LinuxSamplerException e) {      catch (Exception e) {
1105          result.Error(e);          result.Error(e);
1106      }      }
1107      return result.Produce();      return result.Produce();
# Line 957  String LSCPServer::GetMidiInputPortParam Line 1113  String LSCPServer::GetMidiInputPortParam
1113      try {      try {
1114          // get MIDI input device          // get MIDI input device
1115          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1116          if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no midi input device with index " + ToString(DeviceId) + ".");          if (!devices.count(DeviceId)) throw Exception("There is no midi input device with index " + ToString(DeviceId) + ".");
1117          MidiInputDevice* pDevice = devices[DeviceId];          MidiInputDevice* pDevice = devices[DeviceId];
1118    
1119          // get midi port          // get midi port
1120          MidiInputPort* pPort = pDevice->GetPort(PortId);          MidiInputPort* pPort = pDevice->GetPort(PortId);
1121          if (!pPort) throw LinuxSamplerException("Midi input device does not have port " + ToString(PortId) + ".");          if (!pPort) throw Exception("Midi input device does not have port " + ToString(PortId) + ".");
1122    
1123          // get desired port parameter          // get desired port parameter
1124          std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1125          if (!parameters.count(ParameterName)) throw LinuxSamplerException("Midi port does not provide a parameter '" + ParameterName + "'.");          if (!parameters.count(ParameterName)) throw Exception("Midi port does not provide a parameter '" + ParameterName + "'.");
1126          DeviceRuntimeParameter* pParameter = parameters[ParameterName];          DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1127    
1128          // return all fields of this audio channel parameter          // return all fields of this audio channel parameter
# Line 978  String LSCPServer::GetMidiInputPortParam Line 1134  String LSCPServer::GetMidiInputPortParam
1134          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1135          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1136      }      }
1137      catch (LinuxSamplerException e) {      catch (Exception e) {
1138          result.Error(e);          result.Error(e);
1139      }      }
1140      return result.Produce();      return result.Produce();
# Line 990  String LSCPServer::GetAudioOutputChannel Line 1146  String LSCPServer::GetAudioOutputChannel
1146      try {      try {
1147          // get audio output device          // get audio output device
1148          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1149          if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");          if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1150          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1151    
1152          // get audio channel          // get audio channel
1153          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1154          if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1155    
1156          // get desired audio channel parameter          // get desired audio channel parameter
1157          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1158          if (!parameters.count(ParameterName)) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParameterName + "'.");          if (!parameters.count(ParameterName)) throw Exception("Audio channel does not provide a parameter '" + ParameterName + "'.");
1159          DeviceRuntimeParameter* pParameter = parameters[ParameterName];          DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1160    
1161          // return all fields of this audio channel parameter          // return all fields of this audio channel parameter
# Line 1011  String LSCPServer::GetAudioOutputChannel Line 1167  String LSCPServer::GetAudioOutputChannel
1167          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1168          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1169      }      }
1170      catch (LinuxSamplerException e) {      catch (Exception e) {
1171          result.Error(e);          result.Error(e);
1172      }      }
1173      return result.Produce();      return result.Produce();
# Line 1023  String LSCPServer::SetAudioOutputChannel Line 1179  String LSCPServer::SetAudioOutputChannel
1179      try {      try {
1180          // get audio output device          // get audio output device
1181          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1182          if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");          if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1183          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1184    
1185          // get audio channel          // get audio channel
1186          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1187          if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1188    
1189          // get desired audio channel parameter          // get desired audio channel parameter
1190          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1191          if (!parameters.count(ParamKey)) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParamKey + "'.");          if (!parameters.count(ParamKey)) throw Exception("Audio channel does not provide a parameter '" + ParamKey + "'.");
1192          DeviceRuntimeParameter* pParameter = parameters[ParamKey];          DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1193    
1194          // set new channel parameter value          // set new channel parameter value
1195          pParameter->SetValue(ParamVal);          pParameter->SetValue(ParamVal);
1196            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1197      }      }
1198      catch (LinuxSamplerException e) {      catch (Exception e) {
1199          result.Error(e);          result.Error(e);
1200      }      }
1201      return result.Produce();      return result.Produce();
# Line 1049  String LSCPServer::SetAudioOutputDeviceP Line 1206  String LSCPServer::SetAudioOutputDeviceP
1206      LSCPResultSet result;      LSCPResultSet result;
1207      try {      try {
1208          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1209          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1210          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
1211          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1212          if (!parameters.count(ParamKey)) throw LinuxSamplerException("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");          if (!parameters.count(ParamKey)) throw Exception("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1213          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1214            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1215      }      }
1216      catch (LinuxSamplerException e) {      catch (Exception e) {
1217          result.Error(e);          result.Error(e);
1218      }      }
1219      return result.Produce();      return result.Produce();
# Line 1066  String LSCPServer::SetMidiInputDevicePar Line 1224  String LSCPServer::SetMidiInputDevicePar
1224      LSCPResultSet result;      LSCPResultSet result;
1225      try {      try {
1226          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1227          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1228          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1229          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1230          if (!parameters.count(ParamKey)) throw LinuxSamplerException("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");          if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1231          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1232            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1233      }      }
1234      catch (LinuxSamplerException e) {      catch (Exception e) {
1235          result.Error(e);          result.Error(e);
1236      }      }
1237      return result.Produce();      return result.Produce();
# Line 1084  String LSCPServer::SetMidiInputPortParam Line 1243  String LSCPServer::SetMidiInputPortParam
1243      try {      try {
1244          // get MIDI input device          // get MIDI input device
1245          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1246          if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");          if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1247          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1248    
1249          // get MIDI port          // get MIDI port
1250          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1251          if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");          if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1252    
1253          // set port parameter value          // set port parameter value
1254          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1255          if (!parameters.count(ParamKey)) throw LinuxSamplerException("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");          if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1256          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1257            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1258      }      }
1259      catch (LinuxSamplerException e) {      catch (Exception e) {
1260          result.Error(e);          result.Error(e);
1261      }      }
1262      return result.Produce();      return result.Produce();
# Line 1111  String LSCPServer::SetAudioOutputChannel Line 1271  String LSCPServer::SetAudioOutputChannel
1271      LSCPResultSet result;      LSCPResultSet result;
1272      try {      try {
1273          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1274          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1275          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1276          if (!pEngine) throw LinuxSamplerException("No engine deployed on sampler channel " + ToString(uiSamplerChannel));          if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1277          pEngine->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);          if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1278            pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1279      }      }
1280      catch (LinuxSamplerException e) {      catch (Exception e) {
1281           result.Error(e);           result.Error(e);
1282      }      }
1283      return result.Produce();      return result.Produce();
# Line 1125  String LSCPServer::SetAudioOutputChannel Line 1286  String LSCPServer::SetAudioOutputChannel
1286  String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {  String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1287      dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));      dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1288      LSCPResultSet result;      LSCPResultSet result;
1289        LockRTNotify();
1290      try {      try {
1291          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1292          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1293          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1294          if (!devices.count(AudioDeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));          if (!devices.count(AudioDeviceId)) throw Exception("There is no audio output device with index " + ToString(AudioDeviceId));
1295          AudioOutputDevice* pDevice = devices[AudioDeviceId];          AudioOutputDevice* pDevice = devices[AudioDeviceId];
1296          pSamplerChannel->SetAudioOutputDevice(pDevice);          pSamplerChannel->SetAudioOutputDevice(pDevice);
1297      }      }
1298      catch (LinuxSamplerException e) {      catch (Exception e) {
1299           result.Error(e);           result.Error(e);
1300      }      }
1301        UnlockRTNotify();
1302      return result.Produce();      return result.Produce();
1303  }  }
1304    
1305  String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {  String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1306      dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));      dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1307      LSCPResultSet result;      LSCPResultSet result;
1308        LockRTNotify();
1309      try {      try {
1310          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1311          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1312          // Driver type name aliasing...          // Driver type name aliasing...
1313          if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";          if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1314          if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";          if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
# Line 1166  String LSCPServer::SetAudioOutputType(St Line 1330  String LSCPServer::SetAudioOutputType(St
1330          }          }
1331          // Must have a device...          // Must have a device...
1332          if (pDevice == NULL)          if (pDevice == NULL)
1333              throw LinuxSamplerException("Internal error: could not create audio output device.");              throw Exception("Internal error: could not create audio output device.");
1334          // Set it as the current channel device...          // Set it as the current channel device...
1335          pSamplerChannel->SetAudioOutputDevice(pDevice);          pSamplerChannel->SetAudioOutputDevice(pDevice);
1336      }      }
1337      catch (LinuxSamplerException e) {      catch (Exception e) {
1338           result.Error(e);           result.Error(e);
1339      }      }
1340        UnlockRTNotify();
1341      return result.Produce();      return result.Produce();
1342  }  }
1343    
# Line 1181  String LSCPServer::SetMIDIInputPort(uint Line 1346  String LSCPServer::SetMIDIInputPort(uint
1346      LSCPResultSet result;      LSCPResultSet result;
1347      try {      try {
1348          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1349          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1350          pSamplerChannel->SetMidiInputPort(MIDIPort);          pSamplerChannel->SetMidiInputPort(MIDIPort);
1351      }      }
1352      catch (LinuxSamplerException e) {      catch (Exception e) {
1353           result.Error(e);           result.Error(e);
1354      }      }
1355      return result.Produce();      return result.Produce();
# Line 1195  String LSCPServer::SetMIDIInputChannel(u Line 1360  String LSCPServer::SetMIDIInputChannel(u
1360      LSCPResultSet result;      LSCPResultSet result;
1361      try {      try {
1362          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1363          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1364          pSamplerChannel->SetMidiInputChannel((MidiInputPort::midi_chan_t) MIDIChannel);          pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1365      }      }
1366      catch (LinuxSamplerException e) {      catch (Exception e) {
1367           result.Error(e);           result.Error(e);
1368      }      }
1369      return result.Produce();      return result.Produce();
# Line 1209  String LSCPServer::SetMIDIInputDevice(ui Line 1374  String LSCPServer::SetMIDIInputDevice(ui
1374      LSCPResultSet result;      LSCPResultSet result;
1375      try {      try {
1376          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1377          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1378          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1379          if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));          if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1380          MidiInputDevice* pDevice = devices[MIDIDeviceId];          MidiInputDevice* pDevice = devices[MIDIDeviceId];
1381          pSamplerChannel->SetMidiInputDevice(pDevice);          pSamplerChannel->SetMidiInputDevice(pDevice);
1382      }      }
1383      catch (LinuxSamplerException e) {      catch (Exception e) {
1384           result.Error(e);           result.Error(e);
1385      }      }
1386      return result.Produce();      return result.Produce();
# Line 1226  String LSCPServer::SetMIDIInputType(Stri Line 1391  String LSCPServer::SetMIDIInputType(Stri
1391      LSCPResultSet result;      LSCPResultSet result;
1392      try {      try {
1393          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1394          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1395          // Driver type name aliasing...          // Driver type name aliasing...
1396          if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";          if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1397          // Check if there's one MIDI input device already created          // Check if there's one MIDI input device already created
# Line 1250  String LSCPServer::SetMIDIInputType(Stri Line 1415  String LSCPServer::SetMIDIInputType(Stri
1415          }          }
1416          // Must have a device...          // Must have a device...
1417          if (pDevice == NULL)          if (pDevice == NULL)
1418              throw LinuxSamplerException("Internal error: could not create MIDI input device.");              throw Exception("Internal error: could not create MIDI input device.");
1419          // Set it as the current channel device...          // Set it as the current channel device...
1420          pSamplerChannel->SetMidiInputDevice(pDevice);          pSamplerChannel->SetMidiInputDevice(pDevice);
1421      }      }
1422      catch (LinuxSamplerException e) {      catch (Exception e) {
1423           result.Error(e);           result.Error(e);
1424      }      }
1425      return result.Produce();      return result.Produce();
# Line 1269  String LSCPServer::SetMIDIInput(uint MID Line 1434  String LSCPServer::SetMIDIInput(uint MID
1434      LSCPResultSet result;      LSCPResultSet result;
1435      try {      try {
1436          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1437          if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1438          std::map<uint, MidiInputDevice*> devices =  pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices =  pSampler->GetMidiInputDevices();
1439          if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));          if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1440          MidiInputDevice* pDevice = devices[MIDIDeviceId];          MidiInputDevice* pDevice = devices[MIDIDeviceId];
1441          pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (MidiInputPort::midi_chan_t) MIDIChannel);          pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
1442      }      }
1443      catch (LinuxSamplerException e) {      catch (Exception e) {
1444           result.Error(e);           result.Error(e);
1445      }      }
1446      return result.Produce();      return result.Produce();
# Line 1290  String LSCPServer::SetVolume(double dVol Line 1455  String LSCPServer::SetVolume(double dVol
1455      LSCPResultSet result;      LSCPResultSet result;
1456      try {      try {
1457          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1458          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1459          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1460          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1461          pEngine->Volume(dVolume);          pEngineChannel->Volume(dVolume);
1462      }      }
1463      catch (LinuxSamplerException e) {      catch (Exception e) {
1464           result.Error(e);           result.Error(e);
1465      }      }
1466      return result.Produce();      return result.Produce();
1467  }  }
1468    
1469  /**  /**
1470     * Will be called by the parser to mute/unmute particular sampler channel.
1471     */
1472    String LSCPServer::SetChannelMute(bool bMute, uint uiSamplerChannel) {
1473        dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
1474        LSCPResultSet result;
1475        try {
1476            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1477            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1478    
1479            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1480            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1481    
1482            if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1483            else pEngineChannel->SetMute(1);
1484        } catch (Exception e) {
1485            result.Error(e);
1486        }
1487        return result.Produce();
1488    }
1489    
1490    /**
1491     * Will be called by the parser to solo particular sampler channel.
1492     */
1493    String LSCPServer::SetChannelSolo(bool bSolo, uint uiSamplerChannel) {
1494        dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
1495        LSCPResultSet result;
1496        try {
1497            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1498            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1499    
1500            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1501            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1502    
1503            bool oldSolo = pEngineChannel->GetSolo();
1504            bool hadSoloChannel = HasSoloChannel();
1505    
1506            pEngineChannel->SetSolo(bSolo);
1507    
1508            if(!oldSolo && bSolo) {
1509                if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
1510                if(!hadSoloChannel) MuteNonSoloChannels();
1511            }
1512    
1513            if(oldSolo && !bSolo) {
1514                if(!HasSoloChannel()) UnmuteChannels();
1515                else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
1516            }
1517        } catch (Exception e) {
1518            result.Error(e);
1519        }
1520        return result.Produce();
1521    }
1522    
1523    /**
1524     * Determines whether there is at least one solo channel in the channel list.
1525     *
1526     * @returns true if there is at least one solo channel in the channel list,
1527     * false otherwise.
1528     */
1529    bool LSCPServer::HasSoloChannel() {
1530        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1531        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1532        for (; iter != channels.end(); iter++) {
1533            EngineChannel* c = iter->second->GetEngineChannel();
1534            if(c && c->GetSolo()) return true;
1535        }
1536    
1537        return false;
1538    }
1539    
1540    /**
1541     * Mutes all unmuted non-solo channels. Notice that the channels are muted
1542     * with -1 which indicates that they are muted because of the presence
1543     * of a solo channel(s). Channels muted with -1 will be automatically unmuted
1544     * when there are no solo channels left.
1545     */
1546    void LSCPServer::MuteNonSoloChannels() {
1547        dmsg(2,("LSCPServer: MuteNonSoloChannels()\n"));
1548        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1549        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1550        for (; iter != channels.end(); iter++) {
1551            EngineChannel* c = iter->second->GetEngineChannel();
1552            if(c && !c->GetSolo() && !c->GetMute()) c->SetMute(-1);
1553        }
1554    }
1555    
1556    /**
1557     * Unmutes all channels that are muted because of the presence
1558     * of a solo channel(s).
1559     */
1560    void  LSCPServer::UnmuteChannels() {
1561        dmsg(2,("LSCPServer: UnmuteChannels()\n"));
1562        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1563        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1564        for (; iter != channels.end(); iter++) {
1565            EngineChannel* c = iter->second->GetEngineChannel();
1566            if(c && c->GetMute() == -1) c->SetMute(0);
1567        }
1568    }
1569    
1570    String LSCPServer::AddOrReplaceMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg, String EngineType, String InstrumentFile, uint InstrumentIndex, float Volume, MidiInstrumentMapper::mode_t LoadMode, String Name, bool bModal) {
1571        dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
1572    
1573        midi_prog_index_t idx;
1574        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1575        idx.midi_bank_lsb = MidiBank & 0x7f;
1576        idx.midi_prog     = MidiProg;
1577    
1578        MidiInstrumentMapper::entry_t entry;
1579        entry.EngineName      = EngineType;
1580        entry.InstrumentFile  = InstrumentFile;
1581        entry.InstrumentIndex = InstrumentIndex;
1582        entry.LoadMode        = LoadMode;
1583        entry.Volume          = Volume;
1584        entry.Name            = Name;
1585    
1586        LSCPResultSet result;
1587        try {
1588            // PERSISTENT mapping commands might block for a long time, so in
1589            // that case we add/replace the mapping in another thread in case
1590            // the NON_MODAL argument was supplied, non persistent mappings
1591            // should return immediately, so we don't need to do that for them
1592            bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
1593            MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1594        } catch (Exception e) {
1595            result.Error(e);
1596        }
1597        return result.Produce();
1598    }
1599    
1600    String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1601        dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1602    
1603        midi_prog_index_t idx;
1604        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1605        idx.midi_bank_lsb = MidiBank & 0x7f;
1606        idx.midi_prog     = MidiProg;
1607    
1608        LSCPResultSet result;
1609        try {
1610            MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1611        } catch (Exception e) {
1612            result.Error(e);
1613        }
1614        return result.Produce();
1615    }
1616    
1617    String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1618        dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1619        LSCPResultSet result;
1620        try {
1621            result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1622        } catch (Exception e) {
1623            result.Error(e);
1624        }
1625        return result.Produce();
1626    }
1627    
1628    
1629    String LSCPServer::GetAllMidiInstrumentMappings() {
1630        dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1631        LSCPResultSet result;
1632        std::vector<int> maps = MidiInstrumentMapper::Maps();
1633        int totalMappings = 0;
1634        for (int i = 0; i < maps.size(); i++) {
1635            try {
1636                totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1637            } catch (Exception e) { /*NOOP*/ }
1638        }
1639        result.Add(totalMappings);
1640        return result.Produce();
1641    }
1642    
1643    String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1644        dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1645        LSCPResultSet result;
1646        try {
1647            midi_prog_index_t idx;
1648            idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1649            idx.midi_bank_lsb = MidiBank & 0x7f;
1650            idx.midi_prog     = MidiProg;
1651    
1652            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1653            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1654            if (iter == mappings.end()) result.Error("there is no map entry with that index");
1655            else { // found
1656                result.Add("NAME", iter->second.Name);
1657                result.Add("ENGINE_NAME", iter->second.EngineName);
1658                result.Add("INSTRUMENT_FILE", iter->second.InstrumentFile);
1659                result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1660                String instrumentName;
1661                Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1662                if (pEngine) {
1663                    if (pEngine->GetInstrumentManager()) {
1664                        InstrumentManager::instrument_id_t instrID;
1665                        instrID.FileName = iter->second.InstrumentFile;
1666                        instrID.Index    = iter->second.InstrumentIndex;
1667                        instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
1668                    }
1669                    EngineFactory::Destroy(pEngine);
1670                }
1671                result.Add("INSTRUMENT_NAME", instrumentName);
1672                switch (iter->second.LoadMode) {
1673                    case MidiInstrumentMapper::ON_DEMAND:
1674                        result.Add("LOAD_MODE", "ON_DEMAND");
1675                        break;
1676                    case MidiInstrumentMapper::ON_DEMAND_HOLD:
1677                        result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
1678                        break;
1679                    case MidiInstrumentMapper::PERSISTENT:
1680                        result.Add("LOAD_MODE", "PERSISTENT");
1681                        break;
1682                    default:
1683                        throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
1684                }
1685                result.Add("VOLUME", iter->second.Volume);
1686            }
1687        } catch (Exception e) {
1688            result.Error(e);
1689        }
1690        return result.Produce();
1691    }
1692    
1693    String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
1694        dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
1695        LSCPResultSet result;
1696        try {
1697            String s;
1698            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1699            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1700            for (; iter != mappings.end(); iter++) {
1701                if (s.size()) s += ",";
1702                s += "{" + ToString(MidiMapID) + ","
1703                         + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1704                         + ToString(int(iter->first.midi_prog)) + "}";
1705            }
1706            result.Add(s);
1707        } catch (Exception e) {
1708            result.Error(e);
1709        }
1710        return result.Produce();
1711    }
1712    
1713    String LSCPServer::ListAllMidiInstrumentMappings() {
1714        dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
1715        LSCPResultSet result;
1716        try {
1717            std::vector<int> maps = MidiInstrumentMapper::Maps();
1718            String s;
1719            for (int i = 0; i < maps.size(); i++) {
1720                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
1721                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1722                for (; iter != mappings.end(); iter++) {
1723                    if (s.size()) s += ",";
1724                    s += "{" + ToString(maps[i]) + ","
1725                             + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1726                             + ToString(int(iter->first.midi_prog)) + "}";
1727                }
1728            }
1729            result.Add(s);
1730        } catch (Exception e) {
1731            result.Error(e);
1732        }
1733        return result.Produce();
1734    }
1735    
1736    String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
1737        dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
1738        LSCPResultSet result;
1739        try {
1740            MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
1741        } catch (Exception e) {
1742            result.Error(e);
1743        }
1744        return result.Produce();
1745    }
1746    
1747    String LSCPServer::ClearAllMidiInstrumentMappings() {
1748        dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
1749        LSCPResultSet result;
1750        try {
1751            std::vector<int> maps = MidiInstrumentMapper::Maps();
1752            for (int i = 0; i < maps.size(); i++)
1753                MidiInstrumentMapper::RemoveAllEntries(maps[i]);
1754        } catch (Exception e) {
1755            result.Error(e);
1756        }
1757        return result.Produce();
1758    }
1759    
1760    String LSCPServer::AddMidiInstrumentMap(String MapName) {
1761        dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
1762        LSCPResultSet result;
1763        try {
1764            int MapID = MidiInstrumentMapper::AddMap(MapName);
1765            result = LSCPResultSet(MapID);
1766        } catch (Exception e) {
1767            result.Error(e);
1768        }
1769        return result.Produce();
1770    }
1771    
1772    String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
1773        dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
1774        LSCPResultSet result;
1775        try {
1776            MidiInstrumentMapper::RemoveMap(MidiMapID);
1777        } catch (Exception e) {
1778            result.Error(e);
1779        }
1780        return result.Produce();
1781    }
1782    
1783    String LSCPServer::RemoveAllMidiInstrumentMaps() {
1784        dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
1785        LSCPResultSet result;
1786        try {
1787            MidiInstrumentMapper::RemoveAllMaps();
1788        } catch (Exception e) {
1789            result.Error(e);
1790        }
1791        return result.Produce();
1792    }
1793    
1794    String LSCPServer::GetMidiInstrumentMaps() {
1795        dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
1796        LSCPResultSet result;
1797        try {
1798            result.Add(MidiInstrumentMapper::Maps().size());
1799        } catch (Exception e) {
1800            result.Error(e);
1801        }
1802        return result.Produce();
1803    }
1804    
1805    String LSCPServer::ListMidiInstrumentMaps() {
1806        dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
1807        LSCPResultSet result;
1808        try {
1809            std::vector<int> maps = MidiInstrumentMapper::Maps();
1810            String sList;
1811            for (int i = 0; i < maps.size(); i++) {
1812                if (sList != "") sList += ",";
1813                sList += ToString(maps[i]);
1814            }
1815            result.Add(sList);
1816        } catch (Exception e) {
1817            result.Error(e);
1818        }
1819        return result.Produce();
1820    }
1821    
1822    String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
1823        dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
1824        LSCPResultSet result;
1825        try {
1826            result.Add("NAME", MidiInstrumentMapper::MapName(MidiMapID));
1827        } catch (Exception e) {
1828            result.Error(e);
1829        }
1830        return result.Produce();
1831    }
1832    
1833    String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
1834        dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
1835        LSCPResultSet result;
1836        try {
1837            MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
1838        } catch (Exception e) {
1839            result.Error(e);
1840        }
1841        return result.Produce();
1842    }
1843    
1844    /**
1845     * Set the MIDI instrument map the given sampler channel shall use for
1846     * handling MIDI program change messages. There are the following two
1847     * special (negative) values:
1848     *
1849     *    - (-1) :  set to NONE (ignore program changes)
1850     *    - (-2) :  set to DEFAULT map
1851     */
1852    String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
1853        dmsg(2,("LSCPServer: SetChannelMap()\n"));
1854        LSCPResultSet result;
1855        try {
1856            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1857            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1858    
1859            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1860            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1861    
1862            if      (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
1863            else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
1864            else                      pEngineChannel->SetMidiInstrumentMap(MidiMapID);
1865        } catch (Exception e) {
1866            result.Error(e);
1867        }
1868        return result.Produce();
1869    }
1870    
1871    String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
1872        dmsg(2,("LSCPServer: CreateFxSend()\n"));
1873        LSCPResultSet result;
1874        try {
1875            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1876            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1877    
1878            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1879            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1880    
1881            FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
1882            if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
1883    
1884            result = LSCPResultSet(pFxSend->Id()); // success
1885        } catch (Exception e) {
1886            result.Error(e);
1887        }
1888        return result.Produce();
1889    }
1890    
1891    String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
1892        dmsg(2,("LSCPServer: DestroyFxSend()\n"));
1893        LSCPResultSet result;
1894        try {
1895            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1896            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1897    
1898            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1899            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1900    
1901            FxSend* pFxSend = NULL;
1902            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1903                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1904                    pFxSend = pEngineChannel->GetFxSend(i);
1905                    break;
1906                }
1907            }
1908            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1909            pEngineChannel->RemoveFxSend(pFxSend);
1910        } catch (Exception e) {
1911            result.Error(e);
1912        }
1913        return result.Produce();
1914    }
1915    
1916    String LSCPServer::GetFxSends(uint uiSamplerChannel) {
1917        dmsg(2,("LSCPServer: GetFxSends()\n"));
1918        LSCPResultSet result;
1919        try {
1920            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1921            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1922    
1923            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1924            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1925    
1926            result.Add(pEngineChannel->GetFxSendCount());
1927        } catch (Exception e) {
1928            result.Error(e);
1929        }
1930        return result.Produce();
1931    }
1932    
1933    String LSCPServer::ListFxSends(uint uiSamplerChannel) {
1934        dmsg(2,("LSCPServer: ListFxSends()\n"));
1935        LSCPResultSet result;
1936        String list;
1937        try {
1938            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1939            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1940    
1941            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1942            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1943    
1944            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1945                FxSend* pFxSend = pEngineChannel->GetFxSend(i);
1946                if (list != "") list += ",";
1947                list += ToString(pFxSend->Id());
1948            }
1949            result.Add(list);
1950        } catch (Exception e) {
1951            result.Error(e);
1952        }
1953        return result.Produce();
1954    }
1955    
1956    String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
1957        dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
1958        LSCPResultSet result;
1959        try {
1960            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1961            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1962    
1963            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1964            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1965    
1966            FxSend* pFxSend = NULL;
1967            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1968                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1969                    pFxSend = pEngineChannel->GetFxSend(i);
1970                    break;
1971                }
1972            }
1973            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1974    
1975            // gather audio routing informations
1976            String AudioRouting;
1977            for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
1978                if (AudioRouting != "") AudioRouting += ",";
1979                AudioRouting += ToString(pFxSend->DestinationChannel(chan));
1980            }
1981    
1982            // success
1983            result.Add("NAME", pFxSend->Name());
1984            result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
1985            result.Add("LEVEL", ToString(pFxSend->Level()));
1986            result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
1987        } catch (Exception e) {
1988            result.Error(e);
1989        }
1990        return result.Produce();
1991    }
1992    
1993    String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
1994        dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
1995        LSCPResultSet result;
1996        try {
1997            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1998            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1999    
2000            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2001            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2002    
2003            FxSend* pFxSend = NULL;
2004            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2005                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2006                    pFxSend = pEngineChannel->GetFxSend(i);
2007                    break;
2008                }
2009            }
2010            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2011    
2012            pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2013        } catch (Exception e) {
2014            result.Error(e);
2015        }
2016        return result.Produce();
2017    }
2018    
2019    String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2020        dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2021        LSCPResultSet result;
2022        try {
2023            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2024            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2025    
2026            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2027            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2028    
2029            FxSend* pFxSend = NULL;
2030            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2031                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2032                    pFxSend = pEngineChannel->GetFxSend(i);
2033                    break;
2034                }
2035            }
2036            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2037    
2038            pFxSend->SetMidiController(MidiController);
2039        } catch (Exception e) {
2040            result.Error(e);
2041        }
2042        return result.Produce();
2043    }
2044    
2045    String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2046        dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2047        LSCPResultSet result;
2048        try {
2049            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2050            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2051    
2052            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2053            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2054    
2055            FxSend* pFxSend = NULL;
2056            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2057                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2058                    pFxSend = pEngineChannel->GetFxSend(i);
2059                    break;
2060                }
2061            }
2062            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2063    
2064            pFxSend->SetLevel((float)dLevel);
2065        } catch (Exception e) {
2066            result.Error(e);
2067        }
2068        return result.Produce();
2069    }
2070    
2071    /**
2072   * Will be called by the parser to reset a particular sampler channel.   * Will be called by the parser to reset a particular sampler channel.
2073   */   */
2074  String LSCPServer::ResetChannel(uint uiSamplerChannel) {  String LSCPServer::ResetChannel(uint uiSamplerChannel) {
# Line 1309  String LSCPServer::ResetChannel(uint uiS Line 2076  String LSCPServer::ResetChannel(uint uiS
2076      LSCPResultSet result;      LSCPResultSet result;
2077      try {      try {
2078          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2079          if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2080          Engine* pEngine = pSamplerChannel->GetEngine();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2081          if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2082          pEngine->Reset();          pEngineChannel->Reset();
2083      }      }
2084      catch (LinuxSamplerException e) {      catch (Exception e) {
2085           result.Error(e);           result.Error(e);
2086      }      }
2087      return result.Produce();      return result.Produce();
# Line 1331  String LSCPServer::ResetSampler() { Line 2098  String LSCPServer::ResetSampler() {
2098  }  }
2099    
2100  /**  /**
2101     * Will be called by the parser to return general informations about this
2102     * sampler.
2103     */
2104    String LSCPServer::GetServerInfo() {
2105        dmsg(2,("LSCPServer: GetServerInfo()\n"));
2106        LSCPResultSet result;
2107        result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2108        result.Add("VERSION", VERSION);
2109        result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2110        return result.Produce();
2111    }
2112    
2113    /**
2114     * Will be called by the parser to return the current number of all active voices.
2115     */
2116    String LSCPServer::GetTotalVoiceCount() {
2117        dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2118        LSCPResultSet result;
2119        result.Add(pSampler->GetVoiceCount());
2120        return result.Produce();
2121    }
2122    
2123    /**
2124     * Will be called by the parser to return the maximum number of voices.
2125     */
2126    String LSCPServer::GetTotalVoiceCountMax() {
2127        dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2128        LSCPResultSet result;
2129        result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2130        return result.Produce();
2131    }
2132    
2133    String LSCPServer::GetGlobalVolume() {
2134        LSCPResultSet result;
2135        result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2136        return result.Produce();
2137    }
2138    
2139    String LSCPServer::SetGlobalVolume(double dVolume) {
2140        LSCPResultSet result;
2141        try {
2142            if (dVolume < 0) throw Exception("Volume may not be negative");
2143            GLOBAL_VOLUME = dVolume; // see common/global.cpp
2144        } catch (Exception e) {
2145            result.Error(e);
2146        }
2147        return result.Produce();
2148    }
2149    
2150    /**
2151   * Will be called by the parser to subscribe a client (frontend) on the   * Will be called by the parser to subscribe a client (frontend) on the
2152   * server for receiving event messages.   * server for receiving event messages.
2153   */   */
# Line 1356  String LSCPServer::UnsubscribeNotificati Line 2173  String LSCPServer::UnsubscribeNotificati
2173      return result.Produce();      return result.Produce();
2174  }  }
2175    
2176    static int select_callback(void * lscpResultSet, int argc,
2177                            char **argv, char **azColName)
2178    {
2179        LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;
2180        resultSet->Add(argc, argv);
2181        return 0;
2182    }
2183    
2184    String LSCPServer::QueryDatabase(String query) {
2185        LSCPResultSet result;
2186    #if HAVE_SQLITE3
2187        char* zErrMsg = NULL;
2188        sqlite3 *db;
2189        String selectStr = "SELECT " + query;
2190    
2191        int rc = sqlite3_open("linuxsampler.db", &db);
2192        if (rc == SQLITE_OK)
2193        {
2194                rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);
2195        }
2196        if ( rc != SQLITE_OK )
2197        {
2198                result.Error(String(zErrMsg), rc);
2199        }
2200        sqlite3_close(db);
2201    #else
2202        result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);
2203    #endif
2204        return result.Produce();
2205    }
2206    
2207  /**  /**
2208   * Will be called by the parser to enable or disable echo mode; if echo   * Will be called by the parser to enable or disable echo mode; if echo
2209   * mode is enabled, all commands from the client will (immediately) be   * mode is enabled, all commands from the client will (immediately) be
# Line 1367  String LSCPServer::SetEcho(yyparse_param Line 2215  String LSCPServer::SetEcho(yyparse_param
2215      try {      try {
2216          if      (boolean_value == 0) pSession->bVerbose = false;          if      (boolean_value == 0) pSession->bVerbose = false;
2217          else if (boolean_value == 1) pSession->bVerbose = true;          else if (boolean_value == 1) pSession->bVerbose = true;
2218          else throw LinuxSamplerException("Not a boolean value, must either be 0 or 1");          else throw Exception("Not a boolean value, must either be 0 or 1");
2219      }      }
2220      catch (LinuxSamplerException e) {      catch (Exception e) {
2221           result.Error(e);           result.Error(e);
2222      }      }
2223      return result.Produce();      return result.Produce();
2224  }  }
   
 // Instrument loader constructor.  
 LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)  
     : Thread(false, 0, -4)  
 {  
     this->pEngine = pEngine;  
     this->Filename = Filename;  
     this->uiInstrument = uiInstrument;  
 }  
   
 // Instrument loader process.  
 int LSCPLoadInstrument::Main()  
 {  
     try {  
         pEngine->LoadInstrument(Filename.c_str(), uiInstrument);  
     }  
   
     catch (LinuxSamplerException e) {  
         e.PrintMessage();  
     }  
   
     // Always re-enable the engine.  
     pEngine->Enable();  
   
     // FIXME: Shoot ourselves on the foot?  
     delete this;  
 }  

Legend:
Removed from v.226  
changed lines
  Added in v.1047

  ViewVC Help
Powered by ViewVC