/[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 1007 - (show annotations) (download)
Tue Jan 2 15:37:01 2007 UTC (17 years, 2 months ago) by schoenebeck
File size: 88263 byte(s)
* bugfix: LSCP command "LIST MIDI_INSTRUMENTS" returned wrong bank number

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005, 2006 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) {
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 bloock for a long time, so in
1589 // that case we add/replace the mapping in another thread
1590 bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT);
1591 MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1592 } catch (Exception e) {
1593 result.Error(e);
1594 }
1595 return result.Produce();
1596 }
1597
1598 String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1599 dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1600
1601 midi_prog_index_t idx;
1602 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1603 idx.midi_bank_lsb = MidiBank & 0x7f;
1604 idx.midi_prog = MidiProg;
1605
1606 LSCPResultSet result;
1607 try {
1608 MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1609 } catch (Exception e) {
1610 result.Error(e);
1611 }
1612 return result.Produce();
1613 }
1614
1615 String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1616 dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1617 LSCPResultSet result;
1618 try {
1619 result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1620 } catch (Exception e) {
1621 result.Error(e);
1622 }
1623 return result.Produce();
1624 }
1625
1626
1627 String LSCPServer::GetAllMidiInstrumentMappings() {
1628 dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1629 LSCPResultSet result;
1630 std::vector<int> maps = MidiInstrumentMapper::Maps();
1631 int totalMappings = 0;
1632 for (int i = 0; i < maps.size(); i++) {
1633 try {
1634 totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1635 } catch (Exception e) { /*NOOP*/ }
1636 }
1637 result.Add(totalMappings);
1638 return result.Produce();
1639 }
1640
1641 String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1642 dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1643 LSCPResultSet result;
1644 try {
1645 midi_prog_index_t idx;
1646 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1647 idx.midi_bank_lsb = MidiBank & 0x7f;
1648 idx.midi_prog = MidiProg;
1649
1650 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1651 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1652 if (iter == mappings.end()) result.Error("there is no map entry with that index");
1653 else { // found
1654 result.Add("NAME", iter->second.Name);
1655 result.Add("ENGINE_NAME", iter->second.EngineName);
1656 result.Add("INSTRUMENT_FILE", iter->second.InstrumentFile);
1657 result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1658 String instrumentName;
1659 Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1660 if (pEngine) {
1661 if (pEngine->GetInstrumentManager()) {
1662 InstrumentManager::instrument_id_t instrID;
1663 instrID.FileName = iter->second.InstrumentFile;
1664 instrID.Index = iter->second.InstrumentIndex;
1665 instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
1666 }
1667 EngineFactory::Destroy(pEngine);
1668 }
1669 result.Add("INSTRUMENT_NAME", instrumentName);
1670 switch (iter->second.LoadMode) {
1671 case MidiInstrumentMapper::ON_DEMAND:
1672 result.Add("LOAD_MODE", "ON_DEMAND");
1673 break;
1674 case MidiInstrumentMapper::ON_DEMAND_HOLD:
1675 result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
1676 break;
1677 case MidiInstrumentMapper::PERSISTENT:
1678 result.Add("LOAD_MODE", "PERSISTENT");
1679 break;
1680 default:
1681 throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
1682 }
1683 result.Add("VOLUME", iter->second.Volume);
1684 }
1685 } catch (Exception e) {
1686 result.Error(e);
1687 }
1688 return result.Produce();
1689 }
1690
1691 String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
1692 dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
1693 LSCPResultSet result;
1694 try {
1695 String s;
1696 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1697 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1698 for (; iter != mappings.end(); iter++) {
1699 if (s.size()) s += ",";
1700 s += "{" + ToString(MidiMapID) + ","
1701 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1702 + ToString(int(iter->first.midi_prog)) + "}";
1703 }
1704 result.Add(s);
1705 } catch (Exception e) {
1706 result.Error(e);
1707 }
1708 return result.Produce();
1709 }
1710
1711 String LSCPServer::ListAllMidiInstrumentMappings() {
1712 dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
1713 LSCPResultSet result;
1714 try {
1715 std::vector<int> maps = MidiInstrumentMapper::Maps();
1716 String s;
1717 for (int i = 0; i < maps.size(); i++) {
1718 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
1719 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1720 for (; iter != mappings.end(); iter++) {
1721 if (s.size()) s += ",";
1722 s += "{" + ToString(maps[i]) + ","
1723 + ToString((int(iter->first.midi_bank_msb) << 7) & int(iter->first.midi_bank_lsb)) + ","
1724 + ToString(int(iter->first.midi_prog)) + "}";
1725 }
1726 }
1727 result.Add(s);
1728 } catch (Exception e) {
1729 result.Error(e);
1730 }
1731 return result.Produce();
1732 }
1733
1734 String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
1735 dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
1736 LSCPResultSet result;
1737 try {
1738 MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
1739 } catch (Exception e) {
1740 result.Error(e);
1741 }
1742 return result.Produce();
1743 }
1744
1745 String LSCPServer::ClearAllMidiInstrumentMappings() {
1746 dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
1747 LSCPResultSet result;
1748 try {
1749 std::vector<int> maps = MidiInstrumentMapper::Maps();
1750 for (int i = 0; i < maps.size(); i++)
1751 MidiInstrumentMapper::RemoveAllEntries(maps[i]);
1752 } catch (Exception e) {
1753 result.Error(e);
1754 }
1755 return result.Produce();
1756 }
1757
1758 String LSCPServer::AddMidiInstrumentMap(String MapName) {
1759 dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
1760 LSCPResultSet result;
1761 try {
1762 int MapID = MidiInstrumentMapper::AddMap(MapName);
1763 result = LSCPResultSet(MapID);
1764 } catch (Exception e) {
1765 result.Error(e);
1766 }
1767 return result.Produce();
1768 }
1769
1770 String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
1771 dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
1772 LSCPResultSet result;
1773 try {
1774 MidiInstrumentMapper::RemoveMap(MidiMapID);
1775 } catch (Exception e) {
1776 result.Error(e);
1777 }
1778 return result.Produce();
1779 }
1780
1781 String LSCPServer::RemoveAllMidiInstrumentMaps() {
1782 dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
1783 LSCPResultSet result;
1784 try {
1785 MidiInstrumentMapper::RemoveAllMaps();
1786 } catch (Exception e) {
1787 result.Error(e);
1788 }
1789 return result.Produce();
1790 }
1791
1792 String LSCPServer::GetMidiInstrumentMaps() {
1793 dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
1794 LSCPResultSet result;
1795 try {
1796 result.Add(MidiInstrumentMapper::Maps().size());
1797 } catch (Exception e) {
1798 result.Error(e);
1799 }
1800 return result.Produce();
1801 }
1802
1803 String LSCPServer::ListMidiInstrumentMaps() {
1804 dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
1805 LSCPResultSet result;
1806 try {
1807 std::vector<int> maps = MidiInstrumentMapper::Maps();
1808 String sList;
1809 for (int i = 0; i < maps.size(); i++) {
1810 if (sList != "") sList += ",";
1811 sList += ToString(maps[i]);
1812 }
1813 result.Add(sList);
1814 } catch (Exception e) {
1815 result.Error(e);
1816 }
1817 return result.Produce();
1818 }
1819
1820 String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
1821 dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
1822 LSCPResultSet result;
1823 try {
1824 result.Add("NAME", MidiInstrumentMapper::MapName(MidiMapID));
1825 } catch (Exception e) {
1826 result.Error(e);
1827 }
1828 return result.Produce();
1829 }
1830
1831 String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
1832 dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
1833 LSCPResultSet result;
1834 try {
1835 MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
1836 } catch (Exception e) {
1837 result.Error(e);
1838 }
1839 return result.Produce();
1840 }
1841
1842 /**
1843 * Set the MIDI instrument map the given sampler channel shall use for
1844 * handling MIDI program change messages. There are the following two
1845 * special (negative) values:
1846 *
1847 * - (-1) : set to NONE (ignore program changes)
1848 * - (-2) : set to DEFAULT map
1849 */
1850 String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
1851 dmsg(2,("LSCPServer: SetChannelMap()\n"));
1852 LSCPResultSet result;
1853 try {
1854 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1855 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1856
1857 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1858 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1859
1860 if (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
1861 else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
1862 else pEngineChannel->SetMidiInstrumentMap(MidiMapID);
1863 } catch (Exception e) {
1864 result.Error(e);
1865 }
1866 return result.Produce();
1867 }
1868
1869 String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
1870 dmsg(2,("LSCPServer: CreateFxSend()\n"));
1871 LSCPResultSet result;
1872 try {
1873 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1874 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1875
1876 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1877 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1878
1879 FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
1880 if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
1881
1882 result = LSCPResultSet(pFxSend->Id()); // success
1883 } catch (Exception e) {
1884 result.Error(e);
1885 }
1886 return result.Produce();
1887 }
1888
1889 String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
1890 dmsg(2,("LSCPServer: DestroyFxSend()\n"));
1891 LSCPResultSet result;
1892 try {
1893 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1894 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1895
1896 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1897 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1898
1899 FxSend* pFxSend = NULL;
1900 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1901 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1902 pFxSend = pEngineChannel->GetFxSend(i);
1903 break;
1904 }
1905 }
1906 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1907 pEngineChannel->RemoveFxSend(pFxSend);
1908 } catch (Exception e) {
1909 result.Error(e);
1910 }
1911 return result.Produce();
1912 }
1913
1914 String LSCPServer::GetFxSends(uint uiSamplerChannel) {
1915 dmsg(2,("LSCPServer: GetFxSends()\n"));
1916 LSCPResultSet result;
1917 try {
1918 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1919 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1920
1921 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1922 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1923
1924 result.Add(pEngineChannel->GetFxSendCount());
1925 } catch (Exception e) {
1926 result.Error(e);
1927 }
1928 return result.Produce();
1929 }
1930
1931 String LSCPServer::ListFxSends(uint uiSamplerChannel) {
1932 dmsg(2,("LSCPServer: ListFxSends()\n"));
1933 LSCPResultSet result;
1934 String list;
1935 try {
1936 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1937 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1938
1939 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1940 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1941
1942 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1943 FxSend* pFxSend = pEngineChannel->GetFxSend(i);
1944 if (list != "") list += ",";
1945 list += ToString(pFxSend->Id());
1946 }
1947 result.Add(list);
1948 } catch (Exception e) {
1949 result.Error(e);
1950 }
1951 return result.Produce();
1952 }
1953
1954 String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
1955 dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
1956 LSCPResultSet result;
1957 try {
1958 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1959 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1960
1961 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1962 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1963
1964 FxSend* pFxSend = NULL;
1965 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1966 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1967 pFxSend = pEngineChannel->GetFxSend(i);
1968 break;
1969 }
1970 }
1971 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1972
1973 // gather audio routing informations
1974 String AudioRouting;
1975 for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
1976 if (AudioRouting != "") AudioRouting += ",";
1977 AudioRouting += ToString(pFxSend->DestinationChannel(chan));
1978 }
1979
1980 // success
1981 result.Add("NAME", pFxSend->Name());
1982 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
1983 } catch (Exception e) {
1984 result.Error(e);
1985 }
1986 return result.Produce();
1987 }
1988
1989 String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
1990 dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
1991 LSCPResultSet result;
1992 try {
1993 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1994 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1995
1996 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1997 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1998
1999 FxSend* pFxSend = NULL;
2000 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2001 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2002 pFxSend = pEngineChannel->GetFxSend(i);
2003 break;
2004 }
2005 }
2006 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2007
2008 pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2009 } catch (Exception e) {
2010 result.Error(e);
2011 }
2012 return result.Produce();
2013 }
2014
2015 /**
2016 * Will be called by the parser to reset a particular sampler channel.
2017 */
2018 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
2019 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2020 LSCPResultSet result;
2021 try {
2022 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2023 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2024 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2025 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2026 pEngineChannel->Reset();
2027 }
2028 catch (Exception e) {
2029 result.Error(e);
2030 }
2031 return result.Produce();
2032 }
2033
2034 /**
2035 * Will be called by the parser to reset the whole sampler.
2036 */
2037 String LSCPServer::ResetSampler() {
2038 dmsg(2,("LSCPServer: ResetSampler()\n"));
2039 pSampler->Reset();
2040 LSCPResultSet result;
2041 return result.Produce();
2042 }
2043
2044 /**
2045 * Will be called by the parser to return general informations about this
2046 * sampler.
2047 */
2048 String LSCPServer::GetServerInfo() {
2049 dmsg(2,("LSCPServer: GetServerInfo()\n"));
2050 LSCPResultSet result;
2051 result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2052 result.Add("VERSION", VERSION);
2053 result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2054 return result.Produce();
2055 }
2056
2057 /**
2058 * Will be called by the parser to return the current number of all active voices.
2059 */
2060 String LSCPServer::GetTotalVoiceCount() {
2061 dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2062 LSCPResultSet result;
2063 result.Add(pSampler->GetVoiceCount());
2064 return result.Produce();
2065 }
2066
2067 /**
2068 * Will be called by the parser to return the maximum number of voices.
2069 */
2070 String LSCPServer::GetTotalVoiceCountMax() {
2071 dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2072 LSCPResultSet result;
2073 result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2074 return result.Produce();
2075 }
2076
2077 String LSCPServer::GetGlobalVolume() {
2078 LSCPResultSet result;
2079 result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2080 return result.Produce();
2081 }
2082
2083 String LSCPServer::SetGlobalVolume(double dVolume) {
2084 LSCPResultSet result;
2085 try {
2086 if (dVolume < 0) throw Exception("Volume may not be negative");
2087 GLOBAL_VOLUME = dVolume; // see common/global.cpp
2088 } catch (Exception e) {
2089 result.Error(e);
2090 }
2091 return result.Produce();
2092 }
2093
2094 /**
2095 * Will be called by the parser to subscribe a client (frontend) on the
2096 * server for receiving event messages.
2097 */
2098 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
2099 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2100 LSCPResultSet result;
2101 SubscriptionMutex.Lock();
2102 eventSubscriptions[type].push_back(currentSocket);
2103 SubscriptionMutex.Unlock();
2104 return result.Produce();
2105 }
2106
2107 /**
2108 * Will be called by the parser to unsubscribe a client on the server
2109 * for not receiving further event messages.
2110 */
2111 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
2112 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2113 LSCPResultSet result;
2114 SubscriptionMutex.Lock();
2115 eventSubscriptions[type].remove(currentSocket);
2116 SubscriptionMutex.Unlock();
2117 return result.Produce();
2118 }
2119
2120 static int select_callback(void * lscpResultSet, int argc,
2121 char **argv, char **azColName)
2122 {
2123 LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;
2124 resultSet->Add(argc, argv);
2125 return 0;
2126 }
2127
2128 String LSCPServer::QueryDatabase(String query) {
2129 LSCPResultSet result;
2130 #if HAVE_SQLITE3
2131 char* zErrMsg = NULL;
2132 sqlite3 *db;
2133 String selectStr = "SELECT " + query;
2134
2135 int rc = sqlite3_open("linuxsampler.db", &db);
2136 if (rc == SQLITE_OK)
2137 {
2138 rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);
2139 }
2140 if ( rc != SQLITE_OK )
2141 {
2142 result.Error(String(zErrMsg), rc);
2143 }
2144 sqlite3_close(db);
2145 #else
2146 result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);
2147 #endif
2148 return result.Produce();
2149 }
2150
2151 /**
2152 * Will be called by the parser to enable or disable echo mode; if echo
2153 * mode is enabled, all commands from the client will (immediately) be
2154 * echoed back to the client.
2155 */
2156 String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
2157 dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
2158 LSCPResultSet result;
2159 try {
2160 if (boolean_value == 0) pSession->bVerbose = false;
2161 else if (boolean_value == 1) pSession->bVerbose = true;
2162 else throw Exception("Not a boolean value, must either be 0 or 1");
2163 }
2164 catch (Exception e) {
2165 result.Error(e);
2166 }
2167 return result.Produce();
2168 }

  ViewVC Help
Powered by ViewVC