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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1047 - (show annotations) (download)
Mon Feb 19 19:38:04 2007 UTC (17 years, 1 month ago) by schoenebeck
File size: 90702 byte(s)
* by default now all "MAP MIDI_INSTRUMENT" LSCP commands (also the
  "PERSISTENT" ones) block until the respective mapping is completely
  established in the sampler, added a new argument though to allow
  explicit mapping in the background ("MAP MIDI_INSTRUMENT NON_MODAL")
* LSCP documentation updated

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

  ViewVC Help
Powered by ViewVC