/[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 411 - (show annotations) (download)
Sat Feb 26 02:01:14 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 62087 byte(s)
* design change: using now one sampler engine instance and one disk thread
  instance for all sampler channels that are connected to the same audio
  output device (and are using the same engine type of course)
* added EngineFactory / EngineChannelFactory to remove the annoying build
  dependencies e.g. of the lscpserver to the actual sampler engine
  implementations
* bumped version to 0.3.0 (current CVS state is still quite broken,
  previous, stable CVS version was tagged as "v0_2_0" and is also available
  as source tarball)

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

  ViewVC Help
Powered by ViewVC