/[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 1108 - (hide annotations) (download)
Thu Mar 22 20:39:04 2007 UTC (17 years ago) by iliev
File size: 91843 byte(s)
* Added new notification events for tracking
effect send changes and global volume changes

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

  ViewVC Help
Powered by ViewVC