/[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 35 by schoenebeck, Fri Mar 5 13:46:15 2004 UTC revision 1108 by iliev, Thu Mar 22 20:39:04 2007 UTC
# Line 2  Line 2 
2   *                                                                         *   *                                                                         *
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck         *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6     *   Copyright (C) 2005 - 2007 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This program is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
10   *   the Free Software Foundation; either version 2 of the License, or     *   *   the Free Software Foundation; either version 2 of the License, or     *
11   *   (at your option) any later version.                                   *   *   (at your option) any later version.                                   *
12   *                                                                         *   *                                                                         *
13   *   This program is distributed in the hope that it will be useful,       *   *   This library is distributed in the hope that it will be useful,       *
14   *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *   *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16   *   GNU General Public License for more details.                          *   *   GNU General Public License for more details.                          *
17   *                                                                         *   *                                                                         *
18   *   You should have received a copy of the GNU General Public License     *   *   You should have received a copy of the GNU General Public License     *
19   *   along with this program; if not, write to the Free Software           *   *   along with this library; if not, write to the Free Software           *
20   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21   *   MA  02111-1307  USA                                                   *   *   MA  02111-1307  USA                                                   *
22   ***************************************************************************/   ***************************************************************************/
23    
24  #include "lscpserver.h"  #include "lscpserver.h"
25    #include "lscpresultset.h"
26    #include "lscpevent.h"
27    #include "../common/global.h"
28    
29    #include <fcntl.h>
30    
31    #if HAVE_SQLITE3
32    # include "sqlite3.h"
33    #endif
34    
35    #include "../engines/EngineFactory.h"
36    #include "../engines/EngineChannelFactory.h"
37    #include "../drivers/audio/AudioOutputDeviceFactory.h"
38    #include "../drivers/midi/MidiInputDeviceFactory.h"
39    
40  LSCPServer::LSCPServer(AudioThread* pEngine) : Thread(false, 0, -4) {  /**
41      this->pEngine = pEngine;   * Below are a few static members of the LSCPServer class.
42     * The big assumption here is that LSCPServer is going to remain a singleton.
43     * These members are used to support client connections.
44     * Class handles multiple connections at the same time using select() and non-blocking recv()
45     * Commands are processed by a single LSCPServer thread.
46     * Notifications are delivered either by the thread that originated them
47     * or (if the resultset is currently in progress) by the LSCPServer thread
48     * after the resultset was sent out.
49     * This makes sure that resultsets can not be interrupted by notifications.
50     * This also makes sure that the thread sending notification is not blocked
51     * by the LSCPServer thread.
52     */
53    fd_set LSCPServer::fdSet;
54    int LSCPServer::currentSocket = -1;
55    std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();
56    std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();
57    std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();
58    std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();
59    Mutex LSCPServer::NotifyMutex = Mutex();
60    Mutex LSCPServer::NotifyBufferMutex = Mutex();
61    Mutex LSCPServer::SubscriptionMutex = Mutex();
62    Mutex LSCPServer::RTNotifyMutex = Mutex();
63    
64    LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4) {
65        SocketAddress.sin_family      = AF_INET;
66        SocketAddress.sin_addr.s_addr = addr;
67        SocketAddress.sin_port        = port;
68        this->pSampler = pSampler;
69        LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
70        LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
71        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_count, "MIDI_INPUT_DEVICE_COUNT");
72        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_info, "MIDI_INPUT_DEVICE_INFO");
73        LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");
74        LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
75        LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
76        LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
77        LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");
78        LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_count, "FX_SEND_COUNT");
79        LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_info, "FX_SEND_INFO");
80        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_count, "MIDI_INSTRUMENT_MAP_COUNT");
81        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_info, "MIDI_INSTRUMENT_MAP_INFO");
82        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_count, "MIDI_INSTRUMENT_COUNT");
83        LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_info, "MIDI_INSTRUMENT_INFO");
84        LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
85        LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");
86        LSCPEvent::RegisterEvent(LSCPEvent::event_global_info, "GLOBAL_INFO");
87        hSocket = -1;
88    }
89    
90    LSCPServer::~LSCPServer() {
91        if (hSocket >= 0) close(hSocket);
92    }
93    
94    /**
95     * Blocks the calling thread until the LSCP Server is initialized and
96     * accepting socket connections, if the server is already initialized then
97     * this method will return immediately.
98     * @param TimeoutSeconds     - optional: max. wait time in seconds
99     *                             (default: 0s)
100     * @param TimeoutNanoSeconds - optional: max wait time in nano seconds
101     *                             (default: 0ns)
102     * @returns  0 on success, a value less than 0 if timeout exceeded
103     */
104    int LSCPServer::WaitUntilInitialized(long TimeoutSeconds, long TimeoutNanoSeconds) {
105        return Initialized.WaitAndUnlockIf(false, TimeoutSeconds, TimeoutNanoSeconds);
106  }  }
107    
108  int LSCPServer::Main() {  int LSCPServer::Main() {
109      hSocket = socket(AF_INET, SOCK_STREAM, 0);      hSocket = socket(AF_INET, SOCK_STREAM, 0);
110      if (hSocket < 0) {      if (hSocket < 0) {
111          std::cerr << "LSCPServer: Could not create server socket." << std::endl;          std::cerr << "LSCPServer: Could not create server socket." << std::endl;
112          return -1;          //return -1;
113            exit(EXIT_FAILURE);
114      }      }
115    
     SocketAddress.sin_family      = AF_INET;  
     SocketAddress.sin_port        = htons(LSCP_PORT);  
     SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);  
   
116      if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {      if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
117          std::cerr << "LSCPServer: Could not bind server socket." << std::endl;          std::cerr << "LSCPServer: Could not bind server socket, retrying for " << ToString(LSCP_SERVER_BIND_TIMEOUT) << " seconds...";
118          close(hSocket);          for (int trial = 0; true; trial++) { // retry for LSCP_SERVER_BIND_TIMEOUT seconds
119          return -1;              if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
120                    if (trial > LSCP_SERVER_BIND_TIMEOUT) {
121                        std::cerr << "gave up!" << std::endl;
122                        close(hSocket);
123                        //return -1;
124                        exit(EXIT_FAILURE);
125                    }
126                    else sleep(1); // sleep 1s
127                }
128                else break; // success
129            }
130      }      }
131    
132      listen(hSocket, 1);      listen(hSocket, 1);
133      dmsg(1,("LSCPServer: Server running.\n")); // server running      Initialized.Set(true);
134    
135      // now wait for client connections and handle their requests      // now wait for client connections and handle their requests
136      sockaddr_in client;      sockaddr_in client;
137      int length = sizeof(client);      int length = sizeof(client);
138        FD_ZERO(&fdSet);
139        FD_SET(hSocket, &fdSet);
140        int maxSessions = hSocket;
141    
142        timeval timeout;
143    
144      while (true) {      while (true) {
145          hSession = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);          // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers
146          if (hSession < 0) {          {
147              std::cerr << "LSCPServer: Client connection failed." << std::endl;              std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
148              close(hSocket);              std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
149              return -1;              std::set<EngineChannel*>::iterator itEnd           = engineChannels.end();
150          }              for (; itEngineChannel != itEnd; ++itEngineChannel) {
151                    if ((*itEngineChannel)->StatusChanged()) {
152          dmsg(1,("LSCPServer: Client connection established.\n"));                      SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));
153          //send(hSession, "Welcome!\r\n", 10, 0);                  }
154    
155          // Parser invocation                  for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
156          yyparse_param_t yyparse_param;                      FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
157          yyparse_param.pServer = this;                      if(fxs != NULL && fxs->IsInfoChanged()) {
158          yylex_init(&yyparse_param.pScanner);                          int chn = (*itEngineChannel)->iSamplerChannelIndex;
159          while (yyparse(&yyparse_param) == LSCP_SYNTAX_ERROR); // recall parser in case of syntax error                          LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));
160          yylex_destroy(yyparse_param.pScanner);                          fxs->SetInfoChanged(false);
161                        }
162                    }
163                }
164            }
165    
166          close(hSession);          //Now let's deliver late notifies (if any)
167          dmsg(1,("LSCPServer: Client connection terminated.\n"));          NotifyBufferMutex.Lock();
168            for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
169    #ifdef MSG_NOSIGNAL
170                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), MSG_NOSIGNAL);
171    #else
172                    send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
173    #endif
174            }
175            bufferedNotifies.clear();
176            NotifyBufferMutex.Unlock();
177    
178            fd_set selectSet = fdSet;
179            timeout.tv_sec  = 0;
180            timeout.tv_usec = 100000;
181    
182            int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
183    
184            if (retval == 0)
185                    continue; //Nothing try again
186            if (retval == -1) {
187                    std::cerr << "LSCPServer: Socket select error." << std::endl;
188                    close(hSocket);
189                    exit(EXIT_FAILURE);
190            }
191    
192            //Accept new connections now (if any)
193            if (FD_ISSET(hSocket, &selectSet)) {
194                    int socket = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
195                    if (socket < 0) {
196                            std::cerr << "LSCPServer: Client connection failed." << std::endl;
197                            exit(EXIT_FAILURE);
198                    }
199    
200                    if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
201                            std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
202                            exit(EXIT_FAILURE);
203                    }
204    
205                    // Parser initialization
206                    yyparse_param_t yyparse_param;
207                    yyparse_param.pServer  = this;
208                    yyparse_param.hSession = socket;
209    
210                    Sessions.push_back(yyparse_param);
211                    FD_SET(socket, &fdSet);
212                    if (socket > maxSessions)
213                            maxSessions = socket;
214                    dmsg(1,("LSCPServer: Client connection established on socket:%d.\n", socket));
215                    LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection established on socket", socket));
216                    continue; //Maybe this was the only selected socket, better select again
217            }
218    
219            //Something was selected and it was not the hSocket, so it must be some command(s) coming.
220            for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {
221                    if (FD_ISSET((*iter).hSession, &selectSet)) {   //Was it this socket?
222                            if (GetLSCPCommand(iter)) {     //Have we read the entire command?
223                                    dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));
224                                    int dummy; // just a temporary hack to fulfill the restart() function prototype
225                                    restart(NULL, dummy); // restart the 'scanner'
226                                    currentSocket = (*iter).hSession;  //a hack
227                                    dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
228                                    if ((*iter).bVerbose) { // if echo mode enabled
229                                        AnswerClient(bufferedCommands[currentSocket]);
230                                    }
231                                    int result = yyparse(&(*iter));
232                                    currentSocket = -1;     //continuation of a hack
233                                    dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));
234                                    if (result == LSCP_QUIT) { //Was it a quit command by any chance?
235                                            CloseConnection(iter);
236                                    }
237                            }
238                            //socket may have been closed, iter may be invalid, get out of the loop for now.
239                            //we'll be back if there is data.
240                            break;
241                    }
242            }
243      }      }
244  }  }
245    
246    void LSCPServer::CloseConnection( std::vector<yyparse_param_t>::iterator iter ) {
247            int socket = (*iter).hSession;
248            dmsg(1,("LSCPServer: Client connection terminated on socket:%d.\n",socket));
249            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection terminated on socket", socket));
250            Sessions.erase(iter);
251            FD_CLR(socket,  &fdSet);
252            SubscriptionMutex.Lock(); //Must unsubscribe this socket from all events (if any)
253            for (std::map< LSCPEvent::event_t, std::list<int> >::iterator iter = eventSubscriptions.begin(); iter != eventSubscriptions.end(); iter++) {
254                    iter->second.remove(socket);
255            }
256            SubscriptionMutex.Unlock();
257            NotifyMutex.Lock();
258            bufferedCommands.erase(socket);
259            bufferedNotifies.erase(socket);
260            close(socket);
261            NotifyMutex.Unlock();
262    }
263    
264    int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
265            int subs = 0;
266            SubscriptionMutex.Lock();
267            for( std::list<LSCPEvent::event_t>::iterator iter = events.begin();
268                            iter != events.end(); iter++)
269            {
270                    subs += eventSubscriptions.count(*iter);
271            }
272            SubscriptionMutex.Unlock();
273            return subs;
274    }
275    
276    void LSCPServer::SendLSCPNotify( LSCPEvent event ) {
277            SubscriptionMutex.Lock();
278            if (eventSubscriptions.count(event.GetType()) == 0) {
279                    SubscriptionMutex.Unlock();     //Nobody is subscribed to this event
280                    return;
281            }
282            std::list<int>::iterator iter = eventSubscriptions[event.GetType()].begin();
283            std::list<int>::iterator end = eventSubscriptions[event.GetType()].end();
284            String notify = event.Produce();
285    
286            while (true) {
287                    if (NotifyMutex.Trylock()) {
288                            for(;iter != end; iter++)
289    #ifdef MSG_NOSIGNAL
290                                    send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);
291    #else
292                                    send(*iter, notify.c_str(), notify.size(), 0);
293    #endif
294                            NotifyMutex.Unlock();
295                            break;
296                    } else {
297                            if (NotifyBufferMutex.Trylock()) {
298                                    for(;iter != end; iter++)
299                                            bufferedNotifies[*iter] += notify;
300                                    NotifyBufferMutex.Unlock();
301                                    break;
302                            }
303                    }
304            }
305            SubscriptionMutex.Unlock();
306    }
307    
308    extern int GetLSCPCommand( void *buf, int max_size ) {
309            String command = LSCPServer::bufferedCommands[LSCPServer::currentSocket];
310            if (command.size() == 0) {              //Parser wants input but we have nothing.
311                    strcpy((char*) buf, "\n");      //So give it an empty command
312                    return 1;                       //to keep it happy.
313            }
314    
315            if (max_size < command.size()) {
316                    std::cerr << "getLSCPCommand: Flex buffer too small, ignoring the command." << std::endl;
317                    return 0;       //This will never happen
318            }
319    
320            strcpy((char*) buf, command.c_str());
321            LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);
322            return command.size();
323    }
324    
325    /**
326     * Will be called to try to read the command from the socket
327     * If command is read, it will return true. Otherwise false is returned.
328     * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.
329     */
330    bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
331            int socket = (*iter).hSession;
332            char c;
333            int i = 0;
334            while (true) {
335                    int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
336                    if (result == 0) { //socket was selected, so 0 here means client has closed the connection
337                            CloseConnection(iter);
338                            break;
339                    }
340                    if (result == 1) {
341                            if (c == '\r')
342                                    continue; //Ignore CR
343                            if (c == '\n') {
344                                    LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
345                                    bufferedCommands[socket] += "\r\n";
346                                    return true; //Complete command was read
347                            }
348                            bufferedCommands[socket] += c;
349                    }
350                    if (result == -1) {
351                            if (errno == EAGAIN) //Would block, try again later.
352                                    return false;
353                            switch(errno) {
354                                    case EBADF:
355                                            dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
356                                            break;
357                                    case ECONNREFUSED:
358                                            dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
359                                            break;
360                                    case ENOTCONN:
361                                            dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
362                                            break;
363                                    case ENOTSOCK:
364                                            dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
365                                            break;
366                                    case EAGAIN:
367                                            dmsg(2,("LSCPScanner: The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n"));
368                                            break;
369                                    case EINTR:
370                                            dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
371                                            break;
372                                    case EFAULT:
373                                            dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
374                                            break;
375                                    case EINVAL:
376                                            dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
377                                            break;
378                                    case ENOMEM:
379                                            dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
380                                            break;
381                                    default:
382                                            dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
383                                            break;
384                            }
385                            CloseConnection(iter);
386                            break;
387                    }
388            }
389            return false;
390    }
391    
392  /**  /**
393   * Will be called by the parser whenever it wants to send an answer to the   * Will be called by the parser whenever it wants to send an answer to the
394   * client / frontend.   * client / frontend.
# Line 80  int LSCPServer::Main() { Line 397  int LSCPServer::Main() {
397   */   */
398  void LSCPServer::AnswerClient(String ReturnMessage) {  void LSCPServer::AnswerClient(String ReturnMessage) {
399      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));      dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
400      send(hSession, ReturnMessage.c_str(), ReturnMessage.size(), 0);      if (currentSocket != -1) {
401                NotifyMutex.Lock();
402    #ifdef MSG_NOSIGNAL
403                send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
404    #else
405                send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
406    #endif
407                NotifyMutex.Unlock();
408        }
409    }
410    
411    /**
412     * Find a created audio output device index.
413     */
414    int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
415    {
416        // Search for the created device to get its index
417        std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
418        std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
419        for (; iter != devices.end(); iter++) {
420            if (iter->second == pDevice)
421                return iter->first;
422        }
423        // Not found.
424        return -1;
425    }
426    
427    /**
428     * Find a created midi input device index.
429     */
430    int LSCPServer::GetMidiInputDeviceIndex ( MidiInputDevice *pDevice )
431    {
432        // Search for the created device to get its index
433        std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
434        std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
435        for (; iter != devices.end(); iter++) {
436            if (iter->second == pDevice)
437                return iter->first;
438        }
439        // Not found.
440        return -1;
441    }
442    
443    String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
444        dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
445        LSCPResultSet result;
446        try {
447            AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
448            // search for the created device to get its index
449            int index = GetAudioOutputDeviceIndex(pDevice);
450            if (index == -1) throw Exception("Internal error: could not find created audio output device.");
451            result = index; // success
452        }
453        catch (Exception e) {
454            result.Error(e);
455        }
456        return result.Produce();
457    }
458    
459    String LSCPServer::CreateMidiInputDevice(String Driver, std::map<String,String> Parameters) {
460        dmsg(2,("LSCPServer: CreateMidiInputDevice(Driver=%s)\n", Driver.c_str()));
461        LSCPResultSet result;
462        try {
463            MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
464            // search for the created device to get its index
465            int index = GetMidiInputDeviceIndex(pDevice);
466            if (index == -1) throw Exception("Internal error: could not find created midi input device.");
467            result = index; // success
468        }
469        catch (Exception e) {
470            result.Error(e);
471        }
472        return result.Produce();
473    }
474    
475    String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
476        dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
477        LSCPResultSet result;
478        try {
479            std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
480            if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
481            AudioOutputDevice* pDevice = devices[DeviceIndex];
482            pSampler->DestroyAudioOutputDevice(pDevice);
483        }
484        catch (Exception e) {
485            result.Error(e);
486        }
487        return result.Produce();
488    }
489    
490    String LSCPServer::DestroyMidiInputDevice(uint DeviceIndex) {
491        dmsg(2,("LSCPServer: DestroyMidiInputDevice(DeviceIndex=%d)\n", DeviceIndex));
492        LSCPResultSet result;
493        try {
494            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
495            if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
496            MidiInputDevice* pDevice = devices[DeviceIndex];
497            pSampler->DestroyMidiInputDevice(pDevice);
498        }
499        catch (Exception e) {
500            result.Error(e);
501        }
502        return result.Produce();
503  }  }
504    
505  /**  /**
506   * Will be called by the parser to load an instrument.   * Will be called by the parser to load an instrument.
507   */   */
508  String LSCPServer::LoadInstrument(String Filename, uint Instrument, uint SamplerChannel) {  String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
509      dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), Instrument, SamplerChannel));      dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
510      result_t res = pEngine->LoadInstrument(Filename.c_str(), Instrument);      LSCPResultSet result;
511      return ConvertResult(res);      try {
512            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
513            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
514            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
515            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
516            if (!pSamplerChannel->GetAudioOutputDevice())
517                throw Exception("No audio output device connected to sampler channel");
518            if (bBackground) {
519                InstrumentManager::instrument_id_t id;
520                id.FileName = Filename;
521                id.Index    = uiInstrument;
522                InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
523            }
524            else {
525                // tell the engine channel which instrument to load
526                pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrument);
527                // actually start to load the instrument (blocks until completed)
528                pEngineChannel->LoadInstrument();
529            }
530        }
531        catch (Exception e) {
532             result.Error(e);
533        }
534        return result.Produce();
535  }  }
536    
537  /**  /**
538   * Will be called by the parser to load and deploy an engine.   * Will be called by the parser to assign a sampler engine type to a
539     * sampler channel.
540   */   */
541  String LSCPServer::LoadEngine(String EngineName, uint SamplerChannel) {  String LSCPServer::SetEngineType(String EngineName, uint uiSamplerChannel) {
542      dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), SamplerChannel));      dmsg(2,("LSCPServer: SetEngineType(EngineName=%s,uiSamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
543      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
544        try {
545            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
546            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
547            LockRTNotify();
548            pSamplerChannel->SetEngineType(EngineName);
549            if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
550            UnlockRTNotify();
551        }
552        catch (Exception e) {
553             result.Error(e);
554        }
555        return result.Produce();
556  }  }
557    
558  /**  /**
# Line 105  String LSCPServer::LoadEngine(String Eng Line 560  String LSCPServer::LoadEngine(String Eng
560   */   */
561  String LSCPServer::GetChannels() {  String LSCPServer::GetChannels() {
562      dmsg(2,("LSCPServer: GetChannels()\n"));      dmsg(2,("LSCPServer: GetChannels()\n"));
563      return "1\r\n";      LSCPResultSet result;
564        result.Add(pSampler->SamplerChannels());
565        return result.Produce();
566    }
567    
568    /**
569     * Will be called by the parser to get the list of sampler channels.
570     */
571    String LSCPServer::ListChannels() {
572        dmsg(2,("LSCPServer: ListChannels()\n"));
573        String list;
574        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
575        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
576        for (; iter != channels.end(); iter++) {
577            if (list != "") list += ",";
578            list += ToString(iter->first);
579        }
580        LSCPResultSet result;
581        result.Add(list);
582        return result.Produce();
583  }  }
584    
585  /**  /**
# Line 113  String LSCPServer::GetChannels() { Line 587  String LSCPServer::GetChannels() {
587   */   */
588  String LSCPServer::AddChannel() {  String LSCPServer::AddChannel() {
589      dmsg(2,("LSCPServer: AddChannel()\n"));      dmsg(2,("LSCPServer: AddChannel()\n"));
590      return "ERR:0:Not implemented yet.\r\n";      LockRTNotify();
591        SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
592        UnlockRTNotify();
593        LSCPResultSet result(pSamplerChannel->Index());
594        return result.Produce();
595  }  }
596    
597  /**  /**
598   * Will be called by the parser to remove a sampler channel.   * Will be called by the parser to remove a sampler channel.
599   */   */
600  String LSCPServer::RemoveChannel(uint SamplerChannel) {  String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
601      dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", SamplerChannel));      dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
602      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
603        LockRTNotify();
604        pSampler->RemoveSamplerChannel(uiSamplerChannel);
605        UnlockRTNotify();
606        return result.Produce();
607  }  }
608    
609  /**  /**
610   * Will be called by the parser to get all available engines.   * Will be called by the parser to get the amount of all available engines.
611   */   */
612  String LSCPServer::GetAvailableEngines() {  String LSCPServer::GetAvailableEngines() {
613      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
614      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
615        try {
616            int n = EngineFactory::AvailableEngineTypes().size();
617            result.Add(n);
618        }
619        catch (Exception e) {
620            result.Error(e);
621        }
622        return result.Produce();
623    }
624    
625    /**
626     * Will be called by the parser to get a list of all available engines.
627     */
628    String LSCPServer::ListAvailableEngines() {
629        dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
630        LSCPResultSet result;
631        try {
632            String s = EngineFactory::AvailableEngineTypesAsString();
633            result.Add(s);
634        }
635        catch (Exception e) {
636            result.Error(e);
637        }
638        return result.Produce();
639  }  }
640    
641  /**  /**
642   * Will be called by the parser to get descriptions for a particular engine.   * Will be called by the parser to get descriptions for a particular
643     * sampler engine.
644   */   */
645  String LSCPServer::GetEngineInfo(String EngineName) {  String LSCPServer::GetEngineInfo(String EngineName) {
646      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));      dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
647      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
648        LockRTNotify();
649        try {
650            Engine* pEngine = EngineFactory::Create(EngineName);
651            result.Add("DESCRIPTION", pEngine->Description());
652            result.Add("VERSION",     pEngine->Version());
653            EngineFactory::Destroy(pEngine);
654        }
655        catch (Exception e) {
656             result.Error(e);
657        }
658        UnlockRTNotify();
659        return result.Produce();
660  }  }
661    
662  /**  /**
663   * Will be called by the parser to get informations about a particular   * Will be called by the parser to get informations about a particular
664   * sampler channel.   * sampler channel.
665   */   */
666  String LSCPServer::GetChannelInfo(uint SamplerChannel) {  String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
667      dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", SamplerChannel));      dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
668      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
669        try {
670            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
671            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
672            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
673    
674            //Defaults values
675            String EngineName = "NONE";
676            float Volume = 0.0f;
677            String InstrumentFileName = "NONE";
678            String InstrumentName = "NONE";
679            int InstrumentIndex = -1;
680            int InstrumentStatus = -1;
681            int AudioOutputChannels = 0;
682            String AudioRouting;
683            int Mute = 0;
684            bool Solo = false;
685            String MidiInstrumentMap;
686    
687            if (pEngineChannel) {
688                EngineName          = pEngineChannel->EngineName();
689                AudioOutputChannels = pEngineChannel->Channels();
690                Volume              = pEngineChannel->Volume();
691                InstrumentStatus    = pEngineChannel->InstrumentStatus();
692                InstrumentIndex     = pEngineChannel->InstrumentIndex();
693                if (InstrumentIndex != -1) {
694                    InstrumentFileName = pEngineChannel->InstrumentFileName();
695                    InstrumentName     = pEngineChannel->InstrumentName();
696                }
697                for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
698                    if (AudioRouting != "") AudioRouting += ",";
699                    AudioRouting += ToString(pEngineChannel->OutputChannel(chan));
700                }
701                Mute = pEngineChannel->GetMute();
702                Solo = pEngineChannel->GetSolo();
703                if (pEngineChannel->UsesNoMidiInstrumentMap())
704                    MidiInstrumentMap = "NONE";
705                else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
706                    MidiInstrumentMap = "DEFAULT";
707                else
708                    MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
709            }
710    
711            result.Add("ENGINE_NAME", EngineName);
712            result.Add("VOLUME", Volume);
713    
714            //Some not-so-hardcoded stuff to make GUI look good
715            result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
716            result.Add("AUDIO_OUTPUT_CHANNELS", AudioOutputChannels);
717            result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
718    
719            result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
720            result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
721            if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
722            else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
723    
724            result.Add("INSTRUMENT_FILE", InstrumentFileName);
725            result.Add("INSTRUMENT_NR", InstrumentIndex);
726            result.Add("INSTRUMENT_NAME", InstrumentName);
727            result.Add("INSTRUMENT_STATUS", InstrumentStatus);
728            result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
729            result.Add("SOLO", Solo);
730            result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
731        }
732        catch (Exception e) {
733             result.Error(e);
734        }
735        return result.Produce();
736  }  }
737    
738  /**  /**
739   * Will be called by the parser to get the amount of active voices on a   * Will be called by the parser to get the amount of active voices on a
740   * particular sampler channel.   * particular sampler channel.
741   */   */
742  String LSCPServer::GetVoiceCount(uint SamplerChannel) {  String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
743      dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", SamplerChannel));      dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
744      return ToString(pEngine->ActiveVoiceCount) + "\r\n";      LSCPResultSet result;
745        try {
746            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
747            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
748            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
749            if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");
750            if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
751            result.Add(pEngineChannel->GetEngine()->VoiceCount());
752        }
753        catch (Exception e) {
754             result.Error(e);
755        }
756        return result.Produce();
757  }  }
758    
759  /**  /**
760   * Will be called by the parser to get the amount of active disk streams on a   * Will be called by the parser to get the amount of active disk streams on a
761   * particular sampler channel.   * particular sampler channel.
762   */   */
763  String LSCPServer::GetStreamCount(uint SamplerChannel) {  String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
764      dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", SamplerChannel));      dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
765      return ToString(pEngine->pDiskThread->ActiveStreamCount) + "\r\n";      LSCPResultSet result;
766        try {
767            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
768            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
769            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
770            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
771            if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
772            result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
773        }
774        catch (Exception e) {
775             result.Error(e);
776        }
777        return result.Produce();
778  }  }
779    
780  /**  /**
781   * Will be called by the parser to get the buffer fill states of all disk   * Will be called by the parser to get the buffer fill states of all disk
782   * streams on a particular sampler channel.   * streams on a particular sampler channel.
783   */   */
784  String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint SamplerChannel) {  String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
785      dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, SamplerChannel));      dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
786      return (ResponseType == fill_response_bytes) ? pEngine->pDiskThread->GetBufferFillBytes() + "\r\n"      LSCPResultSet result;
787                                                   : pEngine->pDiskThread->GetBufferFillPercentage() + "\r\n";      try {
788            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
789            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
790            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
791            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
792            if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
793            if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
794            else {
795                switch (ResponseType) {
796                    case fill_response_bytes:
797                        result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillBytes());
798                        break;
799                    case fill_response_percentage:
800                        result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
801                        break;
802                    default:
803                        throw Exception("Unknown fill response type");
804                }
805            }
806        }
807        catch (Exception e) {
808             result.Error(e);
809        }
810        return result.Produce();
811  }  }
812    
813  /**  String LSCPServer::GetAvailableAudioOutputDrivers() {
814   * Will be called by the parser to change the audio output type on a      dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
815   * particular sampler channel.      LSCPResultSet result;
816   */      try {
817  String LSCPServer::SetAudioOutputType(audio_output_type_t AudioOutputType, uint SamplerChannel) {          int n = AudioOutputDeviceFactory::AvailableDrivers().size();
818      dmsg(2,("LSCPServer: SetAudioOutputType(AudioOutputType=%d, SamplerChannel=%d)\n", AudioOutputType, SamplerChannel));          result.Add(n);
819      return "ERR:0:Not implemented yet.\r\n";      }
820        catch (Exception e) {
821            result.Error(e);
822        }
823        return result.Produce();
824    }
825    
826    String LSCPServer::ListAvailableAudioOutputDrivers() {
827        dmsg(2,("LSCPServer: ListAvailableAudioOutputDrivers()\n"));
828        LSCPResultSet result;
829        try {
830            String s = AudioOutputDeviceFactory::AvailableDriversAsString();
831            result.Add(s);
832        }
833        catch (Exception e) {
834            result.Error(e);
835        }
836        return result.Produce();
837    }
838    
839    String LSCPServer::GetAvailableMidiInputDrivers() {
840        dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
841        LSCPResultSet result;
842        try {
843            int n = MidiInputDeviceFactory::AvailableDrivers().size();
844            result.Add(n);
845        }
846        catch (Exception e) {
847            result.Error(e);
848        }
849        return result.Produce();
850    }
851    
852    String LSCPServer::ListAvailableMidiInputDrivers() {
853        dmsg(2,("LSCPServer: ListAvailableMidiInputDrivers()\n"));
854        LSCPResultSet result;
855        try {
856            String s = MidiInputDeviceFactory::AvailableDriversAsString();
857            result.Add(s);
858        }
859        catch (Exception e) {
860            result.Error(e);
861        }
862        return result.Produce();
863    }
864    
865    String LSCPServer::GetMidiInputDriverInfo(String Driver) {
866        dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
867        LSCPResultSet result;
868        try {
869            result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
870            result.Add("VERSION",     MidiInputDeviceFactory::GetDriverVersion(Driver));
871    
872            std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
873            if (parameters.size()) { // if there are parameters defined for this driver
874                String s;
875                std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
876                for (;iter != parameters.end(); iter++) {
877                    if (s != "") s += ",";
878                    s += iter->first;
879                }
880                result.Add("PARAMETERS", s);
881            }
882        }
883        catch (Exception e) {
884            result.Error(e);
885        }
886        return result.Produce();
887    }
888    
889    String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
890        dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
891        LSCPResultSet result;
892        try {
893            result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
894            result.Add("VERSION",     AudioOutputDeviceFactory::GetDriverVersion(Driver));
895    
896            std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
897            if (parameters.size()) { // if there are parameters defined for this driver
898                String s;
899                std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
900                for (;iter != parameters.end(); iter++) {
901                    if (s != "") s += ",";
902                    s += iter->first;
903                }
904                result.Add("PARAMETERS", s);
905            }
906        }
907        catch (Exception e) {
908            result.Error(e);
909        }
910        return result.Produce();
911    }
912    
913    String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
914        dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
915        LSCPResultSet result;
916        try {
917            DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
918            result.Add("TYPE",         pParameter->Type());
919            result.Add("DESCRIPTION",  pParameter->Description());
920            result.Add("MANDATORY",    pParameter->Mandatory());
921            result.Add("FIX",          pParameter->Fix());
922            result.Add("MULTIPLICITY", pParameter->Multiplicity());
923            optional<String> oDepends       = pParameter->Depends();
924            optional<String> oDefault       = pParameter->Default(DependencyList);
925            optional<String> oRangeMin      = pParameter->RangeMin(DependencyList);
926            optional<String> oRangeMax      = pParameter->RangeMax(DependencyList);
927            optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
928            if (oDepends)       result.Add("DEPENDS",       *oDepends);
929            if (oDefault)       result.Add("DEFAULT",       *oDefault);
930            if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);
931            if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
932            if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
933        }
934        catch (Exception e) {
935            result.Error(e);
936        }
937        return result.Produce();
938    }
939    
940    String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
941        dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
942        LSCPResultSet result;
943        try {
944            DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
945            result.Add("TYPE",         pParameter->Type());
946            result.Add("DESCRIPTION",  pParameter->Description());
947            result.Add("MANDATORY",    pParameter->Mandatory());
948            result.Add("FIX",          pParameter->Fix());
949            result.Add("MULTIPLICITY", pParameter->Multiplicity());
950            optional<String> oDepends       = pParameter->Depends();
951            optional<String> oDefault       = pParameter->Default(DependencyList);
952            optional<String> oRangeMin      = pParameter->RangeMin(DependencyList);
953            optional<String> oRangeMax      = pParameter->RangeMax(DependencyList);
954            optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
955            if (oDepends)       result.Add("DEPENDS",       *oDepends);
956            if (oDefault)       result.Add("DEFAULT",       *oDefault);
957            if (oRangeMin)      result.Add("RANGE_MIN",     *oRangeMin);
958            if (oRangeMax)      result.Add("RANGE_MAX",     *oRangeMax);
959            if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
960        }
961        catch (Exception e) {
962            result.Error(e);
963        }
964        return result.Produce();
965    }
966    
967    String LSCPServer::GetAudioOutputDeviceCount() {
968        dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
969        LSCPResultSet result;
970        try {
971            uint count = pSampler->AudioOutputDevices();
972            result.Add(count); // success
973        }
974        catch (Exception e) {
975            result.Error(e);
976        }
977        return result.Produce();
978    }
979    
980    String LSCPServer::GetMidiInputDeviceCount() {
981        dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
982        LSCPResultSet result;
983        try {
984            uint count = pSampler->MidiInputDevices();
985            result.Add(count); // success
986        }
987        catch (Exception e) {
988            result.Error(e);
989        }
990        return result.Produce();
991    }
992    
993    String LSCPServer::GetAudioOutputDevices() {
994        dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
995        LSCPResultSet result;
996        try {
997            String s;
998            std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
999            std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1000            for (; iter != devices.end(); iter++) {
1001                if (s != "") s += ",";
1002                s += ToString(iter->first);
1003            }
1004            result.Add(s);
1005        }
1006        catch (Exception e) {
1007            result.Error(e);
1008        }
1009        return result.Produce();
1010    }
1011    
1012    String LSCPServer::GetMidiInputDevices() {
1013        dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
1014        LSCPResultSet result;
1015        try {
1016            String s;
1017            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1018            std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1019            for (; iter != devices.end(); iter++) {
1020                if (s != "") s += ",";
1021                s += ToString(iter->first);
1022            }
1023            result.Add(s);
1024        }
1025        catch (Exception e) {
1026            result.Error(e);
1027        }
1028        return result.Produce();
1029    }
1030    
1031    String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
1032        dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1033        LSCPResultSet result;
1034        try {
1035            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1036            if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1037            AudioOutputDevice* pDevice = devices[DeviceIndex];
1038            result.Add("DRIVER", pDevice->Driver());
1039            std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1040            std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1041            for (; iter != parameters.end(); iter++) {
1042                result.Add(iter->first, iter->second->Value());
1043            }
1044        }
1045        catch (Exception e) {
1046            result.Error(e);
1047        }
1048        return result.Produce();
1049    }
1050    
1051    String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
1052        dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1053        LSCPResultSet result;
1054        try {
1055            std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1056            if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1057            MidiInputDevice* pDevice = devices[DeviceIndex];
1058            result.Add("DRIVER", pDevice->Driver());
1059            std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1060            std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1061            for (; iter != parameters.end(); iter++) {
1062                result.Add(iter->first, iter->second->Value());
1063            }
1064        }
1065        catch (Exception e) {
1066            result.Error(e);
1067        }
1068        return result.Produce();
1069    }
1070    String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
1071        dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
1072        LSCPResultSet result;
1073        try {
1074            // get MIDI input device
1075            std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1076            if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1077            MidiInputDevice* pDevice = devices[DeviceIndex];
1078    
1079            // get MIDI port
1080            MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1081            if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1082    
1083            // return the values of all MIDI port parameters
1084            std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1085            std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1086            for (; iter != parameters.end(); iter++) {
1087                result.Add(iter->first, iter->second->Value());
1088            }
1089        }
1090        catch (Exception e) {
1091            result.Error(e);
1092        }
1093        return result.Produce();
1094    }
1095    
1096    String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
1097        dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
1098        LSCPResultSet result;
1099        try {
1100            // get audio output device
1101            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1102            if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1103            AudioOutputDevice* pDevice = devices[DeviceId];
1104    
1105            // get audio channel
1106            AudioChannel* pChannel = pDevice->Channel(ChannelId);
1107            if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1108    
1109            // return the values of all audio channel parameters
1110            std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1111            std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1112            for (; iter != parameters.end(); iter++) {
1113                result.Add(iter->first, iter->second->Value());
1114            }
1115        }
1116        catch (Exception e) {
1117            result.Error(e);
1118        }
1119        return result.Produce();
1120    }
1121    
1122    String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
1123        dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
1124        LSCPResultSet result;
1125        try {
1126            // get MIDI input device
1127            std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1128            if (!devices.count(DeviceId)) throw Exception("There is no midi input device with index " + ToString(DeviceId) + ".");
1129            MidiInputDevice* pDevice = devices[DeviceId];
1130    
1131            // get midi port
1132            MidiInputPort* pPort = pDevice->GetPort(PortId);
1133            if (!pPort) throw Exception("Midi input device does not have port " + ToString(PortId) + ".");
1134    
1135            // get desired port parameter
1136            std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1137            if (!parameters.count(ParameterName)) throw Exception("Midi port does not provide a parameter '" + ParameterName + "'.");
1138            DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1139    
1140            // return all fields of this audio channel parameter
1141            result.Add("TYPE",         pParameter->Type());
1142            result.Add("DESCRIPTION",  pParameter->Description());
1143            result.Add("FIX",          pParameter->Fix());
1144            result.Add("MULTIPLICITY", pParameter->Multiplicity());
1145            if (pParameter->RangeMin())      result.Add("RANGE_MIN",     *pParameter->RangeMin());
1146            if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1147            if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1148        }
1149        catch (Exception e) {
1150            result.Error(e);
1151        }
1152        return result.Produce();
1153    }
1154    
1155    String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
1156        dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
1157        LSCPResultSet result;
1158        try {
1159            // get audio output device
1160            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1161            if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1162            AudioOutputDevice* pDevice = devices[DeviceId];
1163    
1164            // get audio channel
1165            AudioChannel* pChannel = pDevice->Channel(ChannelId);
1166            if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1167    
1168            // get desired audio channel parameter
1169            std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1170            if (!parameters.count(ParameterName)) throw Exception("Audio channel does not provide a parameter '" + ParameterName + "'.");
1171            DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1172    
1173            // return all fields of this audio channel parameter
1174            result.Add("TYPE",         pParameter->Type());
1175            result.Add("DESCRIPTION",  pParameter->Description());
1176            result.Add("FIX",          pParameter->Fix());
1177            result.Add("MULTIPLICITY", pParameter->Multiplicity());
1178            if (pParameter->RangeMin())      result.Add("RANGE_MIN",     *pParameter->RangeMin());
1179            if (pParameter->RangeMax())      result.Add("RANGE_MAX",     *pParameter->RangeMax());
1180            if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1181        }
1182        catch (Exception e) {
1183            result.Error(e);
1184        }
1185        return result.Produce();
1186    }
1187    
1188    String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
1189        dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
1190        LSCPResultSet result;
1191        try {
1192            // get audio output device
1193            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1194            if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1195            AudioOutputDevice* pDevice = devices[DeviceId];
1196    
1197            // get audio channel
1198            AudioChannel* pChannel = pDevice->Channel(ChannelId);
1199            if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1200    
1201            // get desired audio channel parameter
1202            std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1203            if (!parameters.count(ParamKey)) throw Exception("Audio channel does not provide a parameter '" + ParamKey + "'.");
1204            DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1205    
1206            // set new channel parameter value
1207            pParameter->SetValue(ParamVal);
1208            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1209        }
1210        catch (Exception e) {
1211            result.Error(e);
1212        }
1213        return result.Produce();
1214    }
1215    
1216    String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1217        dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1218        LSCPResultSet result;
1219        try {
1220            std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1221            if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1222            AudioOutputDevice* pDevice = devices[DeviceIndex];
1223            std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1224            if (!parameters.count(ParamKey)) throw Exception("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1225            parameters[ParamKey]->SetValue(ParamVal);
1226            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1227        }
1228        catch (Exception e) {
1229            result.Error(e);
1230        }
1231        return result.Produce();
1232    }
1233    
1234    String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1235        dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1236        LSCPResultSet result;
1237        try {
1238            std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1239            if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1240            MidiInputDevice* pDevice = devices[DeviceIndex];
1241            std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1242            if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1243            parameters[ParamKey]->SetValue(ParamVal);
1244            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1245        }
1246        catch (Exception e) {
1247            result.Error(e);
1248        }
1249        return result.Produce();
1250    }
1251    
1252    String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1253        dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1254        LSCPResultSet result;
1255        try {
1256            // get MIDI input device
1257            std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1258            if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1259            MidiInputDevice* pDevice = devices[DeviceIndex];
1260    
1261            // get MIDI port
1262            MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1263            if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1264    
1265            // set port parameter value
1266            std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1267            if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1268            parameters[ParamKey]->SetValue(ParamVal);
1269            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1270        }
1271        catch (Exception e) {
1272            result.Error(e);
1273        }
1274        return result.Produce();
1275  }  }
1276    
1277  /**  /**
1278   * Will be called by the parser to change the audio output channel for   * Will be called by the parser to change the audio output channel for
1279   * playback on a particular sampler channel.   * playback on a particular sampler channel.
1280   */   */
1281  String LSCPServer::SetAudioOutputChannel(uint AudioOutputChannel, uint SamplerChannel) {  String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1282      dmsg(2,("LSCPServer: SetAudioOutputChannel(AudioOutputChannel=%d, SamplerChannel=%d)\n", AudioOutputChannel, SamplerChannel));      dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1283      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
1284        try {
1285            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1286            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1287            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1288            if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1289            if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1290            pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1291        }
1292        catch (Exception e) {
1293             result.Error(e);
1294        }
1295        return result.Produce();
1296  }  }
1297    
1298  /**  String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1299   * Will be called by the parser to change the MIDI input port on which the      dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1300   * engine of a particular sampler channel should listen to.      LSCPResultSet result;
1301   */      LockRTNotify();
1302  String LSCPServer::SetMIDIInputPort(String MIDIInputPort, uint Samplerchannel) {      try {
1303      dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIInputPort=%s, Samplerchannel=%d)\n", MIDIInputPort.c_str(), Samplerchannel));          SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1304      return "ERR:0:Not implemented yet.\r\n";          if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1305            std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1306            if (!devices.count(AudioDeviceId)) throw Exception("There is no audio output device with index " + ToString(AudioDeviceId));
1307            AudioOutputDevice* pDevice = devices[AudioDeviceId];
1308            pSamplerChannel->SetAudioOutputDevice(pDevice);
1309        }
1310        catch (Exception e) {
1311             result.Error(e);
1312        }
1313        UnlockRTNotify();
1314        return result.Produce();
1315    }
1316    
1317    String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1318        dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1319        LSCPResultSet result;
1320        LockRTNotify();
1321        try {
1322            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1323            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1324            // Driver type name aliasing...
1325            if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1326            if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1327            // Check if there's one audio output device already created
1328            // for the intended audio driver type (AudioOutputDriver)...
1329            AudioOutputDevice *pDevice = NULL;
1330            std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1331            std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1332            for (; iter != devices.end(); iter++) {
1333                if ((iter->second)->Driver() == AudioOutputDriver) {
1334                    pDevice = iter->second;
1335                    break;
1336                }
1337            }
1338            // If it doesn't exist, create a new one with default parameters...
1339            if (pDevice == NULL) {
1340                std::map<String,String> params;
1341                pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1342            }
1343            // Must have a device...
1344            if (pDevice == NULL)
1345                throw Exception("Internal error: could not create audio output device.");
1346            // Set it as the current channel device...
1347            pSamplerChannel->SetAudioOutputDevice(pDevice);
1348        }
1349        catch (Exception e) {
1350             result.Error(e);
1351        }
1352        UnlockRTNotify();
1353        return result.Produce();
1354    }
1355    
1356    String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1357        dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1358        LSCPResultSet result;
1359        try {
1360            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1361            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1362            pSamplerChannel->SetMidiInputPort(MIDIPort);
1363        }
1364        catch (Exception e) {
1365             result.Error(e);
1366        }
1367        return result.Produce();
1368    }
1369    
1370    String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1371        dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1372        LSCPResultSet result;
1373        try {
1374            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1375            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1376            pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1377        }
1378        catch (Exception e) {
1379             result.Error(e);
1380        }
1381        return result.Produce();
1382    }
1383    
1384    String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1385        dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1386        LSCPResultSet result;
1387        try {
1388            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1389            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1390            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1391            if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1392            MidiInputDevice* pDevice = devices[MIDIDeviceId];
1393            pSamplerChannel->SetMidiInputDevice(pDevice);
1394        }
1395        catch (Exception e) {
1396             result.Error(e);
1397        }
1398        return result.Produce();
1399    }
1400    
1401    String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1402        dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1403        LSCPResultSet result;
1404        try {
1405            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1406            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1407            // Driver type name aliasing...
1408            if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1409            // Check if there's one MIDI input device already created
1410            // for the intended MIDI driver type (MidiInputDriver)...
1411            MidiInputDevice *pDevice = NULL;
1412            std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1413            std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1414            for (; iter != devices.end(); iter++) {
1415                if ((iter->second)->Driver() == MidiInputDriver) {
1416                    pDevice = iter->second;
1417                    break;
1418                }
1419            }
1420            // If it doesn't exist, create a new one with default parameters...
1421            if (pDevice == NULL) {
1422                std::map<String,String> params;
1423                pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1424                // Make it with at least one initial port.
1425                std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1426                parameters["PORTS"]->SetValue("1");
1427            }
1428            // Must have a device...
1429            if (pDevice == NULL)
1430                throw Exception("Internal error: could not create MIDI input device.");
1431            // Set it as the current channel device...
1432            pSamplerChannel->SetMidiInputDevice(pDevice);
1433        }
1434        catch (Exception e) {
1435             result.Error(e);
1436        }
1437        return result.Produce();
1438  }  }
1439    
1440  /**  /**
1441   * Will be called by the parser to change the MIDI input channel on which the   * Will be called by the parser to change the MIDI input device, port and channel on which
1442   * engine of a particular sampler channel should listen to.   * engine of a particular sampler channel should listen to.
1443   */   */
1444  String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint SamplerChannel) {  String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1445      dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n", MIDIChannel, SamplerChannel));      dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1446      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
1447        try {
1448            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1449            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1450            std::map<uint, MidiInputDevice*> devices =  pSampler->GetMidiInputDevices();
1451            if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1452            MidiInputDevice* pDevice = devices[MIDIDeviceId];
1453            pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
1454        }
1455        catch (Exception e) {
1456             result.Error(e);
1457        }
1458        return result.Produce();
1459  }  }
1460    
1461  /**  /**
1462   * Will be called by the parser to change the global volume factor on a   * Will be called by the parser to change the global volume factor on a
1463   * particular sampler channel.   * particular sampler channel.
1464   */   */
1465  String LSCPServer::SetVolume(double Volume, uint SamplerChannel) {  String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
1466      dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, SamplerChannel));      dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1467      pEngine->Volume = Volume;      LSCPResultSet result;
1468      return "OK\r\n";      try {
1469            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1470            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1471            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1472            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1473            pEngineChannel->Volume(dVolume);
1474        }
1475        catch (Exception e) {
1476             result.Error(e);
1477        }
1478        return result.Produce();
1479    }
1480    
1481    /**
1482     * Will be called by the parser to mute/unmute particular sampler channel.
1483     */
1484    String LSCPServer::SetChannelMute(bool bMute, uint uiSamplerChannel) {
1485        dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
1486        LSCPResultSet result;
1487        try {
1488            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1489            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1490    
1491            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1492            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1493    
1494            if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1495            else pEngineChannel->SetMute(1);
1496        } catch (Exception e) {
1497            result.Error(e);
1498        }
1499        return result.Produce();
1500    }
1501    
1502    /**
1503     * Will be called by the parser to solo particular sampler channel.
1504     */
1505    String LSCPServer::SetChannelSolo(bool bSolo, uint uiSamplerChannel) {
1506        dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
1507        LSCPResultSet result;
1508        try {
1509            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1510            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1511    
1512            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1513            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1514    
1515            bool oldSolo = pEngineChannel->GetSolo();
1516            bool hadSoloChannel = HasSoloChannel();
1517    
1518            pEngineChannel->SetSolo(bSolo);
1519    
1520            if(!oldSolo && bSolo) {
1521                if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
1522                if(!hadSoloChannel) MuteNonSoloChannels();
1523            }
1524    
1525            if(oldSolo && !bSolo) {
1526                if(!HasSoloChannel()) UnmuteChannels();
1527                else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
1528            }
1529        } catch (Exception e) {
1530            result.Error(e);
1531        }
1532        return result.Produce();
1533    }
1534    
1535    /**
1536     * Determines whether there is at least one solo channel in the channel list.
1537     *
1538     * @returns true if there is at least one solo channel in the channel list,
1539     * false otherwise.
1540     */
1541    bool LSCPServer::HasSoloChannel() {
1542        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1543        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1544        for (; iter != channels.end(); iter++) {
1545            EngineChannel* c = iter->second->GetEngineChannel();
1546            if(c && c->GetSolo()) return true;
1547        }
1548    
1549        return false;
1550    }
1551    
1552    /**
1553     * Mutes all unmuted non-solo channels. Notice that the channels are muted
1554     * with -1 which indicates that they are muted because of the presence
1555     * of a solo channel(s). Channels muted with -1 will be automatically unmuted
1556     * when there are no solo channels left.
1557     */
1558    void LSCPServer::MuteNonSoloChannels() {
1559        dmsg(2,("LSCPServer: MuteNonSoloChannels()\n"));
1560        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1561        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1562        for (; iter != channels.end(); iter++) {
1563            EngineChannel* c = iter->second->GetEngineChannel();
1564            if(c && !c->GetSolo() && !c->GetMute()) c->SetMute(-1);
1565        }
1566    }
1567    
1568    /**
1569     * Unmutes all channels that are muted because of the presence
1570     * of a solo channel(s).
1571     */
1572    void  LSCPServer::UnmuteChannels() {
1573        dmsg(2,("LSCPServer: UnmuteChannels()\n"));
1574        std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1575        std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1576        for (; iter != channels.end(); iter++) {
1577            EngineChannel* c = iter->second->GetEngineChannel();
1578            if(c && c->GetMute() == -1) c->SetMute(0);
1579        }
1580    }
1581    
1582    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) {
1583        dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
1584    
1585        midi_prog_index_t idx;
1586        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1587        idx.midi_bank_lsb = MidiBank & 0x7f;
1588        idx.midi_prog     = MidiProg;
1589    
1590        MidiInstrumentMapper::entry_t entry;
1591        entry.EngineName      = EngineType;
1592        entry.InstrumentFile  = InstrumentFile;
1593        entry.InstrumentIndex = InstrumentIndex;
1594        entry.LoadMode        = LoadMode;
1595        entry.Volume          = Volume;
1596        entry.Name            = Name;
1597    
1598        LSCPResultSet result;
1599        try {
1600            // PERSISTENT mapping commands might block for a long time, so in
1601            // that case we add/replace the mapping in another thread in case
1602            // the NON_MODAL argument was supplied, non persistent mappings
1603            // should return immediately, so we don't need to do that for them
1604            bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
1605            MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1606        } catch (Exception e) {
1607            result.Error(e);
1608        }
1609        return result.Produce();
1610    }
1611    
1612    String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1613        dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1614    
1615        midi_prog_index_t idx;
1616        idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1617        idx.midi_bank_lsb = MidiBank & 0x7f;
1618        idx.midi_prog     = MidiProg;
1619    
1620        LSCPResultSet result;
1621        try {
1622            MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1623        } catch (Exception e) {
1624            result.Error(e);
1625        }
1626        return result.Produce();
1627    }
1628    
1629    String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1630        dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1631        LSCPResultSet result;
1632        try {
1633            result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1634        } catch (Exception e) {
1635            result.Error(e);
1636        }
1637        return result.Produce();
1638    }
1639    
1640    
1641    String LSCPServer::GetAllMidiInstrumentMappings() {
1642        dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1643        LSCPResultSet result;
1644        std::vector<int> maps = MidiInstrumentMapper::Maps();
1645        int totalMappings = 0;
1646        for (int i = 0; i < maps.size(); i++) {
1647            try {
1648                totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1649            } catch (Exception e) { /*NOOP*/ }
1650        }
1651        result.Add(totalMappings);
1652        return result.Produce();
1653    }
1654    
1655    String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1656        dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1657        LSCPResultSet result;
1658        try {
1659            midi_prog_index_t idx;
1660            idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1661            idx.midi_bank_lsb = MidiBank & 0x7f;
1662            idx.midi_prog     = MidiProg;
1663    
1664            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1665            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1666            if (iter == mappings.end()) result.Error("there is no map entry with that index");
1667            else { // found
1668                result.Add("NAME", iter->second.Name);
1669                result.Add("ENGINE_NAME", iter->second.EngineName);
1670                result.Add("INSTRUMENT_FILE", iter->second.InstrumentFile);
1671                result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1672                String instrumentName;
1673                Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1674                if (pEngine) {
1675                    if (pEngine->GetInstrumentManager()) {
1676                        InstrumentManager::instrument_id_t instrID;
1677                        instrID.FileName = iter->second.InstrumentFile;
1678                        instrID.Index    = iter->second.InstrumentIndex;
1679                        instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
1680                    }
1681                    EngineFactory::Destroy(pEngine);
1682                }
1683                result.Add("INSTRUMENT_NAME", instrumentName);
1684                switch (iter->second.LoadMode) {
1685                    case MidiInstrumentMapper::ON_DEMAND:
1686                        result.Add("LOAD_MODE", "ON_DEMAND");
1687                        break;
1688                    case MidiInstrumentMapper::ON_DEMAND_HOLD:
1689                        result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
1690                        break;
1691                    case MidiInstrumentMapper::PERSISTENT:
1692                        result.Add("LOAD_MODE", "PERSISTENT");
1693                        break;
1694                    default:
1695                        throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
1696                }
1697                result.Add("VOLUME", iter->second.Volume);
1698            }
1699        } catch (Exception e) {
1700            result.Error(e);
1701        }
1702        return result.Produce();
1703    }
1704    
1705    String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
1706        dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
1707        LSCPResultSet result;
1708        try {
1709            String s;
1710            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1711            std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1712            for (; iter != mappings.end(); iter++) {
1713                if (s.size()) s += ",";
1714                s += "{" + ToString(MidiMapID) + ","
1715                         + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1716                         + ToString(int(iter->first.midi_prog)) + "}";
1717            }
1718            result.Add(s);
1719        } catch (Exception e) {
1720            result.Error(e);
1721        }
1722        return result.Produce();
1723    }
1724    
1725    String LSCPServer::ListAllMidiInstrumentMappings() {
1726        dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
1727        LSCPResultSet result;
1728        try {
1729            std::vector<int> maps = MidiInstrumentMapper::Maps();
1730            String s;
1731            for (int i = 0; i < maps.size(); i++) {
1732                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
1733                std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1734                for (; iter != mappings.end(); iter++) {
1735                    if (s.size()) s += ",";
1736                    s += "{" + ToString(maps[i]) + ","
1737                             + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1738                             + ToString(int(iter->first.midi_prog)) + "}";
1739                }
1740            }
1741            result.Add(s);
1742        } catch (Exception e) {
1743            result.Error(e);
1744        }
1745        return result.Produce();
1746    }
1747    
1748    String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
1749        dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
1750        LSCPResultSet result;
1751        try {
1752            MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
1753        } catch (Exception e) {
1754            result.Error(e);
1755        }
1756        return result.Produce();
1757    }
1758    
1759    String LSCPServer::ClearAllMidiInstrumentMappings() {
1760        dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
1761        LSCPResultSet result;
1762        try {
1763            std::vector<int> maps = MidiInstrumentMapper::Maps();
1764            for (int i = 0; i < maps.size(); i++)
1765                MidiInstrumentMapper::RemoveAllEntries(maps[i]);
1766        } catch (Exception e) {
1767            result.Error(e);
1768        }
1769        return result.Produce();
1770    }
1771    
1772    String LSCPServer::AddMidiInstrumentMap(String MapName) {
1773        dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
1774        LSCPResultSet result;
1775        try {
1776            int MapID = MidiInstrumentMapper::AddMap(MapName);
1777            result = LSCPResultSet(MapID);
1778        } catch (Exception e) {
1779            result.Error(e);
1780        }
1781        return result.Produce();
1782    }
1783    
1784    String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
1785        dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
1786        LSCPResultSet result;
1787        try {
1788            MidiInstrumentMapper::RemoveMap(MidiMapID);
1789        } catch (Exception e) {
1790            result.Error(e);
1791        }
1792        return result.Produce();
1793    }
1794    
1795    String LSCPServer::RemoveAllMidiInstrumentMaps() {
1796        dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
1797        LSCPResultSet result;
1798        try {
1799            MidiInstrumentMapper::RemoveAllMaps();
1800        } catch (Exception e) {
1801            result.Error(e);
1802        }
1803        return result.Produce();
1804    }
1805    
1806    String LSCPServer::GetMidiInstrumentMaps() {
1807        dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
1808        LSCPResultSet result;
1809        try {
1810            result.Add(MidiInstrumentMapper::Maps().size());
1811        } catch (Exception e) {
1812            result.Error(e);
1813        }
1814        return result.Produce();
1815    }
1816    
1817    String LSCPServer::ListMidiInstrumentMaps() {
1818        dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
1819        LSCPResultSet result;
1820        try {
1821            std::vector<int> maps = MidiInstrumentMapper::Maps();
1822            String sList;
1823            for (int i = 0; i < maps.size(); i++) {
1824                if (sList != "") sList += ",";
1825                sList += ToString(maps[i]);
1826            }
1827            result.Add(sList);
1828        } catch (Exception e) {
1829            result.Error(e);
1830        }
1831        return result.Produce();
1832    }
1833    
1834    String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
1835        dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
1836        LSCPResultSet result;
1837        try {
1838            result.Add("NAME", MidiInstrumentMapper::MapName(MidiMapID));
1839        } catch (Exception e) {
1840            result.Error(e);
1841        }
1842        return result.Produce();
1843    }
1844    
1845    String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
1846        dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
1847        LSCPResultSet result;
1848        try {
1849            MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
1850        } catch (Exception e) {
1851            result.Error(e);
1852        }
1853        return result.Produce();
1854    }
1855    
1856    /**
1857     * Set the MIDI instrument map the given sampler channel shall use for
1858     * handling MIDI program change messages. There are the following two
1859     * special (negative) values:
1860     *
1861     *    - (-1) :  set to NONE (ignore program changes)
1862     *    - (-2) :  set to DEFAULT map
1863     */
1864    String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
1865        dmsg(2,("LSCPServer: SetChannelMap()\n"));
1866        LSCPResultSet result;
1867        try {
1868            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1869            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1870    
1871            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1872            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1873    
1874            if      (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
1875            else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
1876            else                      pEngineChannel->SetMidiInstrumentMap(MidiMapID);
1877        } catch (Exception e) {
1878            result.Error(e);
1879        }
1880        return result.Produce();
1881    }
1882    
1883    String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
1884        dmsg(2,("LSCPServer: CreateFxSend()\n"));
1885        LSCPResultSet result;
1886        try {
1887            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1888            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1889    
1890            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1891            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1892    
1893            FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
1894            if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
1895    
1896            result = LSCPResultSet(pFxSend->Id()); // success
1897        } catch (Exception e) {
1898            result.Error(e);
1899        }
1900        return result.Produce();
1901    }
1902    
1903    String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
1904        dmsg(2,("LSCPServer: DestroyFxSend()\n"));
1905        LSCPResultSet result;
1906        try {
1907            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1908            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1909    
1910            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1911            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1912    
1913            FxSend* pFxSend = NULL;
1914            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1915                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1916                    pFxSend = pEngineChannel->GetFxSend(i);
1917                    break;
1918                }
1919            }
1920            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1921            pEngineChannel->RemoveFxSend(pFxSend);
1922        } catch (Exception e) {
1923            result.Error(e);
1924        }
1925        return result.Produce();
1926    }
1927    
1928    String LSCPServer::GetFxSends(uint uiSamplerChannel) {
1929        dmsg(2,("LSCPServer: GetFxSends()\n"));
1930        LSCPResultSet result;
1931        try {
1932            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1933            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1934    
1935            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1936            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1937    
1938            result.Add(pEngineChannel->GetFxSendCount());
1939        } catch (Exception e) {
1940            result.Error(e);
1941        }
1942        return result.Produce();
1943    }
1944    
1945    String LSCPServer::ListFxSends(uint uiSamplerChannel) {
1946        dmsg(2,("LSCPServer: ListFxSends()\n"));
1947        LSCPResultSet result;
1948        String list;
1949        try {
1950            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1951            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1952    
1953            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1954            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1955    
1956            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1957                FxSend* pFxSend = pEngineChannel->GetFxSend(i);
1958                if (list != "") list += ",";
1959                list += ToString(pFxSend->Id());
1960            }
1961            result.Add(list);
1962        } catch (Exception e) {
1963            result.Error(e);
1964        }
1965        return result.Produce();
1966    }
1967    
1968    String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
1969        dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
1970        LSCPResultSet result;
1971        try {
1972            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1973            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1974    
1975            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1976            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1977    
1978            FxSend* pFxSend = NULL;
1979            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1980                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1981                    pFxSend = pEngineChannel->GetFxSend(i);
1982                    break;
1983                }
1984            }
1985            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1986    
1987            // gather audio routing informations
1988            String AudioRouting;
1989            for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
1990                if (AudioRouting != "") AudioRouting += ",";
1991                AudioRouting += ToString(pFxSend->DestinationChannel(chan));
1992            }
1993    
1994            // success
1995            result.Add("NAME", pFxSend->Name());
1996            result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
1997            result.Add("LEVEL", ToString(pFxSend->Level()));
1998            result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
1999        } catch (Exception e) {
2000            result.Error(e);
2001        }
2002        return result.Produce();
2003    }
2004    
2005    String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
2006        dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
2007        LSCPResultSet result;
2008        try {
2009            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2010            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2011    
2012            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2013            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2014    
2015            FxSend* pFxSend = NULL;
2016            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2017                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2018                    pFxSend = pEngineChannel->GetFxSend(i);
2019                    break;
2020                }
2021            }
2022            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2023    
2024            pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2025            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2026        } catch (Exception e) {
2027            result.Error(e);
2028        }
2029        return result.Produce();
2030    }
2031    
2032    String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2033        dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2034        LSCPResultSet result;
2035        try {
2036            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2037            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2038    
2039            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2040            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2041    
2042            FxSend* pFxSend = NULL;
2043            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2044                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2045                    pFxSend = pEngineChannel->GetFxSend(i);
2046                    break;
2047                }
2048            }
2049            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2050    
2051            pFxSend->SetMidiController(MidiController);
2052            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2053        } catch (Exception e) {
2054            result.Error(e);
2055        }
2056        return result.Produce();
2057    }
2058    
2059    String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2060        dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2061        LSCPResultSet result;
2062        try {
2063            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2064            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2065    
2066            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2067            if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2068    
2069            FxSend* pFxSend = NULL;
2070            for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2071                if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2072                    pFxSend = pEngineChannel->GetFxSend(i);
2073                    break;
2074                }
2075            }
2076            if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2077    
2078            pFxSend->SetLevel((float)dLevel);
2079            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2080        } catch (Exception e) {
2081            result.Error(e);
2082        }
2083        return result.Produce();
2084  }  }
2085    
2086  /**  /**
2087   * Will be called by the parser to reset a particular sampler channel.   * Will be called by the parser to reset a particular sampler channel.
2088   */   */
2089  String LSCPServer::ResetChannel(uint SamplerChannel) {  String LSCPServer::ResetChannel(uint uiSamplerChannel) {
2090      dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", SamplerChannel));      dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2091      pEngine->Reset();      LSCPResultSet result;
2092      return "OK\r\n";      try {
2093            SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2094            if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2095            EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2096            if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2097            pEngineChannel->Reset();
2098        }
2099        catch (Exception e) {
2100             result.Error(e);
2101        }
2102        return result.Produce();
2103    }
2104    
2105    /**
2106     * Will be called by the parser to reset the whole sampler.
2107     */
2108    String LSCPServer::ResetSampler() {
2109        dmsg(2,("LSCPServer: ResetSampler()\n"));
2110        pSampler->Reset();
2111        LSCPResultSet result;
2112        return result.Produce();
2113    }
2114    
2115    /**
2116     * Will be called by the parser to return general informations about this
2117     * sampler.
2118     */
2119    String LSCPServer::GetServerInfo() {
2120        dmsg(2,("LSCPServer: GetServerInfo()\n"));
2121        LSCPResultSet result;
2122        result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2123        result.Add("VERSION", VERSION);
2124        result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2125        return result.Produce();
2126    }
2127    
2128    /**
2129     * Will be called by the parser to return the current number of all active voices.
2130     */
2131    String LSCPServer::GetTotalVoiceCount() {
2132        dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2133        LSCPResultSet result;
2134        result.Add(pSampler->GetVoiceCount());
2135        return result.Produce();
2136    }
2137    
2138    /**
2139     * Will be called by the parser to return the maximum number of voices.
2140     */
2141    String LSCPServer::GetTotalVoiceCountMax() {
2142        dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2143        LSCPResultSet result;
2144        result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2145        return result.Produce();
2146    }
2147    
2148    String LSCPServer::GetGlobalVolume() {
2149        LSCPResultSet result;
2150        result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2151        return result.Produce();
2152    }
2153    
2154    String LSCPServer::SetGlobalVolume(double dVolume) {
2155        LSCPResultSet result;
2156        try {
2157            if (dVolume < 0) throw Exception("Volume may not be negative");
2158            GLOBAL_VOLUME = dVolume; // see common/global.cpp
2159            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
2160        } catch (Exception e) {
2161            result.Error(e);
2162        }
2163        return result.Produce();
2164  }  }
2165    
2166  /**  /**
2167   * 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
2168   * server for receiving event messages.   * server for receiving event messages.
2169   */   */
2170  String LSCPServer::SubscribeNotification(uint UDPPort) {  String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
2171      dmsg(2,("LSCPServer: SubscribeNotification(UDPPort=%d)\n", UDPPort));      dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2172      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
2173        SubscriptionMutex.Lock();
2174        eventSubscriptions[type].push_back(currentSocket);
2175        SubscriptionMutex.Unlock();
2176        return result.Produce();
2177  }  }
2178    
2179  /**  /**
2180   * Will be called by the parser to unsubscribe a client on the server   * Will be called by the parser to unsubscribe a client on the server
2181   * for not receiving further event messages.   * for not receiving further event messages.
2182   */   */
2183  String LSCPServer::UnsubscribeNotification(String SessionID) {  String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
2184      dmsg(2,("LSCPServer: UnsubscribeNotification(SessionID=%s)\n", SessionID.c_str()));      dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2185      return "ERR:0:Not implemented yet.\r\n";      LSCPResultSet result;
2186        SubscriptionMutex.Lock();
2187        eventSubscriptions[type].remove(currentSocket);
2188        SubscriptionMutex.Unlock();
2189        return result.Produce();
2190    }
2191    
2192    static int select_callback(void * lscpResultSet, int argc,
2193                            char **argv, char **azColName)
2194    {
2195        LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;
2196        resultSet->Add(argc, argv);
2197        return 0;
2198    }
2199    
2200    String LSCPServer::QueryDatabase(String query) {
2201        LSCPResultSet result;
2202    #if HAVE_SQLITE3
2203        char* zErrMsg = NULL;
2204        sqlite3 *db;
2205        String selectStr = "SELECT " + query;
2206    
2207        int rc = sqlite3_open("linuxsampler.db", &db);
2208        if (rc == SQLITE_OK)
2209        {
2210                rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);
2211        }
2212        if ( rc != SQLITE_OK )
2213        {
2214                result.Error(String(zErrMsg), rc);
2215        }
2216        sqlite3_close(db);
2217    #else
2218        result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);
2219    #endif
2220        return result.Produce();
2221    }
2222    
2223    /**
2224     * Will be called by the parser to enable or disable echo mode; if echo
2225     * mode is enabled, all commands from the client will (immediately) be
2226     * echoed back to the client.
2227     */
2228    String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
2229        dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
2230        LSCPResultSet result;
2231        try {
2232            if      (boolean_value == 0) pSession->bVerbose = false;
2233            else if (boolean_value == 1) pSession->bVerbose = true;
2234            else throw Exception("Not a boolean value, must either be 0 or 1");
2235        }
2236        catch (Exception e) {
2237             result.Error(e);
2238        }
2239        return result.Produce();
2240  }  }

Legend:
Removed from v.35  
changed lines
  Added in v.1108

  ViewVC Help
Powered by ViewVC