/[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 219 - (show annotations) (download)
Tue Aug 17 20:35:04 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 57474 byte(s)
* completely removed the lex scanner and replaced it by pure yacc rules
  for all terminal symbols (that is command keywords and variables) to
  avoid misunderstandings while parsing (e.g. recognition of command
  keywords in string arguments)
* src/drivers/audio/AudioChannel.cpp: changed channel parameter 'Name' to
 'NAME' as defined in the LSCP documentation

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

  ViewVC Help
Powered by ViewVC