/[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 778 by iliev, Fri Sep 23 06:58:26 2005 UTC revision 1686 by schoenebeck, Thu Feb 14 14:58:50 2008 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 Christian Schoenebeck                              *   *   Copyright (C) 2005 - 2008 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 24  Line 24 
24  #include "lscpserver.h"  #include "lscpserver.h"
25  #include "lscpresultset.h"  #include "lscpresultset.h"
26  #include "lscpevent.h"  #include "lscpevent.h"
 //#include "../common/global.h"  
27    
28    #if defined(WIN32)
29    #include <windows.h>
30    #else
31  #include <fcntl.h>  #include <fcntl.h>
32    #endif
33    
34  #if HAVE_SQLITE3  #if ! HAVE_SQLITE3
35  # include "sqlite3.h"  #define DOESNT_HAVE_SQLITE3 "No database support. SQLITE3 was not installed when linuxsampler was built."
36  #endif  #endif
37    
38  #include "../engines/EngineFactory.h"  #include "../engines/EngineFactory.h"
# Line 37  Line 40 
40  #include "../drivers/audio/AudioOutputDeviceFactory.h"  #include "../drivers/audio/AudioOutputDeviceFactory.h"
41  #include "../drivers/midi/MidiInputDeviceFactory.h"  #include "../drivers/midi/MidiInputDeviceFactory.h"
42    
43    
44    /**
45     * Returns a copy of the given string where all special characters are
46     * replaced by LSCP escape sequences ("\xHH"). This function shall be used
47     * to escape LSCP response fields in case the respective response field is
48     * actually defined as using escape sequences in the LSCP specs.
49     *
50     * @e Caution: DO NOT use this function for escaping path based responses,
51     * use the Path class (src/common/Path.h) for this instead!
52     */
53    static String _escapeLscpResponse(String txt) {
54        for (int i = 0; i < txt.length(); i++) {
55            const char c = txt.c_str()[i];
56            if (
57                !(c >= '0' && c <= '9') &&
58                !(c >= 'a' && c <= 'z') &&
59                !(c >= 'A' && c <= 'Z') &&
60                !(c == ' ') && !(c == '!') && !(c == '#') && !(c == '$') &&
61                !(c == '%') && !(c == '&') && !(c == '(') && !(c == ')') &&
62                !(c == '*') && !(c == '+') && !(c == ',') && !(c == '-') &&
63                !(c == '.') && !(c == '/') && !(c == ':') && !(c == ';') &&
64                !(c == '<') && !(c == '=') && !(c == '>') && !(c == '?') &&
65                !(c == '@') && !(c == '[') && !(c == ']') &&
66                !(c == '^') && !(c == '_') && !(c == '`') && !(c == '{') &&
67                !(c == '|') && !(c == '}') && !(c == '~')
68            ) {
69                // convert the "special" character into a "\xHH" LSCP escape sequence
70                char buf[5];
71                snprintf(buf, sizeof(buf), "\\x%02x", static_cast<unsigned char>(c));
72                txt.replace(i, 1, buf);
73                i += 3;
74            }
75        }
76        return txt;
77    }
78    
79  /**  /**
80   * Below are a few static members of the LSCPServer class.   * Below are a few static members of the LSCPServer class.
81   * The big assumption here is that LSCPServer is going to remain a singleton.   * The big assumption here is that LSCPServer is going to remain a singleton.
# Line 53  Line 92 
92  fd_set LSCPServer::fdSet;  fd_set LSCPServer::fdSet;
93  int LSCPServer::currentSocket = -1;  int LSCPServer::currentSocket = -1;
94  std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();  std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();
95    std::vector<yyparse_param_t>::iterator itCurrentSession = std::vector<yyparse_param_t>::iterator();
96  std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();  std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();
97  std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();  std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();
98  std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();  std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();
# Line 61  Mutex LSCPServer::NotifyBufferMutex = Mu Line 101  Mutex LSCPServer::NotifyBufferMutex = Mu
101  Mutex LSCPServer::SubscriptionMutex = Mutex();  Mutex LSCPServer::SubscriptionMutex = Mutex();
102  Mutex LSCPServer::RTNotifyMutex = Mutex();  Mutex LSCPServer::RTNotifyMutex = Mutex();
103    
104  LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4) {  LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4), eventHandler(this) {
105      SocketAddress.sin_family      = AF_INET;      SocketAddress.sin_family      = AF_INET;
106      SocketAddress.sin_addr.s_addr = addr;      SocketAddress.sin_addr.s_addr = addr;
107      SocketAddress.sin_port        = port;      SocketAddress.sin_port        = port;
108      this->pSampler = pSampler;      this->pSampler = pSampler;
109        LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
110        LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
111        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_count, "MIDI_INPUT_DEVICE_COUNT");
112        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_info, "MIDI_INPUT_DEVICE_INFO");
113      LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");
114      LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
115      LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
116      LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");      LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
117      LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");      LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");
118        LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_count, "FX_SEND_COUNT");
119        LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_info, "FX_SEND_INFO");
120        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_count, "MIDI_INSTRUMENT_MAP_COUNT");
121        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_info, "MIDI_INSTRUMENT_MAP_INFO");
122        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_count, "MIDI_INSTRUMENT_COUNT");
123        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_info, "MIDI_INSTRUMENT_INFO");
124        LSCPEvent::RegisterEvent(LSCPEvent::event_db_instr_dir_count, "DB_INSTRUMENT_DIRECTORY_COUNT");
125        LSCPEvent::RegisterEvent(LSCPEvent::event_db_instr_dir_info, "DB_INSTRUMENT_DIRECTORY_INFO");
126        LSCPEvent::RegisterEvent(LSCPEvent::event_db_instr_count, "DB_INSTRUMENT_COUNT");
127        LSCPEvent::RegisterEvent(LSCPEvent::event_db_instr_info, "DB_INSTRUMENT_INFO");
128        LSCPEvent::RegisterEvent(LSCPEvent::event_db_instrs_job_info, "DB_INSTRUMENTS_JOB_INFO");
129      LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");      LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
130        LSCPEvent::RegisterEvent(LSCPEvent::event_total_stream_count, "TOTAL_STREAM_COUNT");
131      LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");
132        LSCPEvent::RegisterEvent(LSCPEvent::event_global_info, "GLOBAL_INFO");
133        LSCPEvent::RegisterEvent(LSCPEvent::event_channel_midi, "CHANNEL_MIDI");
134      hSocket = -1;      hSocket = -1;
135  }  }
136    
137  LSCPServer::~LSCPServer() {  LSCPServer::~LSCPServer() {
138    #if defined(WIN32)
139        if (hSocket >= 0) closesocket(hSocket);
140    #else
141      if (hSocket >= 0) close(hSocket);      if (hSocket >= 0) close(hSocket);
142    #endif
143    }
144    
145    LSCPServer::EventHandler::EventHandler(LSCPServer* pParent) {
146        this->pParent = pParent;
147    }
148    
149    LSCPServer::EventHandler::~EventHandler() {
150        std::vector<midi_listener_entry> l = channelMidiListeners;
151        channelMidiListeners.clear();
152        for (int i = 0; i < l.size(); i++)
153            delete l[i].pMidiListener;
154    }
155    
156    void LSCPServer::EventHandler::ChannelCountChanged(int NewCount) {
157        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_count, NewCount));
158    }
159    
160    void LSCPServer::EventHandler::ChannelAdded(SamplerChannel* pChannel) {
161        pChannel->AddEngineChangeListener(this);
162    }
163    
164    void LSCPServer::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
165        if (!pChannel->GetEngineChannel()) return;
166        EngineToBeChanged(pChannel->Index());
167    }
168    
169    void LSCPServer::EventHandler::EngineToBeChanged(int ChannelId) {
170        SamplerChannel* pSamplerChannel =
171            pParent->pSampler->GetSamplerChannel(ChannelId);
172        if (!pSamplerChannel) return;
173        EngineChannel* pEngineChannel =
174            pSamplerChannel->GetEngineChannel();
175        if (!pEngineChannel) return;
176        for (std::vector<midi_listener_entry>::iterator iter = channelMidiListeners.begin(); iter != channelMidiListeners.end(); ++iter) {
177            if ((*iter).pEngineChannel == pEngineChannel) {
178                VirtualMidiDevice* pMidiListener = (*iter).pMidiListener;
179                pEngineChannel->Disconnect(pMidiListener);
180                channelMidiListeners.erase(iter);
181                delete pMidiListener;
182                return;
183            }
184        }
185    }
186    
187    void LSCPServer::EventHandler::EngineChanged(int ChannelId) {
188        SamplerChannel* pSamplerChannel =
189            pParent->pSampler->GetSamplerChannel(ChannelId);
190        if (!pSamplerChannel) return;
191        EngineChannel* pEngineChannel =
192            pSamplerChannel->GetEngineChannel();
193        if (!pEngineChannel) return;
194        VirtualMidiDevice* pMidiListener = new VirtualMidiDevice;
195        pEngineChannel->Connect(pMidiListener);
196        midi_listener_entry entry = {
197            pSamplerChannel, pEngineChannel, pMidiListener
198        };
199        channelMidiListeners.push_back(entry);
200    }
201    
202    void LSCPServer::EventHandler::AudioDeviceCountChanged(int NewCount) {
203        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_count, NewCount));
204    }
205    
206    void LSCPServer::EventHandler::MidiDeviceCountChanged(int NewCount) {
207        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_count, NewCount));
208    }
209    
210    void LSCPServer::EventHandler::MidiInstrumentCountChanged(int MapId, int NewCount) {
211        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_count, MapId, NewCount));
212    }
213    
214    void LSCPServer::EventHandler::MidiInstrumentInfoChanged(int MapId, int Bank, int Program) {
215        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_info, MapId, Bank, Program));
216    }
217    
218    void LSCPServer::EventHandler::MidiInstrumentMapCountChanged(int NewCount) {
219        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_count, NewCount));
220    }
221    
222    void LSCPServer::EventHandler::MidiInstrumentMapInfoChanged(int MapId) {
223        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_info, MapId));
224    }
225    
226    void LSCPServer::EventHandler::FxSendCountChanged(int ChannelId, int NewCount) {
227        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_count, ChannelId, NewCount));
228    }
229    
230    void LSCPServer::EventHandler::VoiceCountChanged(int ChannelId, int NewCount) {
231        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_voice_count, ChannelId, NewCount));
232  }  }
233    
234    void LSCPServer::EventHandler::StreamCountChanged(int ChannelId, int NewCount) {
235        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_stream_count, ChannelId, NewCount));
236    }
237    
238    void LSCPServer::EventHandler::BufferFillChanged(int ChannelId, String FillData) {
239        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_buffer_fill, ChannelId, FillData));
240    }
241    
242    void LSCPServer::EventHandler::TotalVoiceCountChanged(int NewCount) {
243        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_total_voice_count, NewCount));
244    }
245    
246    void LSCPServer::EventHandler::TotalStreamCountChanged(int NewCount) {
247        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_total_stream_count, NewCount));
248    }
249    
250    #if HAVE_SQLITE3
251    void LSCPServer::DbInstrumentsEventHandler::DirectoryCountChanged(String Dir) {
252        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_dir_count, InstrumentsDb::toEscapedPath(Dir)));
253    }
254    
255    void LSCPServer::DbInstrumentsEventHandler::DirectoryInfoChanged(String Dir) {
256        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_dir_info, InstrumentsDb::toEscapedPath(Dir)));
257    }
258    
259    void LSCPServer::DbInstrumentsEventHandler::DirectoryNameChanged(String Dir, String NewName) {
260        Dir = "'" + InstrumentsDb::toEscapedPath(Dir) + "'";
261        NewName = "'" + InstrumentsDb::toEscapedPath(NewName) + "'";
262        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_dir_info, "NAME", Dir, NewName));
263    }
264    
265    void LSCPServer::DbInstrumentsEventHandler::InstrumentCountChanged(String Dir) {
266        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_count, InstrumentsDb::toEscapedPath(Dir)));
267    }
268    
269    void LSCPServer::DbInstrumentsEventHandler::InstrumentInfoChanged(String Instr) {
270        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_info, InstrumentsDb::toEscapedPath(Instr)));
271    }
272    
273    void LSCPServer::DbInstrumentsEventHandler::InstrumentNameChanged(String Instr, String NewName) {
274        Instr = "'" + InstrumentsDb::toEscapedPath(Instr) + "'";
275        NewName = "'" + InstrumentsDb::toEscapedPath(NewName) + "'";
276        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_info, "NAME", Instr, NewName));
277    }
278    
279    void LSCPServer::DbInstrumentsEventHandler::JobStatusChanged(int JobId) {
280        LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instrs_job_info, JobId));
281    }
282    #endif // HAVE_SQLITE3
283    
284    
285  /**  /**
286   * Blocks the calling thread until the LSCP Server is initialized and   * Blocks the calling thread until the LSCP Server is initialized and
287   * accepting socket connections, if the server is already initialized then   * accepting socket connections, if the server is already initialized then
# Line 95  int LSCPServer::WaitUntilInitialized(lon Line 297  int LSCPServer::WaitUntilInitialized(lon
297  }  }
298    
299  int LSCPServer::Main() {  int LSCPServer::Main() {
300            #if defined(WIN32)
301            WSADATA wsaData;
302            int iResult;
303            iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
304            if (iResult != 0) {
305                    std::cerr << "LSCPServer: WSAStartup failed: " << iResult << "\n";
306                    exit(EXIT_FAILURE);
307            }
308            #endif
309      hSocket = socket(AF_INET, SOCK_STREAM, 0);      hSocket = socket(AF_INET, SOCK_STREAM, 0);
310      if (hSocket < 0) {      if (hSocket < 0) {
311          std::cerr << "LSCPServer: Could not create server socket." << std::endl;          std::cerr << "LSCPServer: Could not create server socket." << std::endl;
# Line 108  int LSCPServer::Main() { Line 319  int LSCPServer::Main() {
319              if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {              if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
320                  if (trial > LSCP_SERVER_BIND_TIMEOUT) {                  if (trial > LSCP_SERVER_BIND_TIMEOUT) {
321                      std::cerr << "gave up!" << std::endl;                      std::cerr << "gave up!" << std::endl;
322                        #if defined(WIN32)
323                        closesocket(hSocket);
324                        #else
325                      close(hSocket);                      close(hSocket);
326                        #endif
327                      //return -1;                      //return -1;
328                      exit(EXIT_FAILURE);                      exit(EXIT_FAILURE);
329                  }                  }
# Line 121  int LSCPServer::Main() { Line 336  int LSCPServer::Main() {
336      listen(hSocket, 1);      listen(hSocket, 1);
337      Initialized.Set(true);      Initialized.Set(true);
338    
339        // Registering event listeners
340        pSampler->AddChannelCountListener(&eventHandler);
341        pSampler->AddAudioDeviceCountListener(&eventHandler);
342        pSampler->AddMidiDeviceCountListener(&eventHandler);
343        pSampler->AddVoiceCountListener(&eventHandler);
344        pSampler->AddStreamCountListener(&eventHandler);
345        pSampler->AddBufferFillListener(&eventHandler);
346        pSampler->AddTotalStreamCountListener(&eventHandler);
347        pSampler->AddTotalVoiceCountListener(&eventHandler);
348        pSampler->AddFxSendCountListener(&eventHandler);
349        MidiInstrumentMapper::AddMidiInstrumentCountListener(&eventHandler);
350        MidiInstrumentMapper::AddMidiInstrumentInfoListener(&eventHandler);
351        MidiInstrumentMapper::AddMidiInstrumentMapCountListener(&eventHandler);
352        MidiInstrumentMapper::AddMidiInstrumentMapInfoListener(&eventHandler);
353    #if HAVE_SQLITE3
354        InstrumentsDb::GetInstrumentsDb()->AddInstrumentsDbListener(&dbInstrumentsEventHandler);
355    #endif
356      // now wait for client connections and handle their requests      // now wait for client connections and handle their requests
357      sockaddr_in client;      sockaddr_in client;
358      int length = sizeof(client);      int length = sizeof(client);
# Line 128  int LSCPServer::Main() { Line 360  int LSCPServer::Main() {
360      FD_SET(hSocket, &fdSet);      FD_SET(hSocket, &fdSet);
361      int maxSessions = hSocket;      int maxSessions = hSocket;
362    
363        timeval timeout;
364    
365      while (true) {      while (true) {
366          fd_set selectSet = fdSet;          #if CONFIG_PTHREAD_TESTCANCEL
367          int retval = select(maxSessions+1, &selectSet, NULL, NULL, NULL);                  TestCancel();
368            #endif
369            // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers
370            {
371                std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
372                std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
373                std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();
374                for (; itEngineChannel != itEnd; ++itEngineChannel) {
375                    if ((*itEngineChannel)->StatusChanged()) {
376                        SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));
377                    }
378    
379                    for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
380                        FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
381                        if(fxs != NULL && fxs->IsInfoChanged()) {
382                            int chn = (*itEngineChannel)->iSamplerChannelIndex;
383                            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));
384                            fxs->SetInfoChanged(false);
385                        }
386                    }
387                }
388            }
389    
390            // check if MIDI data arrived on some engine channel
391            for (int i = 0; i < eventHandler.channelMidiListeners.size(); ++i) {
392                const EventHandler::midi_listener_entry entry =
393                    eventHandler.channelMidiListeners[i];
394                VirtualMidiDevice* pMidiListener = entry.pMidiListener;
395                if (pMidiListener->NotesChanged()) {
396                    for (int iNote = 0; iNote < 128; iNote++) {
397                        if (pMidiListener->NoteChanged(iNote)) {
398                            const bool bActive = pMidiListener->NoteIsActive(iNote);
399                            LSCPServer::SendLSCPNotify(
400                                LSCPEvent(
401                                    LSCPEvent::event_channel_midi,
402                                    entry.pSamplerChannel->Index(),
403                                    std::string(bActive ? "NOTE_ON" : "NOTE_OFF"),
404                                    iNote,
405                                    bActive ? pMidiListener->NoteOnVelocity(iNote)
406                                            : pMidiListener->NoteOffVelocity(iNote)
407                                )
408                            );
409                        }
410                    }
411                }
412            }
413    
414            //Now let's deliver late notifies (if any)
415            NotifyBufferMutex.Lock();
416            for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
417    #ifdef MSG_NOSIGNAL
418                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), MSG_NOSIGNAL);
419    #else
420                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
421    #endif
422            }
423            bufferedNotifies.clear();
424            NotifyBufferMutex.Unlock();
425    
426            fd_set selectSet = fdSet;
427            timeout.tv_sec  = 0;
428            timeout.tv_usec = 100000;
429    
430            int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
431    
432          if (retval == 0)          if (retval == 0)
433                  continue; //Nothing try again                  continue; //Nothing try again
434          if (retval == -1) {          if (retval == -1) {
435                  std::cerr << "LSCPServer: Socket select error." << std::endl;                  std::cerr << "LSCPServer: Socket select error." << std::endl;
436                    #if defined(WIN32)
437                    closesocket(hSocket);
438                    #else
439                  close(hSocket);                  close(hSocket);
440                    #endif
441                  exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
442          }          }
443    
# Line 147  int LSCPServer::Main() { Line 449  int LSCPServer::Main() {
449                          exit(EXIT_FAILURE);                          exit(EXIT_FAILURE);
450                  }                  }
451    
452                    #if defined(WIN32)
453                    u_long nonblock_io = 1;
454                    if( ioctlsocket(socket, FIONBIO, &nonblock_io) ) {
455                      std::cerr << "LSCPServer: ioctlsocket: set FIONBIO failed. Error " << WSAGetLastError() << std::endl;
456                      exit(EXIT_FAILURE);
457                    }
458            #else
459                  if (fcntl(socket, F_SETFL, O_NONBLOCK)) {                  if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
460                          std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;                          std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
461                          exit(EXIT_FAILURE);                          exit(EXIT_FAILURE);
462                  }                  }
463                    #endif
464    
465                  // Parser initialization                  // Parser initialization
466                  yyparse_param_t yyparse_param;                  yyparse_param_t yyparse_param;
# Line 174  int LSCPServer::Main() { Line 484  int LSCPServer::Main() {
484                                  int dummy; // just a temporary hack to fulfill the restart() function prototype                                  int dummy; // just a temporary hack to fulfill the restart() function prototype
485                                  restart(NULL, dummy); // restart the 'scanner'                                  restart(NULL, dummy); // restart the 'scanner'
486                                  currentSocket = (*iter).hSession;  //a hack                                  currentSocket = (*iter).hSession;  //a hack
487                                    itCurrentSession = iter; // another hack
488                                  dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));                                  dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
489                                  if ((*iter).bVerbose) { // if echo mode enabled                                  if ((*iter).bVerbose) { // if echo mode enabled
490                                      AnswerClient(bufferedCommands[currentSocket]);                                      AnswerClient(bufferedCommands[currentSocket]);
491                                  }                                  }
492                                  int result = yyparse(&(*iter));                                  int result = yyparse(&(*iter));
493                                  currentSocket = -1;     //continuation of a hack                                  currentSocket = -1;     //continuation of a hack
494                                    itCurrentSession = Sessions.end(); // hack as well
495                                  dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));                                  dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));
496                                  if (result == LSCP_QUIT) { //Was it a quit command by any chance?                                  if (result == LSCP_QUIT) { //Was it a quit command by any chance?
497                                          CloseConnection(iter);                                          CloseConnection(iter);
# Line 190  int LSCPServer::Main() { Line 502  int LSCPServer::Main() {
502                          break;                          break;
503                  }                  }
504          }          }
   
         // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers  
         {  
             std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();  
             std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();  
             std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();  
             for (; itEngineChannel != itEnd; ++itEngineChannel) {  
                 if ((*itEngineChannel)->StatusChanged()) {  
                     SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));  
                 }  
             }  
         }  
   
         //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(), MSG_NOSIGNAL);  
                 bufferedNotifies.erase(iterNotify);  
         }  
         NotifyBufferMutex.Unlock();  
505      }      }
506  }  }
507    
# Line 227  void LSCPServer::CloseConnection( std::v Line 519  void LSCPServer::CloseConnection( std::v
519          NotifyMutex.Lock();          NotifyMutex.Lock();
520          bufferedCommands.erase(socket);          bufferedCommands.erase(socket);
521          bufferedNotifies.erase(socket);          bufferedNotifies.erase(socket);
522            #if defined(WIN32)
523            closesocket(socket);
524            #else
525          close(socket);          close(socket);
526            #endif
527          NotifyMutex.Unlock();          NotifyMutex.Unlock();
528  }  }
529    
530    void LSCPServer::LockRTNotify() {
531        RTNotifyMutex.Lock();
532    }
533    
534    void LSCPServer::UnlockRTNotify() {
535        RTNotifyMutex.Unlock();
536    }
537    
538  int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {  int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
539          int subs = 0;          int subs = 0;
540          SubscriptionMutex.Lock();          SubscriptionMutex.Lock();
# Line 256  void LSCPServer::SendLSCPNotify( LSCPEve Line 560  void LSCPServer::SendLSCPNotify( LSCPEve
560          while (true) {          while (true) {
561                  if (NotifyMutex.Trylock()) {                  if (NotifyMutex.Trylock()) {
562                          for(;iter != end; iter++)                          for(;iter != end; iter++)
563    #ifdef MSG_NOSIGNAL
564                                  send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);                                  send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);
565    #else
566                                    send(*iter, notify.c_str(), notify.size(), 0);
567    #endif
568                          NotifyMutex.Unlock();                          NotifyMutex.Unlock();
569                          break;                          break;
570                  } else {                  } else {
# Line 288  extern int GetLSCPCommand( void *buf, in Line 596  extern int GetLSCPCommand( void *buf, in
596          return command.size();          return command.size();
597  }  }
598    
599    extern yyparse_param_t* GetCurrentYaccSession() {
600        return &(*itCurrentSession);
601    }
602    
603  /**  /**
604   * Will be called to try to read the command from the socket   * Will be called to try to read the command from the socket
605   * If command is read, it will return true. Otherwise false is returned.   * If command is read, it will return true. Otherwise false is returned.
# Line 298  bool LSCPServer::GetLSCPCommand( std::ve Line 610  bool LSCPServer::GetLSCPCommand( std::ve
610          char c;          char c;
611          int i = 0;          int i = 0;
612          while (true) {          while (true) {
613                    #if defined(WIN32)
614                    int result = recv(socket, (char *)&c, 1, 0); //Read one character at a time for now
615                    #else
616                  int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now                  int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
617                    #endif
618                  if (result == 0) { //socket was selected, so 0 here means client has closed the connection                  if (result == 0) { //socket was selected, so 0 here means client has closed the connection
619                          CloseConnection(iter);                          CloseConnection(iter);
620                          break;                          break;
# Line 308  bool LSCPServer::GetLSCPCommand( std::ve Line 624  bool LSCPServer::GetLSCPCommand( std::ve
624                                  continue; //Ignore CR                                  continue; //Ignore CR
625                          if (c == '\n') {                          if (c == '\n') {
626                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
627                                  bufferedCommands[socket] += "\n";                                  bufferedCommands[socket] += "\r\n";
628                                  return true; //Complete command was read                                  return true; //Complete command was read
629                          }                          }
630                          bufferedCommands[socket] += c;                          bufferedCommands[socket] += c;
631                  }                  }
632                    #if defined(WIN32)
633                    if (result == SOCKET_ERROR) {
634                        int wsa_lasterror = WSAGetLastError();
635                            if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.
636                                    return false;
637                            dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));
638                            CloseConnection(iter);
639                            break;
640                    }
641                    #else
642                  if (result == -1) {                  if (result == -1) {
643                          if (errno == EAGAIN) //Would block, try again later.                          if (errno == EAGAIN) //Would block, try again later.
644                                  return false;                                  return false;
# Line 351  bool LSCPServer::GetLSCPCommand( std::ve Line 677  bool LSCPServer::GetLSCPCommand( std::ve
677                          CloseConnection(iter);                          CloseConnection(iter);
678                          break;                          break;
679                  }                  }
680                    #endif
681          }          }
682          return false;          return false;
683  }  }
# Line 365  void LSCPServer::AnswerClient(String Ret Line 692  void LSCPServer::AnswerClient(String Ret
692      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
693      if (currentSocket != -1) {      if (currentSocket != -1) {
694              NotifyMutex.Lock();              NotifyMutex.Lock();
695    #ifdef MSG_NOSIGNAL
696              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);              send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
697    #else
698                send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
699    #endif
700              NotifyMutex.Unlock();              NotifyMutex.Unlock();
701      }      }
702  }  }
# Line 409  String LSCPServer::CreateAudioOutputDevi Line 740  String LSCPServer::CreateAudioOutputDevi
740          AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);          AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
741          // search for the created device to get its index          // search for the created device to get its index
742          int index = GetAudioOutputDeviceIndex(pDevice);          int index = GetAudioOutputDeviceIndex(pDevice);
743          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.");
744          result = index; // success          result = index; // success
745      }      }
746      catch (LinuxSamplerException e) {      catch (Exception e) {
747          result.Error(e);          result.Error(e);
748      }      }
749      return result.Produce();      return result.Produce();
# Line 425  String LSCPServer::CreateMidiInputDevice Line 756  String LSCPServer::CreateMidiInputDevice
756          MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);          MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
757          // search for the created device to get its index          // search for the created device to get its index
758          int index = GetMidiInputDeviceIndex(pDevice);          int index = GetMidiInputDeviceIndex(pDevice);
759          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.");
760          result = index; // success          result = index; // success
761      }      }
762      catch (LinuxSamplerException e) {      catch (Exception e) {
763          result.Error(e);          result.Error(e);
764      }      }
765      return result.Produce();      return result.Produce();
# Line 439  String LSCPServer::DestroyAudioOutputDev Line 770  String LSCPServer::DestroyAudioOutputDev
770      LSCPResultSet result;      LSCPResultSet result;
771      try {      try {
772          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
773          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) + ".");
774          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
775          pSampler->DestroyAudioOutputDevice(pDevice);          pSampler->DestroyAudioOutputDevice(pDevice);
776      }      }
777      catch (LinuxSamplerException e) {      catch (Exception e) {
778          result.Error(e);          result.Error(e);
779      }      }
780      return result.Produce();      return result.Produce();
# Line 454  String LSCPServer::DestroyMidiInputDevic Line 785  String LSCPServer::DestroyMidiInputDevic
785      LSCPResultSet result;      LSCPResultSet result;
786      try {      try {
787          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
788          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) + ".");
789          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
790          pSampler->DestroyMidiInputDevice(pDevice);          pSampler->DestroyMidiInputDevice(pDevice);
791      }      }
792      catch (LinuxSamplerException e) {      catch (Exception e) {
793          result.Error(e);          result.Error(e);
794      }      }
795      return result.Produce();      return result.Produce();
796  }  }
797    
798    EngineChannel* LSCPServer::GetEngineChannel(uint uiSamplerChannel) {
799        SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
800        if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
801    
802        EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
803        if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
804    
805        return pEngineChannel;
806    }
807    
808  /**  /**
809   * Will be called by the parser to load an instrument.   * Will be called by the parser to load an instrument.
810   */   */
# Line 472  String LSCPServer::LoadInstrument(String Line 813  String LSCPServer::LoadInstrument(String
813      LSCPResultSet result;      LSCPResultSet result;
814      try {      try {
815          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
816          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
817          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
818          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel yet");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
819          if (!pSamplerChannel->GetAudioOutputDevice())          if (!pSamplerChannel->GetAudioOutputDevice())
820              throw LinuxSamplerException("No audio output device connected to sampler channel");              throw Exception("No audio output device connected to sampler channel");
821          if (bBackground) {          if (bBackground) {
822              InstrumentLoader.StartNewLoad(Filename, uiInstrument, pEngineChannel);              InstrumentManager::instrument_id_t id;
823                id.FileName = Filename;
824                id.Index    = uiInstrument;
825                InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
826          }          }
827          else {          else {
828              // tell the engine channel which instrument to load              // tell the engine channel which instrument to load
# Line 487  String LSCPServer::LoadInstrument(String Line 831  String LSCPServer::LoadInstrument(String
831              pEngineChannel->LoadInstrument();              pEngineChannel->LoadInstrument();
832          }          }
833      }      }
834      catch (LinuxSamplerException e) {      catch (Exception e) {
835           result.Error(e);           result.Error(e);
836      }      }
837      return result.Produce();      return result.Produce();
# Line 502  String LSCPServer::SetEngineType(String Line 846  String LSCPServer::SetEngineType(String
846      LSCPResultSet result;      LSCPResultSet result;
847      try {      try {
848          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
849          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
850          LockRTNotify();          LockRTNotify();
851          pSamplerChannel->SetEngineType(EngineName);          pSamplerChannel->SetEngineType(EngineName);
852          if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);          if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
853          UnlockRTNotify();          UnlockRTNotify();
854      }      }
855      catch (LinuxSamplerException e) {      catch (Exception e) {
856           result.Error(e);           result.Error(e);
857      }      }
858      return result.Produce();      return result.Produce();
# Line 546  String LSCPServer::ListChannels() { Line 890  String LSCPServer::ListChannels() {
890   */   */
891  String LSCPServer::AddChannel() {  String LSCPServer::AddChannel() {
892      dmsg(2,("LSCPServer: AddChannel()\n"));      dmsg(2,("LSCPServer: AddChannel()\n"));
893        LockRTNotify();
894      SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();      SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
895        UnlockRTNotify();
896      LSCPResultSet result(pSamplerChannel->Index());      LSCPResultSet result(pSamplerChannel->Index());
897      return result.Produce();      return result.Produce();
898  }  }
# Line 568  String LSCPServer::RemoveChannel(uint ui Line 914  String LSCPServer::RemoveChannel(uint ui
914   */   */
915  String LSCPServer::GetAvailableEngines() {  String LSCPServer::GetAvailableEngines() {
916      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
917      LSCPResultSet result("1");      LSCPResultSet result;
918        try {
919            int n = EngineFactory::AvailableEngineTypes().size();
920            result.Add(n);
921        }
922        catch (Exception e) {
923            result.Error(e);
924        }
925      return result.Produce();      return result.Produce();
926  }  }
927    
# Line 577  String LSCPServer::GetAvailableEngines() Line 930  String LSCPServer::GetAvailableEngines()
930   */   */
931  String LSCPServer::ListAvailableEngines() {  String LSCPServer::ListAvailableEngines() {
932      dmsg(2,("LSCPServer: ListAvailableEngines()\n"));      dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
933      LSCPResultSet result("\'GIG\'");      LSCPResultSet result;
934        try {
935            String s = EngineFactory::AvailableEngineTypesAsString();
936            result.Add(s);
937        }
938        catch (Exception e) {
939            result.Error(e);
940        }
941      return result.Produce();      return result.Produce();
942  }  }
943    
# Line 588  String LSCPServer::ListAvailableEngines( Line 948  String LSCPServer::ListAvailableEngines(
948  String LSCPServer::GetEngineInfo(String EngineName) {  String LSCPServer::GetEngineInfo(String EngineName) {
949      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
950      LSCPResultSet result;      LSCPResultSet result;
951        LockRTNotify();
952      try {      try {
953          Engine* pEngine = EngineFactory::Create(EngineName);          Engine* pEngine = EngineFactory::Create(EngineName);
954          result.Add("DESCRIPTION", pEngine->Description());          result.Add("DESCRIPTION", _escapeLscpResponse(pEngine->Description()));
955          result.Add("VERSION",     pEngine->Version());          result.Add("VERSION",     pEngine->Version());
956          EngineFactory::Destroy(pEngine);          EngineFactory::Destroy(pEngine);
957      }      }
958      catch (LinuxSamplerException e) {      catch (Exception e) {
959           result.Error(e);           result.Error(e);
960      }      }
961        UnlockRTNotify();
962      return result.Produce();      return result.Produce();
963  }  }
964    
# Line 609  String LSCPServer::GetChannelInfo(uint u Line 971  String LSCPServer::GetChannelInfo(uint u
971      LSCPResultSet result;      LSCPResultSet result;
972      try {      try {
973          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
974          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
975          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
976    
977          //Defaults values          //Defaults values
# Line 623  String LSCPServer::GetChannelInfo(uint u Line 985  String LSCPServer::GetChannelInfo(uint u
985          String AudioRouting;          String AudioRouting;
986          int Mute = 0;          int Mute = 0;
987          bool Solo = false;          bool Solo = false;
988            String MidiInstrumentMap = "NONE";
989    
990          if (pEngineChannel) {          if (pEngineChannel) {
991              EngineName          = pEngineChannel->EngineName();              EngineName          = pEngineChannel->EngineName();
# Line 640  String LSCPServer::GetChannelInfo(uint u Line 1003  String LSCPServer::GetChannelInfo(uint u
1003              }              }
1004              Mute = pEngineChannel->GetMute();              Mute = pEngineChannel->GetMute();
1005              Solo = pEngineChannel->GetSolo();              Solo = pEngineChannel->GetSolo();
1006                if (pEngineChannel->UsesNoMidiInstrumentMap())
1007                    MidiInstrumentMap = "NONE";
1008                else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
1009                    MidiInstrumentMap = "DEFAULT";
1010                else
1011                    MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
1012          }          }
1013    
1014          result.Add("ENGINE_NAME", EngineName);          result.Add("ENGINE_NAME", EngineName);
# Line 655  String LSCPServer::GetChannelInfo(uint u Line 1024  String LSCPServer::GetChannelInfo(uint u
1024          if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");          if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
1025          else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());          else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
1026    
1027            // convert the filename into the correct encoding as defined for LSCP
1028            // (especially in terms of special characters -> escape sequences)
1029            if (InstrumentFileName != "NONE" && InstrumentFileName != "") {
1030    #if WIN32
1031                InstrumentFileName = Path::fromWindows(InstrumentFileName).toLscp();
1032    #else
1033                // assuming POSIX
1034                InstrumentFileName = Path::fromPosix(InstrumentFileName).toLscp();
1035    #endif
1036            }
1037    
1038          result.Add("INSTRUMENT_FILE", InstrumentFileName);          result.Add("INSTRUMENT_FILE", InstrumentFileName);
1039          result.Add("INSTRUMENT_NR", InstrumentIndex);          result.Add("INSTRUMENT_NR", InstrumentIndex);
1040          result.Add("INSTRUMENT_NAME", InstrumentName);          result.Add("INSTRUMENT_NAME", _escapeLscpResponse(InstrumentName));
1041          result.Add("INSTRUMENT_STATUS", InstrumentStatus);          result.Add("INSTRUMENT_STATUS", InstrumentStatus);
1042          result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));          result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
1043          result.Add("SOLO", Solo);          result.Add("SOLO", Solo);
1044            result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
1045      }      }
1046      catch (LinuxSamplerException e) {      catch (Exception e) {
1047           result.Error(e);           result.Error(e);
1048      }      }
1049      return result.Produce();      return result.Produce();
# Line 677  String LSCPServer::GetVoiceCount(uint ui Line 1058  String LSCPServer::GetVoiceCount(uint ui
1058      LSCPResultSet result;      LSCPResultSet result;
1059      try {      try {
1060          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1061          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1062          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1063          if (!pEngineChannel) throw LinuxSamplerException("No engine loaded on sampler channel");          if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");
1064          if (!pEngineChannel->GetEngine()) throw LinuxSamplerException("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1065          result.Add(pEngineChannel->GetEngine()->VoiceCount());          result.Add(pEngineChannel->GetEngine()->VoiceCount());
1066      }      }
1067      catch (LinuxSamplerException e) {      catch (Exception e) {
1068           result.Error(e);           result.Error(e);
1069      }      }
1070      return result.Produce();      return result.Produce();
# Line 698  String LSCPServer::GetStreamCount(uint u Line 1079  String LSCPServer::GetStreamCount(uint u
1079      LSCPResultSet result;      LSCPResultSet result;
1080      try {      try {
1081          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1082          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1083          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1084          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1085          if (!pEngineChannel->GetEngine()) throw LinuxSamplerException("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1086          result.Add(pEngineChannel->GetEngine()->DiskStreamCount());          result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
1087      }      }
1088      catch (LinuxSamplerException e) {      catch (Exception e) {
1089           result.Error(e);           result.Error(e);
1090      }      }
1091      return result.Produce();      return result.Produce();
# Line 719  String LSCPServer::GetBufferFill(fill_re Line 1100  String LSCPServer::GetBufferFill(fill_re
1100      LSCPResultSet result;      LSCPResultSet result;
1101      try {      try {
1102          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1103          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1104          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1105          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1106          if (!pEngineChannel->GetEngine()) throw LinuxSamplerException("No audio output device connected to sampler channel");          if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1107          if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");          if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
1108          else {          else {
1109              switch (ResponseType) {              switch (ResponseType) {
# Line 733  String LSCPServer::GetBufferFill(fill_re Line 1114  String LSCPServer::GetBufferFill(fill_re
1114                      result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());                      result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
1115                      break;                      break;
1116                  default:                  default:
1117                      throw LinuxSamplerException("Unknown fill response type");                      throw Exception("Unknown fill response type");
1118              }              }
1119          }          }
1120      }      }
1121      catch (LinuxSamplerException e) {      catch (Exception e) {
1122           result.Error(e);           result.Error(e);
1123      }      }
1124      return result.Produce();      return result.Produce();
# Line 750  String LSCPServer::GetAvailableAudioOutp Line 1131  String LSCPServer::GetAvailableAudioOutp
1131          int n = AudioOutputDeviceFactory::AvailableDrivers().size();          int n = AudioOutputDeviceFactory::AvailableDrivers().size();
1132          result.Add(n);          result.Add(n);
1133      }      }
1134      catch (LinuxSamplerException e) {      catch (Exception e) {
1135          result.Error(e);          result.Error(e);
1136      }      }
1137      return result.Produce();      return result.Produce();
# Line 763  String LSCPServer::ListAvailableAudioOut Line 1144  String LSCPServer::ListAvailableAudioOut
1144          String s = AudioOutputDeviceFactory::AvailableDriversAsString();          String s = AudioOutputDeviceFactory::AvailableDriversAsString();
1145          result.Add(s);          result.Add(s);
1146      }      }
1147      catch (LinuxSamplerException e) {      catch (Exception e) {
1148          result.Error(e);          result.Error(e);
1149      }      }
1150      return result.Produce();      return result.Produce();
# Line 776  String LSCPServer::GetAvailableMidiInput Line 1157  String LSCPServer::GetAvailableMidiInput
1157          int n = MidiInputDeviceFactory::AvailableDrivers().size();          int n = MidiInputDeviceFactory::AvailableDrivers().size();
1158          result.Add(n);          result.Add(n);
1159      }      }
1160      catch (LinuxSamplerException e) {      catch (Exception e) {
1161          result.Error(e);          result.Error(e);
1162      }      }
1163      return result.Produce();      return result.Produce();
# Line 789  String LSCPServer::ListAvailableMidiInpu Line 1170  String LSCPServer::ListAvailableMidiInpu
1170          String s = MidiInputDeviceFactory::AvailableDriversAsString();          String s = MidiInputDeviceFactory::AvailableDriversAsString();
1171          result.Add(s);          result.Add(s);
1172      }      }
1173      catch (LinuxSamplerException e) {      catch (Exception e) {
1174          result.Error(e);          result.Error(e);
1175      }      }
1176      return result.Produce();      return result.Produce();
# Line 813  String LSCPServer::GetMidiInputDriverInf Line 1194  String LSCPServer::GetMidiInputDriverInf
1194              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
1195          }          }
1196      }      }
1197      catch (LinuxSamplerException e) {      catch (Exception e) {
1198          result.Error(e);          result.Error(e);
1199      }      }
1200      return result.Produce();      return result.Produce();
# Line 837  String LSCPServer::GetAudioOutputDriverI Line 1218  String LSCPServer::GetAudioOutputDriverI
1218              result.Add("PARAMETERS", s);              result.Add("PARAMETERS", s);
1219          }          }
1220      }      }
1221      catch (LinuxSamplerException e) {      catch (Exception e) {
1222          result.Error(e);          result.Error(e);
1223      }      }
1224      return result.Produce();      return result.Produce();
# Line 864  String LSCPServer::GetMidiInputDriverPar Line 1245  String LSCPServer::GetMidiInputDriverPar
1245          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
1246          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1247      }      }
1248      catch (LinuxSamplerException e) {      catch (Exception e) {
1249          result.Error(e);          result.Error(e);
1250      }      }
1251      return result.Produce();      return result.Produce();
# Line 891  String LSCPServer::GetAudioOutputDriverP Line 1272  String LSCPServer::GetAudioOutputDriverP
1272          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);          if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
1273          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);          if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1274      }      }
1275      catch (LinuxSamplerException e) {      catch (Exception e) {
1276          result.Error(e);          result.Error(e);
1277      }      }
1278      return result.Produce();      return result.Produce();
# Line 904  String LSCPServer::GetAudioOutputDeviceC Line 1285  String LSCPServer::GetAudioOutputDeviceC
1285          uint count = pSampler->AudioOutputDevices();          uint count = pSampler->AudioOutputDevices();
1286          result.Add(count); // success          result.Add(count); // success
1287      }      }
1288      catch (LinuxSamplerException e) {      catch (Exception e) {
1289          result.Error(e);          result.Error(e);
1290      }      }
1291      return result.Produce();      return result.Produce();
# Line 917  String LSCPServer::GetMidiInputDeviceCou Line 1298  String LSCPServer::GetMidiInputDeviceCou
1298          uint count = pSampler->MidiInputDevices();          uint count = pSampler->MidiInputDevices();
1299          result.Add(count); // success          result.Add(count); // success
1300      }      }
1301      catch (LinuxSamplerException e) {      catch (Exception e) {
1302          result.Error(e);          result.Error(e);
1303      }      }
1304      return result.Produce();      return result.Produce();
# Line 936  String LSCPServer::GetAudioOutputDevices Line 1317  String LSCPServer::GetAudioOutputDevices
1317          }          }
1318          result.Add(s);          result.Add(s);
1319      }      }
1320      catch (LinuxSamplerException e) {      catch (Exception e) {
1321          result.Error(e);          result.Error(e);
1322      }      }
1323      return result.Produce();      return result.Produce();
# Line 955  String LSCPServer::GetMidiInputDevices() Line 1336  String LSCPServer::GetMidiInputDevices()
1336          }          }
1337          result.Add(s);          result.Add(s);
1338      }      }
1339      catch (LinuxSamplerException e) {      catch (Exception e) {
1340          result.Error(e);          result.Error(e);
1341      }      }
1342      return result.Produce();      return result.Produce();
# Line 966  String LSCPServer::GetAudioOutputDeviceI Line 1347  String LSCPServer::GetAudioOutputDeviceI
1347      LSCPResultSet result;      LSCPResultSet result;
1348      try {      try {
1349          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1350          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) + ".");
1351          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
1352          result.Add("DRIVER", pDevice->Driver());          result.Add("DRIVER", pDevice->Driver());
1353          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
# Line 975  String LSCPServer::GetAudioOutputDeviceI Line 1356  String LSCPServer::GetAudioOutputDeviceI
1356              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1357          }          }
1358      }      }
1359      catch (LinuxSamplerException e) {      catch (Exception e) {
1360          result.Error(e);          result.Error(e);
1361      }      }
1362      return result.Produce();      return result.Produce();
# Line 986  String LSCPServer::GetMidiInputDeviceInf Line 1367  String LSCPServer::GetMidiInputDeviceInf
1367      LSCPResultSet result;      LSCPResultSet result;
1368      try {      try {
1369          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1370          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) + ".");
1371          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1372          result.Add("DRIVER", pDevice->Driver());          result.Add("DRIVER", pDevice->Driver());
1373          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
# Line 995  String LSCPServer::GetMidiInputDeviceInf Line 1376  String LSCPServer::GetMidiInputDeviceInf
1376              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1377          }          }
1378      }      }
1379      catch (LinuxSamplerException e) {      catch (Exception e) {
1380          result.Error(e);          result.Error(e);
1381      }      }
1382      return result.Produce();      return result.Produce();
# Line 1006  String LSCPServer::GetMidiInputPortInfo( Line 1387  String LSCPServer::GetMidiInputPortInfo(
1387      try {      try {
1388          // get MIDI input device          // get MIDI input device
1389          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1390          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) + ".");
1391          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1392    
1393          // get MIDI port          // get MIDI port
1394          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1395          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) + ".");
1396    
1397          // return the values of all MIDI port parameters          // return the values of all MIDI port parameters
1398          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
# Line 1020  String LSCPServer::GetMidiInputPortInfo( Line 1401  String LSCPServer::GetMidiInputPortInfo(
1401              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1402          }          }
1403      }      }
1404      catch (LinuxSamplerException e) {      catch (Exception e) {
1405          result.Error(e);          result.Error(e);
1406      }      }
1407      return result.Produce();      return result.Produce();
# Line 1032  String LSCPServer::GetAudioOutputChannel Line 1413  String LSCPServer::GetAudioOutputChannel
1413      try {      try {
1414          // get audio output device          // get audio output device
1415          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1416          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) + ".");
1417          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1418    
1419          // get audio channel          // get audio channel
1420          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1421          if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1422    
1423          // return the values of all audio channel parameters          // return the values of all audio channel parameters
1424          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
# Line 1046  String LSCPServer::GetAudioOutputChannel Line 1427  String LSCPServer::GetAudioOutputChannel
1427              result.Add(iter->first, iter->second->Value());              result.Add(iter->first, iter->second->Value());
1428          }          }
1429      }      }
1430      catch (LinuxSamplerException e) {      catch (Exception e) {
1431          result.Error(e);          result.Error(e);
1432      }      }
1433      return result.Produce();      return result.Produce();
# Line 1058  String LSCPServer::GetMidiInputPortParam Line 1439  String LSCPServer::GetMidiInputPortParam
1439      try {      try {
1440          // get MIDI input device          // get MIDI input device
1441          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1442          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) + ".");
1443          MidiInputDevice* pDevice = devices[DeviceId];          MidiInputDevice* pDevice = devices[DeviceId];
1444    
1445          // get midi port          // get midi port
1446          MidiInputPort* pPort = pDevice->GetPort(PortId);          MidiInputPort* pPort = pDevice->GetPort(PortId);
1447          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) + ".");
1448    
1449          // get desired port parameter          // get desired port parameter
1450          std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1451          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 + "'.");
1452          DeviceRuntimeParameter* pParameter = parameters[ParameterName];          DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1453    
1454          // return all fields of this audio channel parameter          // return all fields of this audio channel parameter
# Line 1079  String LSCPServer::GetMidiInputPortParam Line 1460  String LSCPServer::GetMidiInputPortParam
1460          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1461          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1462      }      }
1463      catch (LinuxSamplerException e) {      catch (Exception e) {
1464          result.Error(e);          result.Error(e);
1465      }      }
1466      return result.Produce();      return result.Produce();
# Line 1091  String LSCPServer::GetAudioOutputChannel Line 1472  String LSCPServer::GetAudioOutputChannel
1472      try {      try {
1473          // get audio output device          // get audio output device
1474          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1475          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) + ".");
1476          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1477    
1478          // get audio channel          // get audio channel
1479          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1480          if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1481    
1482          // get desired audio channel parameter          // get desired audio channel parameter
1483          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1484          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 + "'.");
1485          DeviceRuntimeParameter* pParameter = parameters[ParameterName];          DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1486    
1487          // return all fields of this audio channel parameter          // return all fields of this audio channel parameter
# Line 1112  String LSCPServer::GetAudioOutputChannel Line 1493  String LSCPServer::GetAudioOutputChannel
1493          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());          if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1494          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());          if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1495      }      }
1496      catch (LinuxSamplerException e) {      catch (Exception e) {
1497          result.Error(e);          result.Error(e);
1498      }      }
1499      return result.Produce();      return result.Produce();
# Line 1124  String LSCPServer::SetAudioOutputChannel Line 1505  String LSCPServer::SetAudioOutputChannel
1505      try {      try {
1506          // get audio output device          // get audio output device
1507          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1508          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) + ".");
1509          AudioOutputDevice* pDevice = devices[DeviceId];          AudioOutputDevice* pDevice = devices[DeviceId];
1510    
1511          // get audio channel          // get audio channel
1512          AudioChannel* pChannel = pDevice->Channel(ChannelId);          AudioChannel* pChannel = pDevice->Channel(ChannelId);
1513          if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");          if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1514    
1515          // get desired audio channel parameter          // get desired audio channel parameter
1516          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1517          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 + "'.");
1518          DeviceRuntimeParameter* pParameter = parameters[ParamKey];          DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1519    
1520          // set new channel parameter value          // set new channel parameter value
1521          pParameter->SetValue(ParamVal);          pParameter->SetValue(ParamVal);
1522            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1523      }      }
1524      catch (LinuxSamplerException e) {      catch (Exception e) {
1525          result.Error(e);          result.Error(e);
1526      }      }
1527      return result.Produce();      return result.Produce();
# Line 1150  String LSCPServer::SetAudioOutputDeviceP Line 1532  String LSCPServer::SetAudioOutputDeviceP
1532      LSCPResultSet result;      LSCPResultSet result;
1533      try {      try {
1534          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1535          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) + ".");
1536          AudioOutputDevice* pDevice = devices[DeviceIndex];          AudioOutputDevice* pDevice = devices[DeviceIndex];
1537          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1538          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 + "'");
1539          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1540            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1541      }      }
1542      catch (LinuxSamplerException e) {      catch (Exception e) {
1543          result.Error(e);          result.Error(e);
1544      }      }
1545      return result.Produce();      return result.Produce();
# Line 1167  String LSCPServer::SetMidiInputDevicePar Line 1550  String LSCPServer::SetMidiInputDevicePar
1550      LSCPResultSet result;      LSCPResultSet result;
1551      try {      try {
1552          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1553          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) + ".");
1554          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1555          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();          std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1556          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 + "'");
1557          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1558            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1559      }      }
1560      catch (LinuxSamplerException e) {      catch (Exception e) {
1561          result.Error(e);          result.Error(e);
1562      }      }
1563      return result.Produce();      return result.Produce();
# Line 1185  String LSCPServer::SetMidiInputPortParam Line 1569  String LSCPServer::SetMidiInputPortParam
1569      try {      try {
1570          // get MIDI input device          // get MIDI input device
1571          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1572          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) + ".");
1573          MidiInputDevice* pDevice = devices[DeviceIndex];          MidiInputDevice* pDevice = devices[DeviceIndex];
1574    
1575          // get MIDI port          // get MIDI port
1576          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);          MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1577          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) + ".");
1578    
1579          // set port parameter value          // set port parameter value
1580          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();          std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1581          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 + "'");
1582          parameters[ParamKey]->SetValue(ParamVal);          parameters[ParamKey]->SetValue(ParamVal);
1583            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1584      }      }
1585      catch (LinuxSamplerException e) {      catch (Exception e) {
1586          result.Error(e);          result.Error(e);
1587      }      }
1588      return result.Produce();      return result.Produce();
# Line 1212  String LSCPServer::SetAudioOutputChannel Line 1597  String LSCPServer::SetAudioOutputChannel
1597      LSCPResultSet result;      LSCPResultSet result;
1598      try {      try {
1599          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1600          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1601          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1602          if (!pEngineChannel) throw LinuxSamplerException("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));          if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1603          if (!pSamplerChannel->GetAudioOutputDevice()) throw LinuxSamplerException("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));          if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1604          pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);          pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1605      }      }
1606      catch (LinuxSamplerException e) {      catch (Exception e) {
1607           result.Error(e);           result.Error(e);
1608      }      }
1609      return result.Produce();      return result.Produce();
# Line 1227  String LSCPServer::SetAudioOutputChannel Line 1612  String LSCPServer::SetAudioOutputChannel
1612  String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {  String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1613      dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));      dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1614      LSCPResultSet result;      LSCPResultSet result;
1615        LockRTNotify();
1616      try {      try {
1617          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1618          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1619          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();          std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1620          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));
1621          AudioOutputDevice* pDevice = devices[AudioDeviceId];          AudioOutputDevice* pDevice = devices[AudioDeviceId];
1622          pSamplerChannel->SetAudioOutputDevice(pDevice);          pSamplerChannel->SetAudioOutputDevice(pDevice);
1623      }      }
1624      catch (LinuxSamplerException e) {      catch (Exception e) {
1625           result.Error(e);           result.Error(e);
1626      }      }
1627        UnlockRTNotify();
1628      return result.Produce();      return result.Produce();
1629  }  }
1630    
1631  String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {  String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1632      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));
1633      LSCPResultSet result;      LSCPResultSet result;
1634        LockRTNotify();
1635      try {      try {
1636          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1637          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1638          // Driver type name aliasing...          // Driver type name aliasing...
1639          if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";          if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1640          if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";          if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
# Line 1268  String LSCPServer::SetAudioOutputType(St Line 1656  String LSCPServer::SetAudioOutputType(St
1656          }          }
1657          // Must have a device...          // Must have a device...
1658          if (pDevice == NULL)          if (pDevice == NULL)
1659              throw LinuxSamplerException("Internal error: could not create audio output device.");              throw Exception("Internal error: could not create audio output device.");
1660          // Set it as the current channel device...          // Set it as the current channel device...
1661          pSamplerChannel->SetAudioOutputDevice(pDevice);          pSamplerChannel->SetAudioOutputDevice(pDevice);
1662      }      }
1663      catch (LinuxSamplerException e) {      catch (Exception e) {
1664           result.Error(e);           result.Error(e);
1665      }      }
1666        UnlockRTNotify();
1667      return result.Produce();      return result.Produce();
1668  }  }
1669    
# Line 1283  String LSCPServer::SetMIDIInputPort(uint Line 1672  String LSCPServer::SetMIDIInputPort(uint
1672      LSCPResultSet result;      LSCPResultSet result;
1673      try {      try {
1674          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1675          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1676          pSamplerChannel->SetMidiInputPort(MIDIPort);          pSamplerChannel->SetMidiInputPort(MIDIPort);
1677      }      }
1678      catch (LinuxSamplerException e) {      catch (Exception e) {
1679           result.Error(e);           result.Error(e);
1680      }      }
1681      return result.Produce();      return result.Produce();
# Line 1297  String LSCPServer::SetMIDIInputChannel(u Line 1686  String LSCPServer::SetMIDIInputChannel(u
1686      LSCPResultSet result;      LSCPResultSet result;
1687      try {      try {
1688          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1689          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1690          pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);          pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1691      }      }
1692      catch (LinuxSamplerException e) {      catch (Exception e) {
1693           result.Error(e);           result.Error(e);
1694      }      }
1695      return result.Produce();      return result.Produce();
# Line 1311  String LSCPServer::SetMIDIInputDevice(ui Line 1700  String LSCPServer::SetMIDIInputDevice(ui
1700      LSCPResultSet result;      LSCPResultSet result;
1701      try {      try {
1702          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1703          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1704          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1705          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));
1706          MidiInputDevice* pDevice = devices[MIDIDeviceId];          MidiInputDevice* pDevice = devices[MIDIDeviceId];
1707          pSamplerChannel->SetMidiInputDevice(pDevice);          pSamplerChannel->SetMidiInputDevice(pDevice);
1708      }      }
1709      catch (LinuxSamplerException e) {      catch (Exception e) {
1710           result.Error(e);           result.Error(e);
1711      }      }
1712      return result.Produce();      return result.Produce();
# Line 1328  String LSCPServer::SetMIDIInputType(Stri Line 1717  String LSCPServer::SetMIDIInputType(Stri
1717      LSCPResultSet result;      LSCPResultSet result;
1718      try {      try {
1719          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1720          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1721          // Driver type name aliasing...          // Driver type name aliasing...
1722          if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";          if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1723          // Check if there's one MIDI input device already created          // Check if there's one MIDI input device already created
# Line 1352  String LSCPServer::SetMIDIInputType(Stri Line 1741  String LSCPServer::SetMIDIInputType(Stri
1741          }          }
1742          // Must have a device...          // Must have a device...
1743          if (pDevice == NULL)          if (pDevice == NULL)
1744              throw LinuxSamplerException("Internal error: could not create MIDI input device.");              throw Exception("Internal error: could not create MIDI input device.");
1745          // Set it as the current channel device...          // Set it as the current channel device...
1746          pSamplerChannel->SetMidiInputDevice(pDevice);          pSamplerChannel->SetMidiInputDevice(pDevice);
1747      }      }
1748      catch (LinuxSamplerException e) {      catch (Exception e) {
1749           result.Error(e);           result.Error(e);
1750      }      }
1751      return result.Produce();      return result.Produce();
# Line 1371  String LSCPServer::SetMIDIInput(uint MID Line 1760  String LSCPServer::SetMIDIInput(uint MID
1760      LSCPResultSet result;      LSCPResultSet result;
1761      try {      try {
1762          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1763          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1764          std::map<uint, MidiInputDevice*> devices =  pSampler->GetMidiInputDevices();          std::map<uint, MidiInputDevice*> devices =  pSampler->GetMidiInputDevices();
1765          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));
1766          MidiInputDevice* pDevice = devices[MIDIDeviceId];          MidiInputDevice* pDevice = devices[MIDIDeviceId];
1767          pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);          pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
1768      }      }
1769      catch (LinuxSamplerException e) {      catch (Exception e) {
1770           result.Error(e);           result.Error(e);
1771      }      }
1772      return result.Produce();      return result.Produce();
# Line 1392  String LSCPServer::SetVolume(double dVol Line 1781  String LSCPServer::SetVolume(double dVol
1781      LSCPResultSet result;      LSCPResultSet result;
1782      try {      try {
1783          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1784          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1785          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1786          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1787          pEngineChannel->Volume(dVolume);          pEngineChannel->Volume(dVolume);
1788      }      }
1789      catch (LinuxSamplerException e) {      catch (Exception e) {
1790           result.Error(e);           result.Error(e);
1791      }      }
1792      return result.Produce();      return result.Produce();
# Line 1411  String LSCPServer::SetChannelMute(bool b Line 1800  String LSCPServer::SetChannelMute(bool b
1800      LSCPResultSet result;      LSCPResultSet result;
1801      try {      try {
1802          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1803          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1804    
1805          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1806          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1807    
1808          if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);          if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1809          else pEngineChannel->SetMute(1);          else pEngineChannel->SetMute(1);
1810      } catch (LinuxSamplerException e) {      } catch (Exception e) {
1811          result.Error(e);          result.Error(e);
1812      }      }
1813      return result.Produce();      return result.Produce();
# Line 1432  String LSCPServer::SetChannelSolo(bool b Line 1821  String LSCPServer::SetChannelSolo(bool b
1821      LSCPResultSet result;      LSCPResultSet result;
1822      try {      try {
1823          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1824          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1825    
1826          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1827          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1828    
1829          bool oldSolo = pEngineChannel->GetSolo();          bool oldSolo = pEngineChannel->GetSolo();
1830          bool hadSoloChannel = HasSoloChannel();          bool hadSoloChannel = HasSoloChannel();
1831            
1832          pEngineChannel->SetSolo(bSolo);          pEngineChannel->SetSolo(bSolo);
1833            
1834          if(!oldSolo && bSolo) {          if(!oldSolo && bSolo) {
1835              if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);              if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
1836              if(!hadSoloChannel) MuteNonSoloChannels();              if(!hadSoloChannel) MuteNonSoloChannels();
1837          }          }
1838            
1839          if(oldSolo && !bSolo) {          if(oldSolo && !bSolo) {
1840              if(!HasSoloChannel()) UnmuteChannels();              if(!HasSoloChannel()) UnmuteChannels();
1841              else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);              else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
1842          }          }
1843      } catch (LinuxSamplerException e) {      } catch (Exception e) {
1844          result.Error(e);          result.Error(e);
1845      }      }
1846      return result.Produce();      return result.Produce();
# Line 1504  void  LSCPServer::UnmuteChannels() { Line 1893  void  LSCPServer::UnmuteChannels() {
1893      }      }
1894  }  }
1895    
1896    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) {
1897        dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
1898    
1899        midi_prog_index_t idx;
1900        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1901        idx.midi_bank_lsb = MidiBank & 0x7f;
1902        idx.midi_prog     = MidiProg;
1903    
1904        MidiInstrumentMapper::entry_t entry;
1905        entry.EngineName      = EngineType;
1906        entry.InstrumentFile  = InstrumentFile;
1907        entry.InstrumentIndex = InstrumentIndex;
1908        entry.LoadMode        = LoadMode;
1909        entry.Volume          = Volume;
1910        entry.Name            = Name;
1911    
1912        LSCPResultSet result;
1913        try {
1914            // PERSISTENT mapping commands might block for a long time, so in
1915            // that case we add/replace the mapping in another thread in case
1916            // the NON_MODAL argument was supplied, non persistent mappings
1917            // should return immediately, so we don't need to do that for them
1918            bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
1919            MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1920        } catch (Exception e) {
1921            result.Error(e);
1922        }
1923        return result.Produce();
1924    }
1925    
1926    String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1927        dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1928    
1929        midi_prog_index_t idx;
1930        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1931        idx.midi_bank_lsb = MidiBank & 0x7f;
1932        idx.midi_prog     = MidiProg;
1933    
1934        LSCPResultSet result;
1935        try {
1936            MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1937        } catch (Exception e) {
1938            result.Error(e);
1939        }
1940        return result.Produce();
1941    }
1942    
1943    String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1944        dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1945        LSCPResultSet result;
1946        try {
1947            result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1948        } catch (Exception e) {
1949            result.Error(e);
1950        }
1951        return result.Produce();
1952    }
1953    
1954    
1955    String LSCPServer::GetAllMidiInstrumentMappings() {
1956        dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1957        LSCPResultSet result;
1958        std::vector<int> maps = MidiInstrumentMapper::Maps();
1959        int totalMappings = 0;
1960        for (int i = 0; i < maps.size(); i++) {
1961            try {
1962                totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1963            } catch (Exception e) { /*NOOP*/ }
1964        }
1965        result.Add(totalMappings);
1966        return result.Produce();
1967    }
1968    
1969    String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1970        dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1971        LSCPResultSet result;
1972        try {
1973            midi_prog_index_t idx;
1974            idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1975            idx.midi_bank_lsb = MidiBank & 0x7f;
1976            idx.midi_prog     = MidiProg;
1977    
1978            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1979            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1980            if (iter == mappings.end()) result.Error("there is no map entry with that index");
1981            else { // found
1982    
1983                // convert the filename into the correct encoding as defined for LSCP
1984                // (especially in terms of special characters -> escape sequences)
1985    #if WIN32
1986                const String instrumentFileName = Path::fromWindows(iter->second.InstrumentFile).toLscp();
1987    #else
1988                // assuming POSIX
1989                const String instrumentFileName = Path::fromPosix(iter->second.InstrumentFile).toLscp();
1990    #endif
1991    
1992                result.Add("NAME", _escapeLscpResponse(iter->second.Name));
1993                result.Add("ENGINE_NAME", iter->second.EngineName);
1994                result.Add("INSTRUMENT_FILE", instrumentFileName);
1995                result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1996                String instrumentName;
1997                Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1998                if (pEngine) {
1999                    if (pEngine->GetInstrumentManager()) {
2000                        InstrumentManager::instrument_id_t instrID;
2001                        instrID.FileName = iter->second.InstrumentFile;
2002                        instrID.Index    = iter->second.InstrumentIndex;
2003                        instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
2004                    }
2005                    EngineFactory::Destroy(pEngine);
2006                }
2007                result.Add("INSTRUMENT_NAME", _escapeLscpResponse(instrumentName));
2008                switch (iter->second.LoadMode) {
2009                    case MidiInstrumentMapper::ON_DEMAND:
2010                        result.Add("LOAD_MODE", "ON_DEMAND");
2011                        break;
2012                    case MidiInstrumentMapper::ON_DEMAND_HOLD:
2013                        result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
2014                        break;
2015                    case MidiInstrumentMapper::PERSISTENT:
2016                        result.Add("LOAD_MODE", "PERSISTENT");
2017                        break;
2018                    default:
2019                        throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
2020                }
2021                result.Add("VOLUME", iter->second.Volume);
2022            }
2023        } catch (Exception e) {
2024            result.Error(e);
2025        }
2026        return result.Produce();
2027    }
2028    
2029    String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
2030        dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
2031        LSCPResultSet result;
2032        try {
2033            String s;
2034            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
2035            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
2036            for (; iter != mappings.end(); iter++) {
2037                if (s.size()) s += ",";
2038                s += "{" + ToString(MidiMapID) + ","
2039                         + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
2040                         + ToString(int(iter->first.midi_prog)) + "}";
2041            }
2042            result.Add(s);
2043        } catch (Exception e) {
2044            result.Error(e);
2045        }
2046        return result.Produce();
2047    }
2048    
2049    String LSCPServer::ListAllMidiInstrumentMappings() {
2050        dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
2051        LSCPResultSet result;
2052        try {
2053            std::vector<int> maps = MidiInstrumentMapper::Maps();
2054            String s;
2055            for (int i = 0; i < maps.size(); i++) {
2056                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
2057                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
2058                for (; iter != mappings.end(); iter++) {
2059                    if (s.size()) s += ",";
2060                    s += "{" + ToString(maps[i]) + ","
2061                             + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
2062                             + ToString(int(iter->first.midi_prog)) + "}";
2063                }
2064            }
2065            result.Add(s);
2066        } catch (Exception e) {
2067            result.Error(e);
2068        }
2069        return result.Produce();
2070    }
2071    
2072    String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
2073        dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
2074        LSCPResultSet result;
2075        try {
2076            MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
2077        } catch (Exception e) {
2078            result.Error(e);
2079        }
2080        return result.Produce();
2081    }
2082    
2083    String LSCPServer::ClearAllMidiInstrumentMappings() {
2084        dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
2085        LSCPResultSet result;
2086        try {
2087            std::vector<int> maps = MidiInstrumentMapper::Maps();
2088            for (int i = 0; i < maps.size(); i++)
2089                MidiInstrumentMapper::RemoveAllEntries(maps[i]);
2090        } catch (Exception e) {
2091            result.Error(e);
2092        }
2093        return result.Produce();
2094    }
2095    
2096    String LSCPServer::AddMidiInstrumentMap(String MapName) {
2097        dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
2098        LSCPResultSet result;
2099        try {
2100            int MapID = MidiInstrumentMapper::AddMap(MapName);
2101            result = LSCPResultSet(MapID);
2102        } catch (Exception e) {
2103            result.Error(e);
2104        }
2105        return result.Produce();
2106    }
2107    
2108    String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
2109        dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
2110        LSCPResultSet result;
2111        try {
2112            MidiInstrumentMapper::RemoveMap(MidiMapID);
2113        } catch (Exception e) {
2114            result.Error(e);
2115        }
2116        return result.Produce();
2117    }
2118    
2119    String LSCPServer::RemoveAllMidiInstrumentMaps() {
2120        dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
2121        LSCPResultSet result;
2122        try {
2123            MidiInstrumentMapper::RemoveAllMaps();
2124        } catch (Exception e) {
2125            result.Error(e);
2126        }
2127        return result.Produce();
2128    }
2129    
2130    String LSCPServer::GetMidiInstrumentMaps() {
2131        dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
2132        LSCPResultSet result;
2133        try {
2134            result.Add(MidiInstrumentMapper::Maps().size());
2135        } catch (Exception e) {
2136            result.Error(e);
2137        }
2138        return result.Produce();
2139    }
2140    
2141    String LSCPServer::ListMidiInstrumentMaps() {
2142        dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
2143        LSCPResultSet result;
2144        try {
2145            std::vector<int> maps = MidiInstrumentMapper::Maps();
2146            String sList;
2147            for (int i = 0; i < maps.size(); i++) {
2148                if (sList != "") sList += ",";
2149                sList += ToString(maps[i]);
2150            }
2151            result.Add(sList);
2152        } catch (Exception e) {
2153            result.Error(e);
2154        }
2155        return result.Produce();
2156    }
2157    
2158    String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
2159        dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
2160        LSCPResultSet result;
2161        try {
2162            result.Add("NAME", _escapeLscpResponse(MidiInstrumentMapper::MapName(MidiMapID)));
2163            result.Add("DEFAULT", MidiInstrumentMapper::GetDefaultMap() == MidiMapID);
2164        } catch (Exception e) {
2165            result.Error(e);
2166        }
2167        return result.Produce();
2168    }
2169    
2170    String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
2171        dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
2172        LSCPResultSet result;
2173        try {
2174            MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
2175        } catch (Exception e) {
2176            result.Error(e);
2177        }
2178        return result.Produce();
2179    }
2180    
2181    /**
2182     * Set the MIDI instrument map the given sampler channel shall use for
2183     * handling MIDI program change messages. There are the following two
2184     * special (negative) values:
2185     *
2186     *    - (-1) :  set to NONE (ignore program changes)
2187     *    - (-2) :  set to DEFAULT map
2188     */
2189    String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
2190        dmsg(2,("LSCPServer: SetChannelMap()\n"));
2191        LSCPResultSet result;
2192        try {
2193            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2194            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2195    
2196            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2197            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2198    
2199            if      (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
2200            else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
2201            else                      pEngineChannel->SetMidiInstrumentMap(MidiMapID);
2202        } catch (Exception e) {
2203            result.Error(e);
2204        }
2205        return result.Produce();
2206    }
2207    
2208    String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
2209        dmsg(2,("LSCPServer: CreateFxSend()\n"));
2210        LSCPResultSet result;
2211        try {
2212            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2213    
2214            FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
2215            if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
2216    
2217            result = LSCPResultSet(pFxSend->Id()); // success
2218        } catch (Exception e) {
2219            result.Error(e);
2220        }
2221        return result.Produce();
2222    }
2223    
2224    String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
2225        dmsg(2,("LSCPServer: DestroyFxSend()\n"));
2226        LSCPResultSet result;
2227        try {
2228            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2229    
2230            FxSend* pFxSend = NULL;
2231            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2232                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2233                    pFxSend = pEngineChannel->GetFxSend(i);
2234                    break;
2235                }
2236            }
2237            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2238            pEngineChannel->RemoveFxSend(pFxSend);
2239        } catch (Exception e) {
2240            result.Error(e);
2241        }
2242        return result.Produce();
2243    }
2244    
2245    String LSCPServer::GetFxSends(uint uiSamplerChannel) {
2246        dmsg(2,("LSCPServer: GetFxSends()\n"));
2247        LSCPResultSet result;
2248        try {
2249            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2250    
2251            result.Add(pEngineChannel->GetFxSendCount());
2252        } catch (Exception e) {
2253            result.Error(e);
2254        }
2255        return result.Produce();
2256    }
2257    
2258    String LSCPServer::ListFxSends(uint uiSamplerChannel) {
2259        dmsg(2,("LSCPServer: ListFxSends()\n"));
2260        LSCPResultSet result;
2261        String list;
2262        try {
2263            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2264    
2265            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2266                FxSend* pFxSend = pEngineChannel->GetFxSend(i);
2267                if (list != "") list += ",";
2268                list += ToString(pFxSend->Id());
2269            }
2270            result.Add(list);
2271        } catch (Exception e) {
2272            result.Error(e);
2273        }
2274        return result.Produce();
2275    }
2276    
2277    FxSend* LSCPServer::GetFxSend(uint uiSamplerChannel, uint FxSendID) {
2278        EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2279    
2280        FxSend* pFxSend = NULL;
2281        for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2282            if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2283                pFxSend = pEngineChannel->GetFxSend(i);
2284                break;
2285            }
2286        }
2287        if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2288        return pFxSend;
2289    }
2290    
2291    String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
2292        dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
2293        LSCPResultSet result;
2294        try {
2295            EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2296            FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2297    
2298            // gather audio routing informations
2299            String AudioRouting;
2300            for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
2301                if (AudioRouting != "") AudioRouting += ",";
2302                AudioRouting += ToString(pFxSend->DestinationChannel(chan));
2303            }
2304    
2305            // success
2306            result.Add("NAME", _escapeLscpResponse(pFxSend->Name()));
2307            result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
2308            result.Add("LEVEL", ToString(pFxSend->Level()));
2309            result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
2310        } catch (Exception e) {
2311            result.Error(e);
2312        }
2313        return result.Produce();
2314    }
2315    
2316    String LSCPServer::SetFxSendName(uint uiSamplerChannel, uint FxSendID, String Name) {
2317        dmsg(2,("LSCPServer: SetFxSendName()\n"));
2318        LSCPResultSet result;
2319        try {
2320            FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2321    
2322            pFxSend->SetName(Name);
2323            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2324        } catch (Exception e) {
2325            result.Error(e);
2326        }
2327        return result.Produce();
2328    }
2329    
2330    String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
2331        dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
2332        LSCPResultSet result;
2333        try {
2334            FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2335    
2336            pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2337            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2338        } catch (Exception e) {
2339            result.Error(e);
2340        }
2341        return result.Produce();
2342    }
2343    
2344    String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2345        dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2346        LSCPResultSet result;
2347        try {
2348            FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2349    
2350            pFxSend->SetMidiController(MidiController);
2351            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2352        } catch (Exception e) {
2353            result.Error(e);
2354        }
2355        return result.Produce();
2356    }
2357    
2358    String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2359        dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2360        LSCPResultSet result;
2361        try {
2362            FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2363    
2364            pFxSend->SetLevel((float)dLevel);
2365            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2366        } catch (Exception e) {
2367            result.Error(e);
2368        }
2369        return result.Produce();
2370    }
2371    
2372    String LSCPServer::EditSamplerChannelInstrument(uint uiSamplerChannel) {
2373        dmsg(2,("LSCPServer: EditSamplerChannelInstrument(SamplerChannel=%d)\n", uiSamplerChannel));
2374        LSCPResultSet result;
2375        try {
2376            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2377            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2378            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2379            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2380            if (pEngineChannel->InstrumentStatus() < 0) throw Exception("No instrument loaded to sampler channel");
2381            Engine* pEngine = pEngineChannel->GetEngine();
2382            InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();
2383            if (!pInstrumentManager) throw Exception("Engine does not provide an instrument manager");
2384            InstrumentManager::instrument_id_t instrumentID;
2385            instrumentID.FileName = pEngineChannel->InstrumentFileName();
2386            instrumentID.Index    = pEngineChannel->InstrumentIndex();
2387            pInstrumentManager->LaunchInstrumentEditor(instrumentID);
2388        } catch (Exception e) {
2389            result.Error(e);
2390        }
2391        return result.Produce();
2392    }
2393    
2394  /**  /**
2395   * Will be called by the parser to reset a particular sampler channel.   * Will be called by the parser to reset a particular sampler channel.
2396   */   */
# Line 1512  String LSCPServer::ResetChannel(uint uiS Line 2399  String LSCPServer::ResetChannel(uint uiS
2399      LSCPResultSet result;      LSCPResultSet result;
2400      try {      try {
2401          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2402          if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2403          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();          EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2404          if (!pEngineChannel) throw LinuxSamplerException("No engine type assigned to sampler channel");          if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2405          pEngineChannel->Reset();          pEngineChannel->Reset();
2406      }      }
2407      catch (LinuxSamplerException e) {      catch (Exception e) {
2408           result.Error(e);           result.Error(e);
2409      }      }
2410      return result.Produce();      return result.Produce();
# Line 1539  String LSCPServer::ResetSampler() { Line 2426  String LSCPServer::ResetSampler() {
2426   */   */
2427  String LSCPServer::GetServerInfo() {  String LSCPServer::GetServerInfo() {
2428      dmsg(2,("LSCPServer: GetServerInfo()\n"));      dmsg(2,("LSCPServer: GetServerInfo()\n"));
2429        const std::string description =
2430            _escapeLscpResponse("LinuxSampler - modular, streaming capable sampler");
2431      LSCPResultSet result;      LSCPResultSet result;
2432      result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");      result.Add("DESCRIPTION", description);
2433      result.Add("VERSION", VERSION);      result.Add("VERSION", VERSION);
2434      result.Add("PROTOCOL_VERSION", "1.0");      result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2435    #if HAVE_SQLITE3
2436        result.Add("INSTRUMENTS_DB_SUPPORT", "yes");
2437    #else
2438        result.Add("INSTRUMENTS_DB_SUPPORT", "no");
2439    #endif
2440    
2441        return result.Produce();
2442    }
2443    
2444    /**
2445     * Will be called by the parser to return the current number of all active streams.
2446     */
2447    String LSCPServer::GetTotalStreamCount() {
2448        dmsg(2,("LSCPServer: GetTotalStreamCount()\n"));
2449        LSCPResultSet result;
2450        result.Add(pSampler->GetDiskStreamCount());
2451      return result.Produce();      return result.Produce();
2452  }  }
2453    
# Line 1566  String LSCPServer::GetTotalVoiceCountMax Line 2471  String LSCPServer::GetTotalVoiceCountMax
2471      return result.Produce();      return result.Produce();
2472  }  }
2473    
2474    String LSCPServer::GetGlobalVolume() {
2475        LSCPResultSet result;
2476        result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2477        return result.Produce();
2478    }
2479    
2480    String LSCPServer::SetGlobalVolume(double dVolume) {
2481        LSCPResultSet result;
2482        try {
2483            if (dVolume < 0) throw Exception("Volume may not be negative");
2484            GLOBAL_VOLUME = dVolume; // see common/global.cpp
2485            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
2486        } catch (Exception e) {
2487            result.Error(e);
2488        }
2489        return result.Produce();
2490    }
2491    
2492    String LSCPServer::GetFileInstruments(String Filename) {
2493        dmsg(2,("LSCPServer: GetFileInstruments(String Filename=%s)\n",Filename.c_str()));
2494        LSCPResultSet result;
2495        try {
2496            VerifyFile(Filename);
2497        } catch (Exception e) {
2498            result.Error(e);
2499            return result.Produce();
2500        }
2501        // try to find a sampler engine that can handle the file
2502        bool bFound = false;
2503        std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
2504        for (int i = 0; !bFound && i < engineTypes.size(); i++) {
2505            Engine* pEngine = NULL;
2506            try {
2507                pEngine = EngineFactory::Create(engineTypes[i]);
2508                if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
2509                InstrumentManager* pManager = pEngine->GetInstrumentManager();
2510                if (pManager) {
2511                    std::vector<InstrumentManager::instrument_id_t> IDs =
2512                        pManager->GetInstrumentFileContent(Filename);
2513                    // return the amount of instruments in the file
2514                    result.Add(IDs.size());
2515                    // no more need to ask other engine types
2516                    bFound = true;
2517                } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
2518            } catch (Exception e) {
2519                // NOOP, as exception is thrown if engine doesn't support file
2520            }
2521            if (pEngine) EngineFactory::Destroy(pEngine);
2522        }
2523    
2524        if (!bFound) result.Error("Unknown file format");
2525        return result.Produce();
2526    }
2527    
2528    String LSCPServer::ListFileInstruments(String Filename) {
2529        dmsg(2,("LSCPServer: ListFileInstruments(String Filename=%s)\n",Filename.c_str()));
2530        LSCPResultSet result;
2531        try {
2532            VerifyFile(Filename);
2533        } catch (Exception e) {
2534            result.Error(e);
2535            return result.Produce();
2536        }
2537        // try to find a sampler engine that can handle the file
2538        bool bFound = false;
2539        std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
2540        for (int i = 0; !bFound && i < engineTypes.size(); i++) {
2541            Engine* pEngine = NULL;
2542            try {
2543                pEngine = EngineFactory::Create(engineTypes[i]);
2544                if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
2545                InstrumentManager* pManager = pEngine->GetInstrumentManager();
2546                if (pManager) {
2547                    std::vector<InstrumentManager::instrument_id_t> IDs =
2548                        pManager->GetInstrumentFileContent(Filename);
2549                    // return a list of IDs of the instruments in the file
2550                    String s;
2551                    for (int j = 0; j < IDs.size(); j++) {
2552                        if (s.size()) s += ",";
2553                        s += ToString(IDs[j].Index);
2554                    }
2555                    result.Add(s);
2556                    // no more need to ask other engine types
2557                    bFound = true;
2558                } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
2559            } catch (Exception e) {
2560                // NOOP, as exception is thrown if engine doesn't support file
2561            }
2562            if (pEngine) EngineFactory::Destroy(pEngine);
2563        }
2564    
2565        if (!bFound) result.Error("Unknown file format");
2566        return result.Produce();
2567    }
2568    
2569    String LSCPServer::GetFileInstrumentInfo(String Filename, uint InstrumentID) {
2570        dmsg(2,("LSCPServer: GetFileInstrumentInfo(String Filename=%s, InstrumentID=%d)\n",Filename.c_str(),InstrumentID));
2571        LSCPResultSet result;
2572        try {
2573            VerifyFile(Filename);
2574        } catch (Exception e) {
2575            result.Error(e);
2576            return result.Produce();
2577        }
2578        InstrumentManager::instrument_id_t id;
2579        id.FileName = Filename;
2580        id.Index    = InstrumentID;
2581        // try to find a sampler engine that can handle the file
2582        bool bFound = false;
2583        bool bFatalErr = false;
2584        std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
2585        for (int i = 0; !bFound && !bFatalErr && i < engineTypes.size(); i++) {
2586            Engine* pEngine = NULL;
2587            try {
2588                pEngine = EngineFactory::Create(engineTypes[i]);
2589                if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
2590                InstrumentManager* pManager = pEngine->GetInstrumentManager();
2591                if (pManager) {
2592                    // check if the instrument index is valid
2593                    // FIXME: this won't work if an engine only supports parts of the instrument file
2594                    std::vector<InstrumentManager::instrument_id_t> IDs =
2595                        pManager->GetInstrumentFileContent(Filename);
2596                    if (std::find(IDs.begin(), IDs.end(), id) == IDs.end()) {
2597                        std::stringstream ss;
2598                        ss << "Invalid instrument index " << InstrumentID << " for instrument file '" << Filename << "'";
2599                        bFatalErr = true;
2600                        throw Exception(ss.str());
2601                    }
2602                    // get the info of the requested instrument
2603                    InstrumentManager::instrument_info_t info =
2604                        pManager->GetInstrumentInfo(id);
2605                    // return detailed informations about the file
2606                    result.Add("NAME", info.InstrumentName);
2607                    result.Add("FORMAT_FAMILY", engineTypes[i]);
2608                    result.Add("FORMAT_VERSION", info.FormatVersion);
2609                    result.Add("PRODUCT", info.Product);
2610                    result.Add("ARTISTS", info.Artists);
2611                    // no more need to ask other engine types
2612                    bFound = true;
2613                } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
2614            } catch (Exception e) {
2615                // usually NOOP, as exception is thrown if engine doesn't support file
2616                if (bFatalErr) result.Error(e);
2617            }
2618            if (pEngine) EngineFactory::Destroy(pEngine);
2619        }
2620    
2621        if (!bFound && !bFatalErr) result.Error("Unknown file format");
2622        return result.Produce();
2623    }
2624    
2625    void LSCPServer::VerifyFile(String Filename) {
2626        #if WIN32
2627        WIN32_FIND_DATA win32FileAttributeData;
2628        BOOL res = GetFileAttributesEx( Filename.c_str(), GetFileExInfoStandard, &win32FileAttributeData );
2629        if (!res) {
2630            std::stringstream ss;
2631            ss << "File does not exist, GetFileAttributesEx failed `" << Filename << "`: Error " << GetLastError();
2632            throw Exception(ss.str());
2633        }
2634        if ( win32FileAttributeData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
2635            throw Exception("Directory is specified");
2636        }
2637        #else
2638        struct stat statBuf;
2639        int res = stat(Filename.c_str(), &statBuf);
2640        if (res) {
2641            std::stringstream ss;
2642            ss << "Fail to stat `" << Filename << "`: " << strerror(errno);
2643            throw Exception(ss.str());
2644        }
2645    
2646        if (S_ISDIR(statBuf.st_mode)) {
2647            throw Exception("Directory is specified");
2648        }
2649        #endif
2650    }
2651    
2652  /**  /**
2653   * 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
2654   * server for receiving event messages.   * server for receiving event messages.
# Line 1592  String LSCPServer::UnsubscribeNotificati Line 2675  String LSCPServer::UnsubscribeNotificati
2675      return result.Produce();      return result.Produce();
2676  }  }
2677    
2678  static int select_callback(void * lscpResultSet, int argc,  String LSCPServer::AddDbInstrumentDirectory(String Dir) {
2679                          char **argv, char **azColName)      dmsg(2,("LSCPServer: AddDbInstrumentDirectory(Dir=%s)\n", Dir.c_str()));
2680  {      LSCPResultSet result;
2681      LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;  #if HAVE_SQLITE3
2682      resultSet->Add(argc, argv);      try {
2683      return 0;          InstrumentsDb::GetInstrumentsDb()->AddDirectory(Dir);
2684        } catch (Exception e) {
2685             result.Error(e);
2686        }
2687    #else
2688        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2689    #endif
2690        return result.Produce();
2691    }
2692    
2693    String LSCPServer::RemoveDbInstrumentDirectory(String Dir, bool Force) {
2694        dmsg(2,("LSCPServer: RemoveDbInstrumentDirectory(Dir=%s,Force=%d)\n", Dir.c_str(), Force));
2695        LSCPResultSet result;
2696    #if HAVE_SQLITE3
2697        try {
2698            InstrumentsDb::GetInstrumentsDb()->RemoveDirectory(Dir, Force);
2699        } catch (Exception e) {
2700             result.Error(e);
2701        }
2702    #else
2703        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2704    #endif
2705        return result.Produce();
2706    }
2707    
2708    String LSCPServer::GetDbInstrumentDirectoryCount(String Dir, bool Recursive) {
2709        dmsg(2,("LSCPServer: GetDbInstrumentDirectoryCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2710        LSCPResultSet result;
2711    #if HAVE_SQLITE3
2712        try {
2713            result.Add(InstrumentsDb::GetInstrumentsDb()->GetDirectoryCount(Dir, Recursive));
2714        } catch (Exception e) {
2715             result.Error(e);
2716        }
2717    #else
2718        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2719    #endif
2720        return result.Produce();
2721    }
2722    
2723    String LSCPServer::GetDbInstrumentDirectories(String Dir, bool Recursive) {
2724        dmsg(2,("LSCPServer: GetDbInstrumentDirectories(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2725        LSCPResultSet result;
2726    #if HAVE_SQLITE3
2727        try {
2728            String list;
2729            StringListPtr dirs = InstrumentsDb::GetInstrumentsDb()->GetDirectories(Dir, Recursive);
2730    
2731            for (int i = 0; i < dirs->size(); i++) {
2732                if (list != "") list += ",";
2733                list += "'" + InstrumentsDb::toEscapedPath(dirs->at(i)) + "'";
2734            }
2735    
2736            result.Add(list);
2737        } catch (Exception e) {
2738             result.Error(e);
2739        }
2740    #else
2741        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2742    #endif
2743        return result.Produce();
2744    }
2745    
2746    String LSCPServer::GetDbInstrumentDirectoryInfo(String Dir) {
2747        dmsg(2,("LSCPServer: GetDbInstrumentDirectoryInfo(Dir=%s)\n", Dir.c_str()));
2748        LSCPResultSet result;
2749    #if HAVE_SQLITE3
2750        try {
2751            DbDirectory info = InstrumentsDb::GetInstrumentsDb()->GetDirectoryInfo(Dir);
2752    
2753            result.Add("DESCRIPTION", _escapeLscpResponse(info.Description));
2754            result.Add("CREATED", info.Created);
2755            result.Add("MODIFIED", info.Modified);
2756        } catch (Exception e) {
2757             result.Error(e);
2758        }
2759    #else
2760        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2761    #endif
2762        return result.Produce();
2763    }
2764    
2765    String LSCPServer::SetDbInstrumentDirectoryName(String Dir, String Name) {
2766        dmsg(2,("LSCPServer: SetDbInstrumentDirectoryName(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));
2767        LSCPResultSet result;
2768    #if HAVE_SQLITE3
2769        try {
2770            InstrumentsDb::GetInstrumentsDb()->RenameDirectory(Dir, Name);
2771        } catch (Exception e) {
2772             result.Error(e);
2773        }
2774    #else
2775        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2776    #endif
2777        return result.Produce();
2778    }
2779    
2780    String LSCPServer::MoveDbInstrumentDirectory(String Dir, String Dst) {
2781        dmsg(2,("LSCPServer: MoveDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
2782        LSCPResultSet result;
2783    #if HAVE_SQLITE3
2784        try {
2785            InstrumentsDb::GetInstrumentsDb()->MoveDirectory(Dir, Dst);
2786        } catch (Exception e) {
2787             result.Error(e);
2788        }
2789    #else
2790        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2791    #endif
2792        return result.Produce();
2793    }
2794    
2795    String LSCPServer::CopyDbInstrumentDirectory(String Dir, String Dst) {
2796        dmsg(2,("LSCPServer: CopyDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
2797        LSCPResultSet result;
2798    #if HAVE_SQLITE3
2799        try {
2800            InstrumentsDb::GetInstrumentsDb()->CopyDirectory(Dir, Dst);
2801        } catch (Exception e) {
2802             result.Error(e);
2803        }
2804    #else
2805        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2806    #endif
2807        return result.Produce();
2808    }
2809    
2810    String LSCPServer::SetDbInstrumentDirectoryDescription(String Dir, String Desc) {
2811        dmsg(2,("LSCPServer: SetDbInstrumentDirectoryDescription(Dir=%s,Desc=%s)\n", Dir.c_str(), Desc.c_str()));
2812        LSCPResultSet result;
2813    #if HAVE_SQLITE3
2814        try {
2815            InstrumentsDb::GetInstrumentsDb()->SetDirectoryDescription(Dir, Desc);
2816        } catch (Exception e) {
2817             result.Error(e);
2818        }
2819    #else
2820        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2821    #endif
2822        return result.Produce();
2823    }
2824    
2825    String LSCPServer::AddDbInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
2826        dmsg(2,("LSCPServer: AddDbInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));
2827        LSCPResultSet result;
2828    #if HAVE_SQLITE3
2829        try {
2830            int id;
2831            InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
2832            id = db->AddInstruments(DbDir, FilePath, Index, bBackground);
2833            if (bBackground) result = id;
2834        } catch (Exception e) {
2835             result.Error(e);
2836        }
2837    #else
2838        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2839    #endif
2840        return result.Produce();
2841    }
2842    
2843    String LSCPServer::AddDbInstruments(String ScanMode, String DbDir, String FsDir, bool bBackground) {
2844        dmsg(2,("LSCPServer: AddDbInstruments(ScanMode=%s,DbDir=%s,FsDir=%s,bBackground=%d)\n", ScanMode.c_str(), DbDir.c_str(), FsDir.c_str(), bBackground));
2845        LSCPResultSet result;
2846    #if HAVE_SQLITE3
2847        try {
2848            int id;
2849            InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
2850            if (ScanMode.compare("RECURSIVE") == 0) {
2851               id = db->AddInstruments(RECURSIVE, DbDir, FsDir, bBackground);
2852            } else if (ScanMode.compare("NON_RECURSIVE") == 0) {
2853               id = db->AddInstruments(NON_RECURSIVE, DbDir, FsDir, bBackground);
2854            } else if (ScanMode.compare("FLAT") == 0) {
2855               id = db->AddInstruments(FLAT, DbDir, FsDir, bBackground);
2856            } else {
2857                throw Exception("Unknown scan mode: " + ScanMode);
2858            }
2859    
2860            if (bBackground) result = id;
2861        } catch (Exception e) {
2862             result.Error(e);
2863        }
2864    #else
2865        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2866    #endif
2867        return result.Produce();
2868    }
2869    
2870    String LSCPServer::RemoveDbInstrument(String Instr) {
2871        dmsg(2,("LSCPServer: RemoveDbInstrument(Instr=%s)\n", Instr.c_str()));
2872        LSCPResultSet result;
2873    #if HAVE_SQLITE3
2874        try {
2875            InstrumentsDb::GetInstrumentsDb()->RemoveInstrument(Instr);
2876        } catch (Exception e) {
2877             result.Error(e);
2878        }
2879    #else
2880        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2881    #endif
2882        return result.Produce();
2883    }
2884    
2885    String LSCPServer::GetDbInstrumentCount(String Dir, bool Recursive) {
2886        dmsg(2,("LSCPServer: GetDbInstrumentCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2887        LSCPResultSet result;
2888    #if HAVE_SQLITE3
2889        try {
2890            result.Add(InstrumentsDb::GetInstrumentsDb()->GetInstrumentCount(Dir, Recursive));
2891        } catch (Exception e) {
2892             result.Error(e);
2893        }
2894    #else
2895        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2896    #endif
2897        return result.Produce();
2898    }
2899    
2900    String LSCPServer::GetDbInstruments(String Dir, bool Recursive) {
2901        dmsg(2,("LSCPServer: GetDbInstruments(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2902        LSCPResultSet result;
2903    #if HAVE_SQLITE3
2904        try {
2905            String list;
2906            StringListPtr instrs = InstrumentsDb::GetInstrumentsDb()->GetInstruments(Dir, Recursive);
2907    
2908            for (int i = 0; i < instrs->size(); i++) {
2909                if (list != "") list += ",";
2910                list += "'" + InstrumentsDb::toEscapedPath(instrs->at(i)) + "'";
2911            }
2912    
2913            result.Add(list);
2914        } catch (Exception e) {
2915             result.Error(e);
2916        }
2917    #else
2918        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2919    #endif
2920        return result.Produce();
2921    }
2922    
2923    String LSCPServer::GetDbInstrumentInfo(String Instr) {
2924        dmsg(2,("LSCPServer: GetDbInstrumentInfo(Instr=%s)\n", Instr.c_str()));
2925        LSCPResultSet result;
2926    #if HAVE_SQLITE3
2927        try {
2928            DbInstrument info = InstrumentsDb::GetInstrumentsDb()->GetInstrumentInfo(Instr);
2929    
2930            result.Add("INSTRUMENT_FILE", info.InstrFile);
2931            result.Add("INSTRUMENT_NR", info.InstrNr);
2932            result.Add("FORMAT_FAMILY", info.FormatFamily);
2933            result.Add("FORMAT_VERSION", info.FormatVersion);
2934            result.Add("SIZE", (int)info.Size);
2935            result.Add("CREATED", info.Created);
2936            result.Add("MODIFIED", info.Modified);
2937            result.Add("DESCRIPTION", _escapeLscpResponse(info.Description));
2938            result.Add("IS_DRUM", info.IsDrum);
2939            result.Add("PRODUCT", _escapeLscpResponse(info.Product));
2940            result.Add("ARTISTS", _escapeLscpResponse(info.Artists));
2941            result.Add("KEYWORDS", _escapeLscpResponse(info.Keywords));
2942        } catch (Exception e) {
2943             result.Error(e);
2944        }
2945    #else
2946        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2947    #endif
2948        return result.Produce();
2949  }  }
2950    
2951  String LSCPServer::QueryDatabase(String query) {  String LSCPServer::GetDbInstrumentsJobInfo(int JobId) {
2952        dmsg(2,("LSCPServer: GetDbInstrumentsJobInfo(JobId=%d)\n", JobId));
2953      LSCPResultSet result;      LSCPResultSet result;
2954  #if HAVE_SQLITE3  #if HAVE_SQLITE3
2955      char* zErrMsg = NULL;      try {
2956      sqlite3 *db;          ScanJob job = InstrumentsDb::GetInstrumentsDb()->Jobs.GetJobById(JobId);
     String selectStr = "SELECT " + query;  
2957    
2958      int rc = sqlite3_open("linuxsampler.db", &db);          result.Add("FILES_TOTAL", job.FilesTotal);
2959      if (rc == SQLITE_OK)          result.Add("FILES_SCANNED", job.FilesScanned);
2960      {          result.Add("SCANNING", job.Scanning);
2961              rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);          result.Add("STATUS", job.Status);
2962        } catch (Exception e) {
2963             result.Error(e);
2964      }      }
2965      if ( rc != SQLITE_OK )  #else
2966      {      result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2967              result.Error(String(zErrMsg), rc);  #endif
2968        return result.Produce();
2969    }
2970    
2971    String LSCPServer::SetDbInstrumentName(String Instr, String Name) {
2972        dmsg(2,("LSCPServer: SetDbInstrumentName(Instr=%s,Name=%s)\n", Instr.c_str(), Name.c_str()));
2973        LSCPResultSet result;
2974    #if HAVE_SQLITE3
2975        try {
2976            InstrumentsDb::GetInstrumentsDb()->RenameInstrument(Instr, Name);
2977        } catch (Exception e) {
2978             result.Error(e);
2979      }      }
     sqlite3_close(db);  
2980  #else  #else
2981      result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);      result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2982  #endif  #endif
2983      return result.Produce();      return result.Produce();
2984  }  }
2985    
2986    String LSCPServer::MoveDbInstrument(String Instr, String Dst) {
2987        dmsg(2,("LSCPServer: MoveDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
2988        LSCPResultSet result;
2989    #if HAVE_SQLITE3
2990        try {
2991            InstrumentsDb::GetInstrumentsDb()->MoveInstrument(Instr, Dst);
2992        } catch (Exception e) {
2993             result.Error(e);
2994        }
2995    #else
2996        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2997    #endif
2998        return result.Produce();
2999    }
3000    
3001    String LSCPServer::CopyDbInstrument(String Instr, String Dst) {
3002        dmsg(2,("LSCPServer: CopyDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
3003        LSCPResultSet result;
3004    #if HAVE_SQLITE3
3005        try {
3006            InstrumentsDb::GetInstrumentsDb()->CopyInstrument(Instr, Dst);
3007        } catch (Exception e) {
3008             result.Error(e);
3009        }
3010    #else
3011        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3012    #endif
3013        return result.Produce();
3014    }
3015    
3016    String LSCPServer::SetDbInstrumentDescription(String Instr, String Desc) {
3017        dmsg(2,("LSCPServer: SetDbInstrumentDescription(Instr=%s,Desc=%s)\n", Instr.c_str(), Desc.c_str()));
3018        LSCPResultSet result;
3019    #if HAVE_SQLITE3
3020        try {
3021            InstrumentsDb::GetInstrumentsDb()->SetInstrumentDescription(Instr, Desc);
3022        } catch (Exception e) {
3023             result.Error(e);
3024        }
3025    #else
3026        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3027    #endif
3028        return result.Produce();
3029    }
3030    
3031    String LSCPServer::FindDbInstrumentDirectories(String Dir, std::map<String,String> Parameters, bool Recursive) {
3032        dmsg(2,("LSCPServer: FindDbInstrumentDirectories(Dir=%s)\n", Dir.c_str()));
3033        LSCPResultSet result;
3034    #if HAVE_SQLITE3
3035        try {
3036            SearchQuery Query;
3037            std::map<String,String>::iterator iter;
3038            for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
3039                if (iter->first.compare("NAME") == 0) {
3040                    Query.Name = iter->second;
3041                } else if (iter->first.compare("CREATED") == 0) {
3042                    Query.SetCreated(iter->second);
3043                } else if (iter->first.compare("MODIFIED") == 0) {
3044                    Query.SetModified(iter->second);
3045                } else if (iter->first.compare("DESCRIPTION") == 0) {
3046                    Query.Description = iter->second;
3047                } else {
3048                    throw Exception("Unknown search criteria: " + iter->first);
3049                }
3050            }
3051    
3052            String list;
3053            StringListPtr pDirectories =
3054                InstrumentsDb::GetInstrumentsDb()->FindDirectories(Dir, &Query, Recursive);
3055    
3056            for (int i = 0; i < pDirectories->size(); i++) {
3057                if (list != "") list += ",";
3058                list += "'" + InstrumentsDb::toEscapedPath(pDirectories->at(i)) + "'";
3059            }
3060    
3061            result.Add(list);
3062        } catch (Exception e) {
3063             result.Error(e);
3064        }
3065    #else
3066        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3067    #endif
3068        return result.Produce();
3069    }
3070    
3071    String LSCPServer::FindDbInstruments(String Dir, std::map<String,String> Parameters, bool Recursive) {
3072        dmsg(2,("LSCPServer: FindDbInstruments(Dir=%s)\n", Dir.c_str()));
3073        LSCPResultSet result;
3074    #if HAVE_SQLITE3
3075        try {
3076            SearchQuery Query;
3077            std::map<String,String>::iterator iter;
3078            for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
3079                if (iter->first.compare("NAME") == 0) {
3080                    Query.Name = iter->second;
3081                } else if (iter->first.compare("FORMAT_FAMILIES") == 0) {
3082                    Query.SetFormatFamilies(iter->second);
3083                } else if (iter->first.compare("SIZE") == 0) {
3084                    Query.SetSize(iter->second);
3085                } else if (iter->first.compare("CREATED") == 0) {
3086                    Query.SetCreated(iter->second);
3087                } else if (iter->first.compare("MODIFIED") == 0) {
3088                    Query.SetModified(iter->second);
3089                } else if (iter->first.compare("DESCRIPTION") == 0) {
3090                    Query.Description = iter->second;
3091                } else if (iter->first.compare("IS_DRUM") == 0) {
3092                    if (!strcasecmp(iter->second.c_str(), "true")) {
3093                        Query.InstrType = SearchQuery::DRUM;
3094                    } else {
3095                        Query.InstrType = SearchQuery::CHROMATIC;
3096                    }
3097                } else if (iter->first.compare("PRODUCT") == 0) {
3098                     Query.Product = iter->second;
3099                } else if (iter->first.compare("ARTISTS") == 0) {
3100                     Query.Artists = iter->second;
3101                } else if (iter->first.compare("KEYWORDS") == 0) {
3102                     Query.Keywords = iter->second;
3103                } else {
3104                    throw Exception("Unknown search criteria: " + iter->first);
3105                }
3106            }
3107    
3108            String list;
3109            StringListPtr pInstruments =
3110                InstrumentsDb::GetInstrumentsDb()->FindInstruments(Dir, &Query, Recursive);
3111    
3112            for (int i = 0; i < pInstruments->size(); i++) {
3113                if (list != "") list += ",";
3114                list += "'" + InstrumentsDb::toEscapedPath(pInstruments->at(i)) + "'";
3115            }
3116    
3117            result.Add(list);
3118        } catch (Exception e) {
3119             result.Error(e);
3120        }
3121    #else
3122        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3123    #endif
3124        return result.Produce();
3125    }
3126    
3127    String LSCPServer::FormatInstrumentsDb() {
3128        dmsg(2,("LSCPServer: FormatInstrumentsDb()\n"));
3129        LSCPResultSet result;
3130    #if HAVE_SQLITE3
3131        try {
3132            InstrumentsDb::GetInstrumentsDb()->Format();
3133        } catch (Exception e) {
3134             result.Error(e);
3135        }
3136    #else
3137        result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3138    #endif
3139        return result.Produce();
3140    }
3141    
3142    
3143  /**  /**
3144   * 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
3145   * mode is enabled, all commands from the client will (immediately) be   * mode is enabled, all commands from the client will (immediately) be
# Line 1634  String LSCPServer::SetEcho(yyparse_param Line 3151  String LSCPServer::SetEcho(yyparse_param
3151      try {      try {
3152          if      (boolean_value == 0) pSession->bVerbose = false;          if      (boolean_value == 0) pSession->bVerbose = false;
3153          else if (boolean_value == 1) pSession->bVerbose = true;          else if (boolean_value == 1) pSession->bVerbose = true;
3154          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");
3155      }      }
3156      catch (LinuxSamplerException e) {      catch (Exception e) {
3157           result.Error(e);           result.Error(e);
3158      }      }
3159      return result.Produce();      return result.Produce();

Legend:
Removed from v.778  
changed lines
  Added in v.1686

  ViewVC Help
Powered by ViewVC