/[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 198 - (show annotations) (download)
Tue Jul 13 15:36:16 2004 UTC (19 years, 8 months ago) by senkov
File size: 54823 byte(s)
* Get rid of the timeout on select()

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

  ViewVC Help
Powered by ViewVC