/[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 374 - (show annotations) (download)
Sat Feb 12 00:36:08 2005 UTC (19 years, 2 months ago) by schoenebeck
File size: 60997 byte(s)
* JACK audio driver: added device creation parameter 'NAME' which can be
  used to assign an arbitrary name to the JACK client, it's now possible to
  create multiple JACK audio output devices simultaniously for LS
* src/network/lscpserver.cpp: fixed little bug in
  'SET CHANNEL AUDIO_OUTPUT_CHANNEL' (altering of audio routing)
  implementation, cleanup of error messages

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

  ViewVC Help
Powered by ViewVC