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

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

  ViewVC Help
Powered by ViewVC