/[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 337 - (show annotations) (download)
Sun Jan 9 02:26:29 2005 UTC (14 years, 9 months ago) by senkov
File size: 60176 byte(s)
* Fix for a core. SET CHANNEL AUDIO_OUTPUT_CHANNEL needs
 to check if audio output device exists.

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() == MidiInputPort::midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
595 else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
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 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1127 if (!devices.count(ChannelAudioOutputChannel)) throw LinuxSamplerException("There is no audio output device with index " + ToString(ChannelAudioOutputChannel));
1128 pEngine->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1129 }
1130 catch (LinuxSamplerException e) {
1131 result.Error(e);
1132 }
1133 return result.Produce();
1134 }
1135
1136 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1137 dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1138 LSCPResultSet result;
1139 try {
1140 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1141 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1142 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1143 if (!devices.count(AudioDeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));
1144 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1145 pSamplerChannel->SetAudioOutputDevice(pDevice);
1146 }
1147 catch (LinuxSamplerException e) {
1148 result.Error(e);
1149 }
1150 return result.Produce();
1151 }
1152
1153 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1154 dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1155 LSCPResultSet result;
1156 try {
1157 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1158 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1159 // Driver type name aliasing...
1160 if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1161 if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1162 // Check if there's one audio output device already created
1163 // for the intended audio driver type (AudioOutputDriver)...
1164 AudioOutputDevice *pDevice = NULL;
1165 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1166 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1167 for (; iter != devices.end(); iter++) {
1168 if ((iter->second)->Driver() == AudioOutputDriver) {
1169 pDevice = iter->second;
1170 break;
1171 }
1172 }
1173 // If it doesn't exist, create a new one with default parameters...
1174 if (pDevice == NULL) {
1175 std::map<String,String> params;
1176 pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1177 }
1178 // Must have a device...
1179 if (pDevice == NULL)
1180 throw LinuxSamplerException("Internal error: could not create audio output device.");
1181 // Set it as the current channel device...
1182 pSamplerChannel->SetAudioOutputDevice(pDevice);
1183 }
1184 catch (LinuxSamplerException e) {
1185 result.Error(e);
1186 }
1187 return result.Produce();
1188 }
1189
1190 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1191 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1192 LSCPResultSet result;
1193 try {
1194 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1195 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1196 pSamplerChannel->SetMidiInputPort(MIDIPort);
1197 }
1198 catch (LinuxSamplerException e) {
1199 result.Error(e);
1200 }
1201 return result.Produce();
1202 }
1203
1204 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1205 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1206 LSCPResultSet result;
1207 try {
1208 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1209 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1210 pSamplerChannel->SetMidiInputChannel((MidiInputPort::midi_chan_t) MIDIChannel);
1211 }
1212 catch (LinuxSamplerException e) {
1213 result.Error(e);
1214 }
1215 return result.Produce();
1216 }
1217
1218 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1219 dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1220 LSCPResultSet result;
1221 try {
1222 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1223 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1224 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1225 if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1226 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1227 pSamplerChannel->SetMidiInputDevice(pDevice);
1228 }
1229 catch (LinuxSamplerException e) {
1230 result.Error(e);
1231 }
1232 return result.Produce();
1233 }
1234
1235 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1236 dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1237 LSCPResultSet result;
1238 try {
1239 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1240 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1241 // Driver type name aliasing...
1242 if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1243 // Check if there's one MIDI input device already created
1244 // for the intended MIDI driver type (MidiInputDriver)...
1245 MidiInputDevice *pDevice = NULL;
1246 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1247 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1248 for (; iter != devices.end(); iter++) {
1249 if ((iter->second)->Driver() == MidiInputDriver) {
1250 pDevice = iter->second;
1251 break;
1252 }
1253 }
1254 // If it doesn't exist, create a new one with default parameters...
1255 if (pDevice == NULL) {
1256 std::map<String,String> params;
1257 pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1258 // Make it with at least one initial port.
1259 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1260 parameters["PORTS"]->SetValue("1");
1261 }
1262 // Must have a device...
1263 if (pDevice == NULL)
1264 throw LinuxSamplerException("Internal error: could not create MIDI input device.");
1265 // Set it as the current channel device...
1266 pSamplerChannel->SetMidiInputDevice(pDevice);
1267 }
1268 catch (LinuxSamplerException e) {
1269 result.Error(e);
1270 }
1271 return result.Produce();
1272 }
1273
1274 /**
1275 * Will be called by the parser to change the MIDI input device, port and channel on which
1276 * engine of a particular sampler channel should listen to.
1277 */
1278 String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1279 dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1280 LSCPResultSet result;
1281 try {
1282 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1283 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1284 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1285 if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1286 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1287 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (MidiInputPort::midi_chan_t) MIDIChannel);
1288 }
1289 catch (LinuxSamplerException e) {
1290 result.Error(e);
1291 }
1292 return result.Produce();
1293 }
1294
1295 /**
1296 * Will be called by the parser to change the global volume factor on a
1297 * particular sampler channel.
1298 */
1299 String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
1300 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1301 LSCPResultSet result;
1302 try {
1303 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1304 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
1305 Engine* pEngine = pSamplerChannel->GetEngine();
1306 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
1307 pEngine->Volume(dVolume);
1308 }
1309 catch (LinuxSamplerException e) {
1310 result.Error(e);
1311 }
1312 return result.Produce();
1313 }
1314
1315 /**
1316 * Will be called by the parser to reset a particular sampler channel.
1317 */
1318 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
1319 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
1320 LSCPResultSet result;
1321 try {
1322 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1323 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
1324 Engine* pEngine = pSamplerChannel->GetEngine();
1325 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
1326 pEngine->Reset();
1327 }
1328 catch (LinuxSamplerException e) {
1329 result.Error(e);
1330 }
1331 return result.Produce();
1332 }
1333
1334 /**
1335 * Will be called by the parser to reset the whole sampler.
1336 */
1337 String LSCPServer::ResetSampler() {
1338 dmsg(2,("LSCPServer: ResetSampler()\n"));
1339 pSampler->Reset();
1340 LSCPResultSet result;
1341 return result.Produce();
1342 }
1343
1344 /**
1345 * Will be called by the parser to subscribe a client (frontend) on the
1346 * server for receiving event messages.
1347 */
1348 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
1349 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1350 LSCPResultSet result;
1351 SubscriptionMutex.Lock();
1352 eventSubscriptions[type].push_back(currentSocket);
1353 SubscriptionMutex.Unlock();
1354 return result.Produce();
1355 }
1356
1357 /**
1358 * Will be called by the parser to unsubscribe a client on the server
1359 * for not receiving further event messages.
1360 */
1361 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
1362 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1363 LSCPResultSet result;
1364 SubscriptionMutex.Lock();
1365 eventSubscriptions[type].remove(currentSocket);
1366 SubscriptionMutex.Unlock();
1367 return result.Produce();
1368 }
1369
1370 /**
1371 * Will be called by the parser to enable or disable echo mode; if echo
1372 * mode is enabled, all commands from the client will (immediately) be
1373 * echoed back to the client.
1374 */
1375 String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
1376 dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
1377 LSCPResultSet result;
1378 try {
1379 if (boolean_value == 0) pSession->bVerbose = false;
1380 else if (boolean_value == 1) pSession->bVerbose = true;
1381 else throw LinuxSamplerException("Not a boolean value, must either be 0 or 1");
1382 }
1383 catch (LinuxSamplerException e) {
1384 result.Error(e);
1385 }
1386 return result.Produce();
1387 }
1388
1389 // Instrument loader constructor.
1390 LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)
1391 : Thread(false, 0, -4)
1392 {
1393 this->pEngine = pEngine;
1394 this->Filename = Filename;
1395 this->uiInstrument = uiInstrument;
1396 }
1397
1398 // Instrument loader process.
1399 int LSCPLoadInstrument::Main()
1400 {
1401 try {
1402 pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
1403 }
1404
1405 catch (LinuxSamplerException e) {
1406 e.PrintMessage();
1407 }
1408
1409 // Always re-enable the engine.
1410 pEngine->Enable();
1411
1412 // FIXME: Shoot ourselves on the foot?
1413 delete this;
1414 }

  ViewVC Help
Powered by ViewVC