/[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 211 - (show annotations) (download)
Sun Jul 25 23:27:41 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 57174 byte(s)
* src/linuxsampler.cpp: tidied up a bit, "initialization completed"
  message shown only after the server is actually running
* src/testcases/: print the name of each test suite before running the
  tests of the suite, added first tests against the LSCP server using a
  socket connection to the LSCP server (tests for the following LSCP
  commands: "ADD CHANNEL", "GET CHANNELS", "REMOVE CHANNEL")

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

  ViewVC Help
Powered by ViewVC