/[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 227 - (show annotations) (download)
Thu Aug 26 22:05:44 2004 UTC (19 years, 7 months ago) by schoenebeck
File size: 59926 byte(s)
* ALSA audio driver: bugfix in device parameter 'CARD' which caused an
  error message if used in conjunction with 'CREATE AUDIO_OUTPUT_DEVICE'
  LSCP command
* JACK audio driver: fixed minor JACK port name issue and the device was
  not activated by default on creation which caused it to render solely
  silence
* src/network/lscpserver.cpp: retry to bind socket for 3 minutes if bind
  failed

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

  ViewVC Help
Powered by ViewVC