/[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 1727 by iliev, Tue Apr 29 15:44:09 2008 UTC revision 2135 by schoenebeck, Thu Sep 30 20:00:43 2010 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2008 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2009 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This library 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  *
# Line 22  Line 22 
22   ***************************************************************************/   ***************************************************************************/
23    
24  #include <algorithm>  #include <algorithm>
25    #include <string>
26    
27    #include "../common/File.h"
28  #include "lscpserver.h"  #include "lscpserver.h"
29  #include "lscpresultset.h"  #include "lscpresultset.h"
30  #include "lscpevent.h"  #include "lscpevent.h"
# Line 41  Line 43 
43  #include "../engines/EngineChannelFactory.h"  #include "../engines/EngineChannelFactory.h"
44  #include "../drivers/audio/AudioOutputDeviceFactory.h"  #include "../drivers/audio/AudioOutputDeviceFactory.h"
45  #include "../drivers/midi/MidiInputDeviceFactory.h"  #include "../drivers/midi/MidiInputDeviceFactory.h"
46    #include "../effects/EffectFactory.h"
47    
48    namespace LinuxSampler {
49    
50  /**  /**
51   * Returns a copy of the given string where all special characters are   * Returns a copy of the given string where all special characters are
# Line 138  LSCPServer::LSCPServer(Sampler* pSampler Line 142  LSCPServer::LSCPServer(Sampler* pSampler
142  }  }
143    
144  LSCPServer::~LSCPServer() {  LSCPServer::~LSCPServer() {
145        CloseAllConnections();
146        InstrumentManager::StopBackgroundThread();
147  #if defined(WIN32)  #if defined(WIN32)
148      if (hSocket >= 0) closesocket(hSocket);      if (hSocket >= 0) closesocket(hSocket);
149  #else  #else
# Line 332  void LSCPServer::DbInstrumentsEventHandl Line 338  void LSCPServer::DbInstrumentsEventHandl
338  }  }
339  #endif // HAVE_SQLITE3  #endif // HAVE_SQLITE3
340    
341    void LSCPServer::RemoveListeners() {
342        pSampler->RemoveChannelCountListener(&eventHandler);
343        pSampler->RemoveAudioDeviceCountListener(&eventHandler);
344        pSampler->RemoveMidiDeviceCountListener(&eventHandler);
345        pSampler->RemoveVoiceCountListener(&eventHandler);
346        pSampler->RemoveStreamCountListener(&eventHandler);
347        pSampler->RemoveBufferFillListener(&eventHandler);
348        pSampler->RemoveTotalStreamCountListener(&eventHandler);
349        pSampler->RemoveTotalVoiceCountListener(&eventHandler);
350        pSampler->RemoveFxSendCountListener(&eventHandler);
351        MidiInstrumentMapper::RemoveMidiInstrumentCountListener(&eventHandler);
352        MidiInstrumentMapper::RemoveMidiInstrumentInfoListener(&eventHandler);
353        MidiInstrumentMapper::RemoveMidiInstrumentMapCountListener(&eventHandler);
354        MidiInstrumentMapper::RemoveMidiInstrumentMapInfoListener(&eventHandler);
355    #if HAVE_SQLITE3
356        InstrumentsDb::GetInstrumentsDb()->RemoveInstrumentsDbListener(&dbInstrumentsEventHandler);
357    #endif
358    }
359    
360  /**  /**
361   * Blocks the calling thread until the LSCP Server is initialized and   * Blocks the calling thread until the LSCP Server is initialized and
# Line 424  int LSCPServer::Main() { Line 448  int LSCPServer::Main() {
448              std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();              std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();
449              for (; itEngineChannel != itEnd; ++itEngineChannel) {              for (; itEngineChannel != itEnd; ++itEngineChannel) {
450                  if ((*itEngineChannel)->StatusChanged()) {                  if ((*itEngineChannel)->StatusChanged()) {
451                      SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));                      SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->GetSamplerChannel()->Index()));
452                  }                  }
453    
454                  for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {                  for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
455                      FxSend* fxs = (*itEngineChannel)->GetFxSend(i);                      FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
456                      if(fxs != NULL && fxs->IsInfoChanged()) {                      if(fxs != NULL && fxs->IsInfoChanged()) {
457                          int chn = (*itEngineChannel)->iSamplerChannelIndex;                          int chn = (*itEngineChannel)->GetSamplerChannel()->Index();
458                          LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));                          LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));
459                          fxs->SetInfoChanged(false);                          fxs->SetInfoChanged(false);
460                      }                      }
# Line 505  int LSCPServer::Main() { Line 529  int LSCPServer::Main() {
529    
530          int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);          int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
531    
532          if (retval == 0)          if (retval == 0 || (retval == -1 && errno == EINTR))
533                  continue; //Nothing try again                  continue; //Nothing try again
534          if (retval == -1) {          if (retval == -1) {
535                  std::cerr << "LSCPServer: Socket select error." << std::endl;                  std::cerr << "LSCPServer: Socket select error." << std::endl;
# Line 532  int LSCPServer::Main() { Line 556  int LSCPServer::Main() {
556                    exit(EXIT_FAILURE);                    exit(EXIT_FAILURE);
557                  }                  }
558          #else          #else
559                    struct linger linger;
560                    linger.l_onoff = 1;
561                    linger.l_linger = 0;
562                    if(setsockopt(socket, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger))) {
563                        std::cerr << "LSCPServer: Failed to set SO_LINGER\n";
564                    }
565    
566                  if (fcntl(socket, F_SETFL, O_NONBLOCK)) {                  if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
567                          std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;                          std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
568                          exit(EXIT_FAILURE);                          exit(EXIT_FAILURE);
# Line 603  void LSCPServer::CloseConnection( std::v Line 634  void LSCPServer::CloseConnection( std::v
634          NotifyMutex.Unlock();          NotifyMutex.Unlock();
635  }  }
636    
637    void LSCPServer::CloseAllConnections() {
638        std::vector<yyparse_param_t>::iterator iter = Sessions.begin();
639        while(iter != Sessions.end()) {
640            CloseConnection(iter);
641            iter = Sessions.begin();
642        }
643    }
644    
645  void LSCPServer::LockRTNotify() {  void LSCPServer::LockRTNotify() {
646      RTNotifyMutex.Lock();      RTNotifyMutex.Lock();
647  }  }
# Line 1133  String LSCPServer::GetVoiceCount(uint ui Line 1172  String LSCPServer::GetVoiceCount(uint ui
1172      dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));      dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
1173      LSCPResultSet result;      LSCPResultSet result;
1174      try {      try {
1175          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");  
1176          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1177          result.Add(pEngineChannel->GetEngine()->VoiceCount());          result.Add(pEngineChannel->GetEngine()->VoiceCount());
1178      }      }
# Line 1154  String LSCPServer::GetStreamCount(uint u Line 1190  String LSCPServer::GetStreamCount(uint u
1190      dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));      dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
1191      LSCPResultSet result;      LSCPResultSet result;
1192      try {      try {
1193          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
1194          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1195          result.Add(pEngineChannel->GetEngine()->DiskStreamCount());          result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
1196      }      }
# Line 1175  String LSCPServer::GetBufferFill(fill_re Line 1208  String LSCPServer::GetBufferFill(fill_re
1208      dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));      dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
1209      LSCPResultSet result;      LSCPResultSet result;
1210      try {      try {
1211          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
1212          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1213          if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");          if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
1214          else {          else {
# Line 1266  String LSCPServer::GetMidiInputDriverInf Line 1296  String LSCPServer::GetMidiInputDriverInf
1296              for (;iter != parameters.end(); iter++) {              for (;iter != parameters.end(); iter++) {
1297                  if (s != "") s += ",";                  if (s != "") s += ",";
1298                  s += iter->first;                  s += iter->first;
1299                    delete iter->second;
1300              }              }
1301              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
1302          }          }
# Line 1290  String LSCPServer::GetAudioOutputDriverI Line 1321  String LSCPServer::GetAudioOutputDriverI
1321              for (;iter != parameters.end(); iter++) {              for (;iter != parameters.end(); iter++) {
1322                  if (s != "") s += ",";                  if (s != "") s += ",";
1323                  s += iter->first;                  s += iter->first;
1324                    delete iter->second;
1325              }              }
1326              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
1327          }          }
# Line 1320  String LSCPServer::GetMidiInputDriverPar Line 1352  String LSCPServer::GetMidiInputDriverPar
1352          if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);          if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);
1353          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
1354          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1355            delete pParameter;
1356      }      }
1357      catch (Exception e) {      catch (Exception e) {
1358          result.Error(e);          result.Error(e);
# Line 1347  String LSCPServer::GetAudioOutputDriverP Line 1380  String LSCPServer::GetAudioOutputDriverP
1380          if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);          if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);
1381          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
1382          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1383            delete pParameter;
1384      }      }
1385      catch (Exception e) {      catch (Exception e) {
1386          result.Error(e);          result.Error(e);
# Line 1813  String LSCPServer::SetMIDIInputType(Stri Line 1847  String LSCPServer::SetMIDIInputType(Stri
1847              pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);              pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1848              // Make it with at least one initial port.              // Make it with at least one initial port.
1849              std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();              std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
             parameters["PORTS"]->SetValue("1");  
1850          }          }
1851          // Must have a device...          // Must have a device...
1852          if (pDevice == NULL)          if (pDevice == NULL)
# Line 1856  String LSCPServer::SetVolume(double dVol Line 1889  String LSCPServer::SetVolume(double dVol
1889      dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));      dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1890      LSCPResultSet result;      LSCPResultSet result;
1891      try {      try {
1892          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
1893          pEngineChannel->Volume(dVolume);          pEngineChannel->Volume(dVolume);
1894      }      }
1895      catch (Exception e) {      catch (Exception e) {
# Line 1875  String LSCPServer::SetChannelMute(bool b Line 1905  String LSCPServer::SetChannelMute(bool b
1905      dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));      dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
1906      LSCPResultSet result;      LSCPResultSet result;
1907      try {      try {
1908          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
   
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
1909    
1910          if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);          if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1911          else pEngineChannel->SetMute(1);          else pEngineChannel->SetMute(1);
# Line 1896  String LSCPServer::SetChannelSolo(bool b Line 1922  String LSCPServer::SetChannelSolo(bool b
1922      dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));      dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
1923      LSCPResultSet result;      LSCPResultSet result;
1924      try {      try {
1925          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
   
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
1926    
1927          bool oldSolo = pEngineChannel->GetSolo();          bool oldSolo = pEngineChannel->GetSolo();
1928          bool hadSoloChannel = HasSoloChannel();          bool hadSoloChannel = HasSoloChannel();
# Line 2020  String LSCPServer::GetMidiInstrumentMapp Line 2042  String LSCPServer::GetMidiInstrumentMapp
2042      dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));      dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
2043      LSCPResultSet result;      LSCPResultSet result;
2044      try {      try {
2045          result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());          result.Add(MidiInstrumentMapper::GetInstrumentCount(MidiMapID));
2046      } catch (Exception e) {      } catch (Exception e) {
2047          result.Error(e);          result.Error(e);
2048      }      }
# Line 2031  String LSCPServer::GetMidiInstrumentMapp Line 2053  String LSCPServer::GetMidiInstrumentMapp
2053  String LSCPServer::GetAllMidiInstrumentMappings() {  String LSCPServer::GetAllMidiInstrumentMappings() {
2054      dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));      dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
2055      LSCPResultSet result;      LSCPResultSet result;
2056      std::vector<int> maps = MidiInstrumentMapper::Maps();      try {
2057      int totalMappings = 0;          result.Add(MidiInstrumentMapper::GetInstrumentCount());
2058      for (int i = 0; i < maps.size(); i++) {      } catch (Exception e) {
2059          try {          result.Error(e);
             totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();  
         } catch (Exception e) { /*NOOP*/ }  
2060      }      }
     result.Add(totalMappings);  
2061      return result.Produce();      return result.Produce();
2062  }  }
2063    
# Line 2046  String LSCPServer::GetMidiInstrumentMapp Line 2065  String LSCPServer::GetMidiInstrumentMapp
2065      dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));      dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
2066      LSCPResultSet result;      LSCPResultSet result;
2067      try {      try {
2068          midi_prog_index_t idx;          MidiInstrumentMapper::entry_t entry = MidiInstrumentMapper::GetEntry(MidiMapID, MidiBank, MidiProg);
2069          idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;          // convert the filename into the correct encoding as defined for LSCP
2070          idx.midi_bank_lsb = MidiBank & 0x7f;          // (especially in terms of special characters -> escape sequences)
         idx.midi_prog     = MidiProg;  
   
         std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);  
         std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);  
         if (iter == mappings.end()) result.Error("there is no map entry with that index");  
         else { // found  
   
             // convert the filename into the correct encoding as defined for LSCP  
             // (especially in terms of special characters -> escape sequences)  
2071  #if WIN32  #if WIN32
2072              const String instrumentFileName = Path::fromWindows(iter->second.InstrumentFile).toLscp();          const String instrumentFileName = Path::fromWindows(entry.InstrumentFile).toLscp();
2073  #else  #else
2074              // assuming POSIX          // assuming POSIX
2075              const String instrumentFileName = Path::fromPosix(iter->second.InstrumentFile).toLscp();          const String instrumentFileName = Path::fromPosix(entry.InstrumentFile).toLscp();
2076  #endif  #endif
2077    
2078              result.Add("NAME", _escapeLscpResponse(iter->second.Name));          result.Add("NAME", _escapeLscpResponse(entry.Name));
2079              result.Add("ENGINE_NAME", iter->second.EngineName);          result.Add("ENGINE_NAME", entry.EngineName);
2080              result.Add("INSTRUMENT_FILE", instrumentFileName);          result.Add("INSTRUMENT_FILE", instrumentFileName);
2081              result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);          result.Add("INSTRUMENT_NR", (int) entry.InstrumentIndex);
2082              String instrumentName;          String instrumentName;
2083              Engine* pEngine = EngineFactory::Create(iter->second.EngineName);          Engine* pEngine = EngineFactory::Create(entry.EngineName);
2084              if (pEngine) {          if (pEngine) {
2085                  if (pEngine->GetInstrumentManager()) {              if (pEngine->GetInstrumentManager()) {
2086                      InstrumentManager::instrument_id_t instrID;                  InstrumentManager::instrument_id_t instrID;
2087                      instrID.FileName = iter->second.InstrumentFile;                  instrID.FileName = entry.InstrumentFile;
2088                      instrID.Index    = iter->second.InstrumentIndex;                  instrID.Index    = entry.InstrumentIndex;
2089                      instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);                  instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
                 }  
                 EngineFactory::Destroy(pEngine);  
2090              }              }
2091              result.Add("INSTRUMENT_NAME", _escapeLscpResponse(instrumentName));              EngineFactory::Destroy(pEngine);
2092              switch (iter->second.LoadMode) {          }
2093                  case MidiInstrumentMapper::ON_DEMAND:          result.Add("INSTRUMENT_NAME", _escapeLscpResponse(instrumentName));
2094                      result.Add("LOAD_MODE", "ON_DEMAND");          switch (entry.LoadMode) {
2095                      break;              case MidiInstrumentMapper::ON_DEMAND:
2096                  case MidiInstrumentMapper::ON_DEMAND_HOLD:                  result.Add("LOAD_MODE", "ON_DEMAND");
2097                      result.Add("LOAD_MODE", "ON_DEMAND_HOLD");                  break;
2098                      break;              case MidiInstrumentMapper::ON_DEMAND_HOLD:
2099                  case MidiInstrumentMapper::PERSISTENT:                  result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
2100                      result.Add("LOAD_MODE", "PERSISTENT");                  break;
2101                      break;              case MidiInstrumentMapper::PERSISTENT:
2102                  default:                  result.Add("LOAD_MODE", "PERSISTENT");
2103                      throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");                  break;
2104              }              default:
2105              result.Add("VOLUME", iter->second.Volume);                  throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
2106          }          }
2107            result.Add("VOLUME", entry.Volume);
2108      } catch (Exception e) {      } catch (Exception e) {
2109          result.Error(e);          result.Error(e);
2110      }      }
# Line 2266  String LSCPServer::SetChannelMap(uint ui Line 2275  String LSCPServer::SetChannelMap(uint ui
2275      dmsg(2,("LSCPServer: SetChannelMap()\n"));      dmsg(2,("LSCPServer: SetChannelMap()\n"));
2276      LSCPResultSet result;      LSCPResultSet result;
2277      try {      try {
2278          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
   
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");  
2279    
2280          if      (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();          if      (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
2281          else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();          else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
# Line 2445  String LSCPServer::SetFxSendLevel(uint u Line 2450  String LSCPServer::SetFxSendLevel(uint u
2450      return result.Produce();      return result.Produce();
2451  }  }
2452    
2453    String LSCPServer::GetAvailableEffects() {
2454        dmsg(2,("LSCPServer: GetAvailableEffects()\n"));
2455        LSCPResultSet result;
2456        try {
2457            int n = EffectFactory::AvailableEffectsCount();
2458            result.Add(n);
2459        }
2460        catch (Exception e) {
2461            result.Error(e);
2462        }
2463        return result.Produce();
2464    }
2465    
2466    String LSCPServer::ListAvailableEffects() {
2467        dmsg(2,("LSCPServer: ListAvailableEffects()\n"));
2468        LSCPResultSet result;
2469        String list;
2470        try {
2471            //FIXME: for now we simply enumerate from 0 .. EffectFactory::AvailableEffectsCount() here, in future we should use unique IDs for effects during the whole sampler session. This issue comes into game when the user forces a reload of available effect plugins
2472            int n = EffectFactory::AvailableEffectsCount();
2473            for (int i = 0; i < n; i++) {
2474                if (i) list += ",";
2475                list += ToString(i);
2476            }
2477        }
2478        catch (Exception e) {
2479            result.Error(e);
2480        }
2481        result.Add(list);
2482        return result.Produce();
2483    }
2484    
2485    String LSCPServer::GetEffectInfo(int iEffectIndex) {
2486        dmsg(2,("LSCPServer: GetEffectInfo(%d)\n", iEffectIndex));
2487        LSCPResultSet result;
2488        try {
2489            EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(iEffectIndex);
2490            if (!pEffectInfo)
2491                throw Exception("There is no effect with index " + ToString(iEffectIndex));
2492    
2493            // convert the filename into the correct encoding as defined for LSCP
2494            // (especially in terms of special characters -> escape sequences)
2495    #if WIN32
2496            const String dllFileName = Path::fromWindows(pEffectInfo->Module()).toLscp();
2497    #else
2498            // assuming POSIX
2499            const String dllFileName = Path::fromPosix(pEffectInfo->Module()).toLscp();
2500    #endif
2501    
2502            result.Add("SYSTEM", pEffectInfo->EffectSystem());
2503            result.Add("MODULE", dllFileName);
2504            result.Add("NAME", _escapeLscpResponse(pEffectInfo->Name()));
2505            result.Add("DESCRIPTION", _escapeLscpResponse(pEffectInfo->Description()));
2506        }
2507        catch (Exception e) {
2508            result.Error(e);
2509        }
2510        return result.Produce();    
2511    }
2512    
2513    String LSCPServer::GetEffectInstanceInfo(int iEffectInstanceIndex) {
2514        dmsg(2,("LSCPServer: GetEffectInstanceInfo(%d)\n", iEffectInstanceIndex));
2515        LSCPResultSet result;
2516        try {
2517            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstanceIndex);
2518            if (!pEffect)
2519                throw Exception("There is no effect instance with index " + ToString(iEffectInstanceIndex));
2520    
2521            EffectInfo* pEffectInfo = pEffect->GetEffectInfo();
2522    
2523            // convert the filename into the correct encoding as defined for LSCP
2524            // (especially in terms of special characters -> escape sequences)
2525    #if WIN32
2526            const String dllFileName = Path::fromWindows(pEffectInfo->Module()).toLscp();
2527    #else
2528            // assuming POSIX
2529            const String dllFileName = Path::fromPosix(pEffectInfo->Module()).toLscp();
2530    #endif
2531    
2532            result.Add("SYSTEM", pEffectInfo->EffectSystem());
2533            result.Add("MODULE", dllFileName);
2534            result.Add("NAME", _escapeLscpResponse(pEffectInfo->Name()));
2535            result.Add("DESCRIPTION", _escapeLscpResponse(pEffectInfo->Description()));
2536            result.Add("INPUT_CONTROLS", ToString(pEffect->InputControlCount()));
2537        }
2538        catch (Exception e) {
2539            result.Error(e);
2540        }
2541        return result.Produce();
2542    }
2543    
2544    String LSCPServer::GetEffectInstanceInputControlInfo(int iEffectInstanceIndex, int iInputControlIndex) {
2545        dmsg(2,("LSCPServer: GetEffectInstanceInputControlInfo(%d,%d)\n", iEffectInstanceIndex, iInputControlIndex));
2546        LSCPResultSet result;
2547        try {
2548            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstanceIndex);
2549            if (!pEffect)
2550                throw Exception("There is no effect instance with index " + ToString(iEffectInstanceIndex));
2551    
2552            EffectControl* pEffectControl = pEffect->InputControl(iInputControlIndex);
2553            if (!pEffectControl)
2554                throw Exception(
2555                    "Effect instance " + ToString(iEffectInstanceIndex) +
2556                    " does not have an input control with index " +
2557                    ToString(iInputControlIndex)
2558                );
2559    
2560            result.Add("DESCRIPTION", _escapeLscpResponse(pEffectControl->Description()));
2561            result.Add("VALUE", pEffectControl->Value());
2562            if (pEffectControl->MinValue())
2563                 result.Add("RANGE_MIN", *pEffectControl->MinValue());
2564            if (pEffectControl->MaxValue())
2565                 result.Add("RANGE_MAX", *pEffectControl->MaxValue());
2566            if (!pEffectControl->Possibilities().empty())
2567                 result.Add("POSSIBILITIES", pEffectControl->Possibilities());
2568            if (pEffectControl->DefaultValue())
2569                 result.Add("DEFAULT", *pEffectControl->DefaultValue());
2570        } catch (Exception e) {
2571            result.Error(e);
2572        }
2573        return result.Produce();
2574    }
2575    
2576    String LSCPServer::SetEffectInstanceInputControl(int iEffectInstanceIndex, int iInputControlIndex, double dValue) {
2577        dmsg(2,("LSCPServer: SetEffectInstanceInputControl(%d,%d,%f)\n", iEffectInstanceIndex, iInputControlIndex, dValue));
2578        LSCPResultSet result;
2579        try {
2580            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstanceIndex);
2581            if (!pEffect)
2582                throw Exception("There is no effect instance with index " + ToString(iEffectInstanceIndex));
2583    
2584            EffectControl* pEffectControl = pEffect->InputControl(iInputControlIndex);
2585            if (!pEffectControl)
2586                throw Exception(
2587                    "Effect instance " + ToString(iEffectInstanceIndex) +
2588                    " does not have an input control with index " +
2589                    ToString(iInputControlIndex)
2590                );
2591    
2592            pEffectControl->SetValue(dValue);
2593        } catch (Exception e) {
2594            result.Error(e);
2595        }
2596        return result.Produce();
2597    }
2598    
2599    String LSCPServer::CreateEffectInstance(int index) {
2600        dmsg(2,("LSCPServer: CreateEffectInstance()\n"));
2601        LSCPResultSet result;
2602        try {
2603            EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(index);
2604            if (!pEffectInfo)
2605                throw Exception("There is no effect with index " + ToString(index));
2606            Effect* pEffect = EffectFactory::Create(pEffectInfo);
2607            result.Add(pEffect->ID());
2608        } catch (Exception e) {
2609            result.Error(e);
2610        }
2611        return result.Produce();
2612    }
2613    
2614    String LSCPServer::CreateEffectInstance(String effectSystem, String module, String effectName) {
2615        dmsg(2,("LSCPServer: CreateEffectInstance()\n"));
2616        LSCPResultSet result;
2617        try {
2618            // to allow loading the same LSCP session file on different systems
2619            // successfully, probably with different effect plugin DLL paths or even
2620            // running completely different operating systems, we do the following
2621            // for finding the right effect:
2622            //
2623            // first try to search for an exact match of the effect plugin DLL
2624            // (a.k.a 'module'), to avoid picking the wrong DLL with the same
2625            // effect name ...
2626            EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_MATCH_EXACTLY);
2627            // ... if no effect with exactly matchin DLL filename was found, then
2628            // try to lower the restrictions of matching the effect plugin DLL
2629            // filename and try again and again ...
2630            if (!pEffectInfo) {
2631                dmsg(2,("no exact module match, trying MODULE_IGNORE_PATH\n"));
2632                pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH);
2633            }
2634            if (!pEffectInfo) {
2635                dmsg(2,("no module match, trying MODULE_IGNORE_PATH | MODULE_IGNORE_CASE\n"));
2636                pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH | EffectFactory::MODULE_IGNORE_CASE);
2637            }
2638            if (!pEffectInfo) {
2639                dmsg(2,("no module match, trying MODULE_IGNORE_PATH | MODULE_IGNORE_CASE | MODULE_IGNORE_EXTENSION\n"));
2640                pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH | EffectFactory::MODULE_IGNORE_CASE | EffectFactory::MODULE_IGNORE_EXTENSION);
2641            }
2642            // ... if there was still no effect found, then completely ignore the
2643            // DLL plugin filename argument and just search for the matching effect
2644            // system type and effect name
2645            if (!pEffectInfo) {
2646                dmsg(2,("no module match, trying MODULE_IGNORE_ALL\n"));
2647                pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_ALL);
2648            }
2649            if (!pEffectInfo)
2650                throw Exception("There is no such effect '" + effectSystem + "' '" + module + "' '" + effectName + "'");
2651    
2652            Effect* pEffect = EffectFactory::Create(pEffectInfo);
2653            result = LSCPResultSet(pEffect->ID());
2654        } catch (Exception e) {
2655            result.Error(e);
2656        }
2657        return result.Produce();
2658    }
2659    
2660    String LSCPServer::DestroyEffectInstance(int iEffectID) {
2661        dmsg(2,("LSCPServer: DestroyEffectInstance(%d)\n", iEffectID));
2662        LSCPResultSet result;
2663        try {
2664            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectID);
2665            if (!pEffect)
2666                throw Exception("There is no effect instance with ID " + ToString(iEffectID));
2667            EffectFactory::Destroy(pEffect);
2668        } catch (Exception e) {
2669            result.Error(e);
2670        }
2671        return result.Produce();
2672    }
2673    
2674    String LSCPServer::GetEffectInstances() {
2675        dmsg(2,("LSCPServer: GetEffectInstances()\n"));
2676        LSCPResultSet result;
2677        try {
2678            int n = EffectFactory::EffectInstancesCount();
2679            result.Add(n);
2680        } catch (Exception e) {
2681            result.Error(e);
2682        }
2683        return result.Produce();
2684    }
2685    
2686    String LSCPServer::ListEffectInstances() {
2687        dmsg(2,("LSCPServer: ListEffectInstances()\n"));
2688        LSCPResultSet result;
2689        String list;
2690        try {
2691            int n = EffectFactory::EffectInstancesCount();
2692            for (int i = 0; i < n; i++) {
2693                Effect* pEffect = EffectFactory::GetEffectInstance(i);
2694                if (i) list += ",";
2695                list += ToString(pEffect->ID());
2696            }
2697        } catch (Exception e) {
2698            result.Error(e);
2699        }
2700        result.Add(list);
2701        return result.Produce();
2702    }
2703    
2704    String LSCPServer::GetMasterEffectChains(int iAudioOutputDevice) {
2705        dmsg(2,("LSCPServer: GetMasterEffectChains(%d)\n", iAudioOutputDevice));
2706        LSCPResultSet result;
2707        try {
2708            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2709            if (!devices.count(iAudioOutputDevice))
2710                throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2711            AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2712            int n = pDevice->MasterEffectChainCount();
2713            result.Add(n);
2714        } catch (Exception e) {
2715            result.Error(e);
2716        }
2717        return result.Produce();
2718    }
2719    
2720    String LSCPServer::ListMasterEffectChains(int iAudioOutputDevice) {
2721        dmsg(2,("LSCPServer: ListMasterEffectChains(%d)\n", iAudioOutputDevice));
2722        LSCPResultSet result;
2723        String list;
2724        try {
2725            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2726            if (!devices.count(iAudioOutputDevice))
2727                throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2728            AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2729            int n = pDevice->MasterEffectChainCount();
2730            for (int i = 0; i < n; i++) {
2731                EffectChain* pEffectChain = pDevice->MasterEffectChain(i);
2732                if (i) list += ",";
2733                list += ToString(pEffectChain->ID());
2734            }
2735        } catch (Exception e) {
2736            result.Error(e);
2737        }
2738        result.Add(list);
2739        return result.Produce();
2740    }
2741    
2742    String LSCPServer::AddMasterEffectChain(int iAudioOutputDevice) {
2743        dmsg(2,("LSCPServer: AddMasterEffectChain(%d)\n", iAudioOutputDevice));
2744        LSCPResultSet result;
2745        try {
2746            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2747            if (!devices.count(iAudioOutputDevice))
2748                throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2749            AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2750            EffectChain* pEffectChain = pDevice->AddMasterEffectChain();
2751            result.Add(pEffectChain->ID());
2752        } catch (Exception e) {
2753            result.Error(e);
2754        }
2755        return result.Produce();
2756    }
2757    
2758    String LSCPServer::RemoveMasterEffectChain(int iAudioOutputDevice, int iMasterEffectChain) {
2759        dmsg(2,("LSCPServer: RemoveMasterEffectChain(%d,%d)\n", iAudioOutputDevice, iMasterEffectChain));
2760        LSCPResultSet result;
2761        try {
2762            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2763            if (!devices.count(iAudioOutputDevice))
2764                throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2765            AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2766            for (int i = 0; i < pDevice->MasterEffectChainCount(); i++) {
2767                EffectChain* pEffectChain = pDevice->MasterEffectChain(i);
2768                if (pEffectChain->ID() == iMasterEffectChain) {
2769                    pDevice->RemoveMasterEffectChain(i);
2770                    return result.Produce();
2771                }
2772            }
2773            throw Exception(
2774                "There is no master effect chain with ID " +
2775                ToString(iMasterEffectChain) + " for audio output device " +
2776                ToString(iAudioOutputDevice) + "."
2777            );
2778        } catch (Exception e) {
2779            result.Error(e);
2780        }
2781        return result.Produce();
2782    }
2783    
2784    static EffectChain* _getMasterEffectChain(Sampler* pSampler, int iAudioOutputDevice, int iMasterEffectChain) throw (Exception) {
2785        std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2786        if (!devices.count(iAudioOutputDevice))
2787            throw Exception(
2788                "There is no audio output device with index " +
2789                ToString(iAudioOutputDevice) + "."
2790            );
2791        AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2792        for (int i = 0; i < pDevice->MasterEffectChainCount(); i++) {
2793            EffectChain* pEffectChain = pDevice->MasterEffectChain(i);
2794            if (pEffectChain->ID() == iMasterEffectChain) {
2795                return pEffectChain;
2796            }
2797        }
2798        throw Exception(
2799            "There is no master effect chain with ID " +
2800            ToString(iMasterEffectChain) + " for audio output device " +
2801            ToString(iAudioOutputDevice) + "."
2802        );
2803    }
2804    
2805    String LSCPServer::GetMasterEffectChainInfo(int iAudioOutputDevice, int iMasterEffectChain) {
2806        dmsg(2,("LSCPServer: GetMasterEffectChainInfo(%d,%d)\n", iAudioOutputDevice, iMasterEffectChain));
2807        LSCPResultSet result;
2808        try {
2809            EffectChain* pEffectChain =
2810                _getMasterEffectChain(pSampler, iAudioOutputDevice, iMasterEffectChain);
2811            String sEffectSequence;
2812            for (int i = 0; i < pEffectChain->EffectCount(); i++) {
2813                if (i) sEffectSequence += ",";
2814                sEffectSequence += ToString(pEffectChain->GetEffect(i)->ID());
2815            }
2816            result.Add("EFFECT_COUNT", pEffectChain->EffectCount());
2817            result.Add("EFFECT_SEQUENCE", sEffectSequence);
2818        } catch (Exception e) {
2819            result.Error(e);
2820        }
2821        return result.Produce();
2822    }
2823    
2824    String LSCPServer::AppendMasterEffectChainEffect(int iAudioOutputDevice, int iMasterEffectChain, int iEffectInstance) {
2825        dmsg(2,("LSCPServer: AppendMasterEffectChainEffect(%d,%d,%d)\n", iAudioOutputDevice, iMasterEffectChain, iEffectInstance));
2826        LSCPResultSet result;
2827        try {
2828            EffectChain* pEffectChain =
2829                _getMasterEffectChain(pSampler, iAudioOutputDevice, iMasterEffectChain);
2830            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2831            if (!pEffect)
2832                throw Exception("There is no effect instance with index " + ToString(iEffectInstance));
2833            pEffectChain->AppendEffect(pEffect);
2834        } catch (Exception e) {
2835            result.Error(e);
2836        }
2837        return result.Produce();
2838    }
2839    
2840    String LSCPServer::InsertMasterEffectChainEffect(int iAudioOutputDevice, int iMasterEffectChain, int iEffectInstance, int iEffectChainPosition) {
2841        dmsg(2,("LSCPServer: InsertMasterEffectChainEffect(%d,%d,%d,%d)\n", iAudioOutputDevice, iMasterEffectChain, iEffectInstance, iEffectChainPosition));
2842        LSCPResultSet result;
2843        try {
2844            EffectChain* pEffectChain =
2845                _getMasterEffectChain(pSampler, iAudioOutputDevice, iMasterEffectChain);
2846            Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2847            if (!pEffect)
2848                throw Exception("There is no effect instance with index " + ToString(iEffectInstance));
2849            pEffectChain->InsertEffect(pEffect, iEffectChainPosition);
2850        } catch (Exception e) {
2851            result.Error(e);
2852        }
2853        return result.Produce();
2854    }
2855    
2856    String LSCPServer::RemoveMasterEffectChainEffect(int iAudioOutputDevice, int iMasterEffectChain, int iEffectInstance) {
2857        dmsg(2,("LSCPServer: RemoveMasterEffectChainEffect(%d,%d,%d)\n", iAudioOutputDevice, iMasterEffectChain, iEffectInstance));
2858        LSCPResultSet result;
2859        try {
2860            EffectChain* pEffectChain =
2861                _getMasterEffectChain(pSampler, iAudioOutputDevice, iMasterEffectChain);
2862            for (int i = 0; i < pEffectChain->EffectCount(); i++) {
2863                Effect* pEffect = pEffectChain->GetEffect(i);
2864                if (pEffect->ID() == iEffectInstance) {
2865                    pEffectChain->RemoveEffect(i);
2866                    return result.Produce();
2867                }
2868            }
2869            throw Exception(
2870                "There is no effect instance with index " +
2871                ToString(iEffectInstance)
2872            );
2873        } catch (Exception e) {
2874            result.Error(e);
2875        }
2876        return result.Produce();
2877    }
2878    
2879  String LSCPServer::EditSamplerChannelInstrument(uint uiSamplerChannel) {  String LSCPServer::EditSamplerChannelInstrument(uint uiSamplerChannel) {
2880      dmsg(2,("LSCPServer: EditSamplerChannelInstrument(SamplerChannel=%d)\n", uiSamplerChannel));      dmsg(2,("LSCPServer: EditSamplerChannelInstrument(SamplerChannel=%d)\n", uiSamplerChannel));
2881      LSCPResultSet result;      LSCPResultSet result;
2882      try {      try {
2883          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
2884          if (pEngineChannel->InstrumentStatus() < 0) throw Exception("No instrument loaded to sampler channel");          if (pEngineChannel->InstrumentStatus() < 0) throw Exception("No instrument loaded to sampler channel");
2885          Engine* pEngine = pEngineChannel->GetEngine();          Engine* pEngine = pEngineChannel->GetEngine();
2886          InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();          InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();
# Line 2467  String LSCPServer::EditSamplerChannelIns Line 2895  String LSCPServer::EditSamplerChannelIns
2895      return result.Produce();      return result.Produce();
2896  }  }
2897    
2898    String LSCPServer::SendChannelMidiData(String MidiMsg, uint uiSamplerChannel, uint Arg1, uint Arg2) {
2899        dmsg(2,("LSCPServer: SendChannelMidiData(MidiMsg=%s,uiSamplerChannel=%d,Arg1=%d,Arg2=%d)\n", MidiMsg.c_str(), uiSamplerChannel, Arg1, Arg2));
2900        LSCPResultSet result;
2901        try {
2902            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2903    
2904            if (Arg1 > 127 || Arg2 > 127) {
2905                throw Exception("Invalid MIDI message");
2906            }
2907    
2908            VirtualMidiDevice* pMidiDevice = NULL;
2909            std::vector<EventHandler::midi_listener_entry>::iterator iter = eventHandler.channelMidiListeners.begin();
2910            for (; iter != eventHandler.channelMidiListeners.end(); ++iter) {
2911                if ((*iter).pEngineChannel == pEngineChannel) {
2912                    pMidiDevice = (*iter).pMidiListener;
2913                    break;
2914                }
2915            }
2916            
2917            if(pMidiDevice == NULL) throw Exception("Couldn't find virtual MIDI device");
2918    
2919            if (MidiMsg == "NOTE_ON") {
2920                pMidiDevice->SendNoteOnToDevice(Arg1, Arg2);
2921                bool b = pMidiDevice->SendNoteOnToSampler(Arg1, Arg2);
2922                if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
2923            } else if (MidiMsg == "NOTE_OFF") {
2924                pMidiDevice->SendNoteOffToDevice(Arg1, Arg2);
2925                bool b = pMidiDevice->SendNoteOffToSampler(Arg1, Arg2);
2926                if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
2927            } else if (MidiMsg == "CC") {
2928                pMidiDevice->SendCCToDevice(Arg1, Arg2);
2929                bool b = pMidiDevice->SendCCToSampler(Arg1, Arg2);
2930                if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
2931            } else {
2932                throw Exception("Unknown MIDI message type: " + MidiMsg);
2933            }
2934        } catch (Exception e) {
2935            result.Error(e);
2936        }
2937        return result.Produce();
2938    }
2939    
2940  /**  /**
2941   * Will be called by the parser to reset a particular sampler channel.   * Will be called by the parser to reset a particular sampler channel.
2942   */   */
# Line 2474  String LSCPServer::ResetChannel(uint uiS Line 2944  String LSCPServer::ResetChannel(uint uiS
2944      dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));      dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2945      LSCPResultSet result;      LSCPResultSet result;
2946      try {      try {
2947          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
         if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));  
         EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();  
         if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");  
2948          pEngineChannel->Reset();          pEngineChannel->Reset();
2949      }      }
2950      catch (Exception e) {      catch (Exception e) {
# Line 2543  String LSCPServer::GetTotalVoiceCount() Line 3010  String LSCPServer::GetTotalVoiceCount()
3010  String LSCPServer::GetTotalVoiceCountMax() {  String LSCPServer::GetTotalVoiceCountMax() {
3011      dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));      dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
3012      LSCPResultSet result;      LSCPResultSet result;
3013      result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);      result.Add(EngineFactory::EngineInstances().size() * GLOBAL_MAX_VOICES);
3014        return result.Produce();
3015    }
3016    
3017    /**
3018     * Will be called by the parser to return the sampler global maximum
3019     * allowed number of voices.
3020     */
3021    String LSCPServer::GetGlobalMaxVoices() {
3022        dmsg(2,("LSCPServer: GetGlobalMaxVoices()\n"));
3023        LSCPResultSet result;
3024        result.Add(GLOBAL_MAX_VOICES);
3025        return result.Produce();
3026    }
3027    
3028    /**
3029     * Will be called by the parser to set the sampler global maximum number of
3030     * voices.
3031     */
3032    String LSCPServer::SetGlobalMaxVoices(int iVoices) {
3033        dmsg(2,("LSCPServer: SetGlobalMaxVoices(%d)\n", iVoices));
3034        LSCPResultSet result;
3035        try {
3036            if (iVoices < 1) throw Exception("Maximum voices may not be less than 1");
3037            GLOBAL_MAX_VOICES = iVoices; // see common/global_private.cpp
3038            const std::set<Engine*>& engines = EngineFactory::EngineInstances();
3039            if (engines.size() > 0) {
3040                std::set<Engine*>::iterator iter = engines.begin();
3041                std::set<Engine*>::iterator end  = engines.end();
3042                for (; iter != end; ++iter) {
3043                    (*iter)->SetMaxVoices(iVoices);
3044                }
3045            }
3046            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOICES", GLOBAL_MAX_VOICES));
3047        } catch (Exception e) {
3048            result.Error(e);
3049        }
3050        return result.Produce();
3051    }
3052    
3053    /**
3054     * Will be called by the parser to return the sampler global maximum
3055     * allowed number of disk streams.
3056     */
3057    String LSCPServer::GetGlobalMaxStreams() {
3058        dmsg(2,("LSCPServer: GetGlobalMaxStreams()\n"));
3059        LSCPResultSet result;
3060        result.Add(GLOBAL_MAX_STREAMS);
3061        return result.Produce();
3062    }
3063    
3064    /**
3065     * Will be called by the parser to set the sampler global maximum number of
3066     * disk streams.
3067     */
3068    String LSCPServer::SetGlobalMaxStreams(int iStreams) {
3069        dmsg(2,("LSCPServer: SetGlobalMaxStreams(%d)\n", iStreams));
3070        LSCPResultSet result;
3071        try {
3072            if (iStreams < 0) throw Exception("Maximum disk streams may not be negative");
3073            GLOBAL_MAX_STREAMS = iStreams; // see common/global_private.cpp
3074            const std::set<Engine*>& engines = EngineFactory::EngineInstances();
3075            if (engines.size() > 0) {
3076                std::set<Engine*>::iterator iter = engines.begin();
3077                std::set<Engine*>::iterator end  = engines.end();
3078                for (; iter != end; ++iter) {
3079                    (*iter)->SetMaxDiskStreams(iStreams);
3080                }
3081            }
3082            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "STREAMS", GLOBAL_MAX_STREAMS));
3083        } catch (Exception e) {
3084            result.Error(e);
3085        }
3086      return result.Produce();      return result.Produce();
3087  }  }
3088    
# Line 2684  String LSCPServer::GetFileInstrumentInfo Line 3223  String LSCPServer::GetFileInstrumentInfo
3223                  result.Add("FORMAT_VERSION", info.FormatVersion);                  result.Add("FORMAT_VERSION", info.FormatVersion);
3224                  result.Add("PRODUCT", info.Product);                  result.Add("PRODUCT", info.Product);
3225                  result.Add("ARTISTS", info.Artists);                  result.Add("ARTISTS", info.Artists);
3226    
3227                    std::stringstream ss;
3228                    bool b = false;
3229                    for (int i = 0; i < 128; i++) {
3230                        if (info.KeyBindings[i]) {
3231                            if (b) ss << ',';
3232                            ss << i; b = true;
3233                        }
3234                    }
3235                    result.Add("KEY_BINDINGS", ss.str());
3236    
3237                    b = false;
3238                    std::stringstream ss2;
3239                    for (int i = 0; i < 128; i++) {
3240                        if (info.KeySwitchBindings[i]) {
3241                            if (b) ss2 << ',';
3242                            ss2 << i; b = true;
3243                        }
3244                    }
3245                    result.Add("KEYSWITCH_BINDINGS", ss2.str());
3246                  // no more need to ask other engine types                  // no more need to ask other engine types
3247                  bFound = true;                  bFound = true;
3248              } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));              } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
# Line 2711  void LSCPServer::VerifyFile(String Filen Line 3270  void LSCPServer::VerifyFile(String Filen
3270          throw Exception("Directory is specified");          throw Exception("Directory is specified");
3271      }      }
3272      #else      #else
3273      struct stat statBuf;      File f(Filename);
3274      int res = stat(Filename.c_str(), &statBuf);      if(!f.Exist()) throw Exception(f.GetErrorMsg());
3275      if (res) {      if (f.IsDirectory()) throw Exception("Directory is specified");
         std::stringstream ss;  
         ss << "Fail to stat `" << Filename << "`: " << strerror(errno);  
         throw Exception(ss.str());  
     }  
   
     if (S_ISDIR(statBuf.st_mode)) {  
         throw Exception("Directory is specified");  
     }  
3276      #endif      #endif
3277  }  }
3278    
# Line 2916  String LSCPServer::AddDbInstruments(Stri Line 3467  String LSCPServer::AddDbInstruments(Stri
3467      return result.Produce();      return result.Produce();
3468  }  }
3469    
3470  String LSCPServer::AddDbInstruments(String ScanMode, String DbDir, String FsDir, bool bBackground) {  String LSCPServer::AddDbInstruments(String ScanMode, String DbDir, String FsDir, bool bBackground, bool insDir) {
3471      dmsg(2,("LSCPServer: AddDbInstruments(ScanMode=%s,DbDir=%s,FsDir=%s,bBackground=%d)\n", ScanMode.c_str(), DbDir.c_str(), FsDir.c_str(), bBackground));      dmsg(2,("LSCPServer: AddDbInstruments(ScanMode=%s,DbDir=%s,FsDir=%s,bBackground=%d,insDir=%d)\n", ScanMode.c_str(), DbDir.c_str(), FsDir.c_str(), bBackground, insDir));
3472      LSCPResultSet result;      LSCPResultSet result;
3473  #if HAVE_SQLITE3  #if HAVE_SQLITE3
3474      try {      try {
3475          int id;          int id;
3476          InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();          InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
3477          if (ScanMode.compare("RECURSIVE") == 0) {          if (ScanMode.compare("RECURSIVE") == 0) {
3478             id = db->AddInstruments(RECURSIVE, DbDir, FsDir, bBackground);              id = db->AddInstruments(RECURSIVE, DbDir, FsDir, bBackground, insDir);
3479          } else if (ScanMode.compare("NON_RECURSIVE") == 0) {          } else if (ScanMode.compare("NON_RECURSIVE") == 0) {
3480             id = db->AddInstruments(NON_RECURSIVE, DbDir, FsDir, bBackground);              id = db->AddInstruments(NON_RECURSIVE, DbDir, FsDir, bBackground, insDir);
3481          } else if (ScanMode.compare("FLAT") == 0) {          } else if (ScanMode.compare("FLAT") == 0) {
3482             id = db->AddInstruments(FLAT, DbDir, FsDir, bBackground);              id = db->AddInstruments(FLAT, DbDir, FsDir, bBackground, insDir);
3483          } else {          } else {
3484              throw Exception("Unknown scan mode: " + ScanMode);              throw Exception("Unknown scan mode: " + ScanMode);
3485          }          }
# Line 3272  String LSCPServer::SetEcho(yyparse_param Line 3823  String LSCPServer::SetEcho(yyparse_param
3823      }      }
3824      return result.Produce();      return result.Produce();
3825  }  }
3826    
3827    }

Legend:
Removed from v.1727  
changed lines
  Added in v.2135

  ViewVC Help
Powered by ViewVC