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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 973 - (hide annotations) (download)
Fri Dec 15 21:40:27 2006 UTC (17 years, 4 months ago) by schoenebeck
File size: 80636 byte(s)
* revised and extended MIDI instrument mapping feature to allow managing
  arbitrary amount of maps and assigning each sampler channel individually
  to one map (this commit batch includes LSCP spec document update and
  respective implementation on LS side)

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

  ViewVC Help
Powered by ViewVC