/[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 705 - (show annotations) (download)
Wed Jul 20 21:43:23 2005 UTC (18 years, 8 months ago) by schoenebeck
File size: 68960 byte(s)
* support for muting sampler channels and solo mode of the same, two new
  LSCP commands ("SET CHANNEL MUTE" and "SET CHANNEL SOLO") and two new
  fields ("MUTE" and "SOLO") for command "GET CHANNEL INFO" were
  introduced for this (patch by Grigor Iliev, a bit adjusted)

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

  ViewVC Help
Powered by ViewVC