/[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 209 - (show annotations) (download)
Sun Jul 18 00:29:39 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 55329 byte(s)
* src/Sampler.cpp: changed sampler channel index allocation from consistent
channel index allocation to incrementing channel index allocation, that is
it doesn't fill channel index gaps anymore (to avoid race conditions)
* implemented "LIST CHANNELS" LSCP command

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<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 get the list of sampler channels.
458 */
459 String LSCPServer::ListChannels() {
460 dmsg(2,("LSCPServer: ListChannels()\n"));
461 String list;
462 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
463 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
464 for (; iter != channels.end(); iter++) {
465 if (list != "") list += ",";
466 list += ToString(iter->first);
467 }
468 LSCPResultSet result;
469 result.Add(list);
470 return result.Produce();
471 }
472
473 /**
474 * Will be called by the parser to add a sampler channel.
475 */
476 String LSCPServer::AddChannel() {
477 dmsg(2,("LSCPServer: AddChannel()\n"));
478 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
479 LSCPResultSet result(pSamplerChannel->Index());
480 return result.Produce();
481 }
482
483 /**
484 * Will be called by the parser to remove a sampler channel.
485 */
486 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
487 dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
488 LSCPResultSet result;
489 pSampler->RemoveSamplerChannel(uiSamplerChannel);
490 return result.Produce();
491 }
492
493 /**
494 * Will be called by the parser to get all available engines.
495 */
496 String LSCPServer::GetAvailableEngines() {
497 dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
498 LSCPResultSet result("GigEngine");
499 return result.Produce();
500 }
501
502 /**
503 * Will be called by the parser to get descriptions for a particular engine.
504 */
505 String LSCPServer::GetEngineInfo(String EngineName) {
506 dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
507 LSCPResultSet result;
508 try {
509 if ((EngineName == "GigEngine") || (EngineName == "gig")) {
510 Engine* pEngine = new LinuxSampler::gig::Engine;
511 result.Add(pEngine->Description());
512 result.Add(pEngine->Version());
513 delete pEngine;
514 }
515 else throw LinuxSamplerException("Unknown engine type");
516 }
517 catch (LinuxSamplerException e) {
518 result.Error(e);
519 }
520 return result.Produce();
521 }
522
523 /**
524 * Will be called by the parser to get informations about a particular
525 * sampler channel.
526 */
527 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
528 dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
529 LSCPResultSet result;
530 try {
531 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
532 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
533 Engine* pEngine = pSamplerChannel->GetEngine();
534
535 //Defaults values
536 String EngineName = "NONE";
537 float Volume = 0;
538 String InstrumentFileName = "NONE";
539 int InstrumentIndex = -1;
540 int InstrumentStatus = -1;
541
542 if (pEngine) {
543 EngineName = pEngine->EngineName();
544 Volume = pEngine->Volume();
545 InstrumentStatus = pEngine->InstrumentStatus();
546 InstrumentIndex = pEngine->InstrumentIndex();
547 if (InstrumentIndex != -1)
548 InstrumentFileName = pEngine->InstrumentFileName();
549 }
550
551 result.Add("ENGINE_NAME", EngineName);
552 result.Add("VOLUME", Volume);
553
554 //Some not-so-hardcoded stuff to make GUI look good
555 result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
556 result.Add("AUDIO_OUTPUT_CHANNELS", "2");
557 result.Add("AUDIO_OUTPUT_ROUTING", "0,1");
558
559 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
560 result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
561 result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
562
563 result.Add("INSTRUMENT_FILE", InstrumentFileName);
564 result.Add("INSTRUMENT_NR", InstrumentIndex);
565 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
566 }
567 catch (LinuxSamplerException e) {
568 result.Error(e);
569 }
570 return result.Produce();
571 }
572
573 /**
574 * Will be called by the parser to get the amount of active voices on a
575 * particular sampler channel.
576 */
577 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
578 dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
579 LSCPResultSet result;
580 try {
581 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
582 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
583 Engine* pEngine = pSamplerChannel->GetEngine();
584 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
585 result.Add(pEngine->VoiceCount());
586 }
587 catch (LinuxSamplerException e) {
588 result.Error(e);
589 }
590 return result.Produce();
591 }
592
593 /**
594 * Will be called by the parser to get the amount of active disk streams on a
595 * particular sampler channel.
596 */
597 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
598 dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
599 LSCPResultSet result;
600 try {
601 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
602 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
603 Engine* pEngine = pSamplerChannel->GetEngine();
604 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
605 result.Add(pEngine->DiskStreamCount());
606 }
607 catch (LinuxSamplerException e) {
608 result.Error(e);
609 }
610 return result.Produce();
611 }
612
613 /**
614 * Will be called by the parser to get the buffer fill states of all disk
615 * streams on a particular sampler channel.
616 */
617 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
618 dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
619 LSCPResultSet result;
620 try {
621 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
622 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
623 Engine* pEngine = pSamplerChannel->GetEngine();
624 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
625 if (!pEngine->DiskStreamSupported())
626 result.Add("NA");
627 else {
628 switch (ResponseType) {
629 case fill_response_bytes:
630 result.Add(pEngine->DiskStreamBufferFillBytes());
631 break;
632 case fill_response_percentage:
633 result.Add(pEngine->DiskStreamBufferFillPercentage());
634 break;
635 default:
636 throw LinuxSamplerException("Unknown fill response type");
637 }
638 }
639 }
640 catch (LinuxSamplerException e) {
641 result.Error(e);
642 }
643 return result.Produce();
644 }
645
646 String LSCPServer::GetAvailableAudioOutputDrivers() {
647 dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
648 LSCPResultSet result;
649 try {
650 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
651 result.Add(s);
652 }
653 catch (LinuxSamplerException e) {
654 result.Error(e);
655 }
656 return result.Produce();
657 }
658
659 String LSCPServer::GetAvailableMidiInputDrivers() {
660 dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
661 LSCPResultSet result;
662 try {
663 String s = MidiInputDeviceFactory::AvailableDriversAsString();
664 result.Add(s);
665 }
666 catch (LinuxSamplerException e) {
667 result.Error(e);
668 }
669 return result.Produce();
670 }
671
672 String LSCPServer::GetMidiInputDriverInfo(String Driver) {
673 dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
674 LSCPResultSet result;
675 try {
676 result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
677 result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
678
679 std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
680 if (parameters.size()) { // if there are parameters defined for this driver
681 String s;
682 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
683 for (;iter != parameters.end(); iter++) {
684 if (s != "") s += ",";
685 s += iter->first;
686 }
687 result.Add("PARAMETERS", s);
688 }
689 }
690 catch (LinuxSamplerException e) {
691 result.Error(e);
692 }
693 return result.Produce();
694 }
695
696 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
697 dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
698 LSCPResultSet result;
699 try {
700 result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
701 result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
702
703 std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
704 if (parameters.size()) { // if there are parameters defined for this driver
705 String s;
706 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
707 for (;iter != parameters.end(); iter++) {
708 if (s != "") s += ",";
709 s += iter->first;
710 }
711 result.Add("PARAMETERS", s);
712 }
713 }
714 catch (LinuxSamplerException e) {
715 result.Error(e);
716 }
717 return result.Produce();
718 }
719
720 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
721 dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s)\n",Driver.c_str(),Parameter.c_str()));
722 LSCPResultSet result;
723 try {
724 DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
725 result.Add("TYPE", pParameter->Type());
726 result.Add("DESCRIPTION", pParameter->Description());
727 result.Add("MANDATORY", pParameter->Mandatory());
728 result.Add("FIX", pParameter->Fix());
729 result.Add("MULTIPLICITY", pParameter->Multiplicity());
730 if (pParameter->Depends()) result.Add("DEPENDS", pParameter->Depends());
731 if (pParameter->Default()) result.Add("DEFAULT", pParameter->Default());
732 if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
733 if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
734 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
735 }
736 catch (LinuxSamplerException e) {
737 result.Error(e);
738 }
739 return result.Produce();
740 }
741
742 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
743 dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s)\n",Driver.c_str(),Parameter.c_str()));
744 LSCPResultSet result;
745 try {
746 DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
747 result.Add("TYPE", pParameter->Type());
748 result.Add("DESCRIPTION", pParameter->Description());
749 result.Add("MANDATORY", pParameter->Mandatory());
750 result.Add("FIX", pParameter->Fix());
751 result.Add("MULTIPLICITY", pParameter->Multiplicity());
752 if (pParameter->Depends()) result.Add("DEPENDS", pParameter->Depends());
753 if (pParameter->Default()) result.Add("DEFAULT", pParameter->Default());
754 if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
755 if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
756 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
757 }
758 catch (LinuxSamplerException e) {
759 result.Error(e);
760 }
761 return result.Produce();
762 }
763
764 String LSCPServer::GetAudioOutputDeviceCount() {
765 dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
766 LSCPResultSet result;
767 try {
768 uint count = pSampler->AudioOutputDevices();
769 result.Add(count); // success
770 }
771 catch (LinuxSamplerException e) {
772 result.Error(e);
773 }
774 return result.Produce();
775 }
776
777 String LSCPServer::GetMidiInputDeviceCount() {
778 dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
779 LSCPResultSet result;
780 try {
781 uint count = pSampler->MidiInputDevices();
782 result.Add(count); // success
783 }
784 catch (LinuxSamplerException e) {
785 result.Error(e);
786 }
787 return result.Produce();
788 }
789
790 String LSCPServer::GetAudioOutputDevices() {
791 dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
792 LSCPResultSet result;
793 try {
794 String s;
795 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
796 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
797 for (; iter != devices.end(); iter++) {
798 if (s != "") s += ",";
799 s += ToString(iter->first);
800 }
801 result.Add(s);
802 }
803 catch (LinuxSamplerException e) {
804 result.Error(e);
805 }
806 return result.Produce();
807 }
808
809 String LSCPServer::GetMidiInputDevices() {
810 dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
811 LSCPResultSet result;
812 try {
813 String s;
814 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
815 std::map<uint, MidiInputDevice*>::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::GetAudioOutputDeviceInfo(uint DeviceIndex) {
829 dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
830 LSCPResultSet result;
831 try {
832 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
833 if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
834 AudioOutputDevice* pDevice = devices[DeviceIndex];
835 result.Add("driver", pDevice->Driver());
836 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
837 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
838 for (; iter != parameters.end(); iter++) {
839 result.Add(iter->first, iter->second->Value());
840 }
841 }
842 catch (LinuxSamplerException e) {
843 result.Error(e);
844 }
845 return result.Produce();
846 }
847
848 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
849 dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
850 LSCPResultSet result;
851 try {
852 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
853 MidiInputDevice* pDevice = devices[DeviceIndex];
854 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
855 result.Add("driver", pDevice->Driver());
856 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
857 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
858 for (; iter != parameters.end(); iter++) {
859 result.Add(iter->first, iter->second->Value());
860 }
861 }
862 catch (LinuxSamplerException e) {
863 result.Error(e);
864 }
865 return result.Produce();
866 }
867 String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
868 dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
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 MidiInputDevice::MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
875 if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
876 std::map<String,DeviceCreationParameter*> parameters = pMidiInputPort->DeviceParameters();
877 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
878 for (; iter != parameters.end(); iter++) {
879 result.Add(iter->first, iter->second->Value());
880 }
881 }
882 catch (LinuxSamplerException e) {
883 result.Error(e);
884 }
885 return result.Produce();
886 }
887
888 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
889 dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
890 LSCPResultSet result;
891 try {
892 // get audio output device
893 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
894 if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
895 AudioOutputDevice* pDevice = devices[DeviceId];
896
897 // get audio channel
898 AudioChannel* pChannel = pDevice->Channel(ChannelId);
899 if (!pChannel) throw LinuxSamplerException("Audio ouotput device does not have channel " + ToString(ChannelId) + ".");
900
901 // return the values of all audio channel parameters
902 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
903 std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
904 for (; iter != parameters.end(); iter++) {
905 result.Add(iter->first, iter->second->Value());
906 }
907 }
908 catch (LinuxSamplerException e) {
909 result.Error(e);
910 }
911 return result.Produce();
912 }
913
914 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
915 dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
916 LSCPResultSet result;
917 try {
918 // get audio output device
919 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
920 if (!devices[DeviceId]) throw LinuxSamplerException("There is no midi input device with index " + ToString(DeviceId) + ".");
921 MidiInputDevice* pDevice = devices[DeviceId];
922
923 // get midi port
924 MidiInputDevice::MidiInputPort* pPort = pDevice->GetPort(PortId);
925 if (!pPort) throw LinuxSamplerException("Midi input device does not have port " + ToString(PortId) + ".");
926
927 // get desired port parameter
928 std::map<String,DeviceCreationParameter*> parameters = pPort->DeviceParameters();
929 if (!parameters[ParameterName]) throw LinuxSamplerException("Midi port does not provice a parameters '" + ParameterName + "'.");
930 DeviceCreationParameter* pParameter = parameters[ParameterName];
931
932 // return all fields of this audio channel parameter
933 result.Add("TYPE", pParameter->Type());
934 result.Add("DESCRIPTION", pParameter->Description());
935 result.Add("FIX", pParameter->Fix());
936 result.Add("MULTIPLICITY", pParameter->Multiplicity());
937 if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
938 if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
939 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
940 }
941 catch (LinuxSamplerException e) {
942 result.Error(e);
943 }
944 return result.Produce();
945 }
946
947 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
948 dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
949 LSCPResultSet result;
950 try {
951 // get audio output device
952 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
953 if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
954 AudioOutputDevice* pDevice = devices[DeviceId];
955
956 // get audio channel
957 AudioChannel* pChannel = pDevice->Channel(ChannelId);
958 if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
959
960 // get desired audio channel parameter
961 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
962 if (!parameters[ParameterName]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParameterName + "'.");
963 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
964
965 // return all fields of this audio channel parameter
966 result.Add("TYPE", pParameter->Type());
967 result.Add("DESCRIPTION", pParameter->Description());
968 result.Add("FIX", pParameter->Fix());
969 result.Add("MULTIPLICITY", pParameter->Multiplicity());
970 if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
971 if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
972 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
973 }
974 catch (LinuxSamplerException e) {
975 result.Error(e);
976 }
977 return result.Produce();
978 }
979
980 String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
981 dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
982 LSCPResultSet result;
983 try {
984 // get audio output device
985 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
986 if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
987 AudioOutputDevice* pDevice = devices[DeviceId];
988
989 // get audio channel
990 AudioChannel* pChannel = pDevice->Channel(ChannelId);
991 if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
992
993 // get desired audio channel parameter
994 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
995 if (!parameters[ParamKey]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParamKey + "'.");
996 DeviceRuntimeParameter* pParameter = parameters[ParamKey];
997
998 // set new channel parameter value
999 pParameter->SetValue(ParamVal);
1000 }
1001 catch (LinuxSamplerException e) {
1002 result.Error(e);
1003 }
1004 return result.Produce();
1005 }
1006
1007 String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1008 dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1009 LSCPResultSet result;
1010 try {
1011 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1012 if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1013 AudioOutputDevice* pDevice = devices[DeviceIndex];
1014 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1015 if (!parameters[ParamKey]) throw LinuxSamplerException("Audio output 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::SetMidiInputDeviceParameter(uint DeviceIndex, 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 if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1030 MidiInputDevice* pDevice = devices[DeviceIndex];
1031 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1032 if (!parameters[ParamKey]) throw LinuxSamplerException("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1033 parameters[ParamKey]->SetValue(ParamVal);
1034 }
1035 catch (LinuxSamplerException e) {
1036 result.Error(e);
1037 }
1038 return result.Produce();
1039 }
1040
1041 String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1042 dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1043 LSCPResultSet result;
1044 try {
1045 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1046 MidiInputDevice* pDevice = devices[DeviceIndex];
1047 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1048 MidiInputDevice::MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1049 if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1050 std::map<String,DeviceCreationParameter*> parameters = pMidiInputPort->DeviceParameters();
1051 if (!parameters[ParamKey]) throw LinuxSamplerException("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1052 parameters[ParamKey]->SetValue(ParamVal);
1053 }
1054 catch (LinuxSamplerException e) {
1055 result.Error(e);
1056 }
1057 return result.Produce();
1058 }
1059
1060 /**
1061 * Will be called by the parser to change the audio output channel for
1062 * playback on a particular sampler channel.
1063 */
1064 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1065 dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1066 return "ERR:0:Not implemented yet.\r\n"; //FIXME: Add support for this in resultset class?
1067 }
1068
1069 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1070 dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1071 LSCPResultSet result;
1072 try {
1073 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1074 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1075 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1076 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1077 if (!pDevice) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));
1078 pSamplerChannel->SetAudioOutputDevice(pDevice);
1079 }
1080 catch (LinuxSamplerException e) {
1081 result.Error(e);
1082 }
1083 return result.Produce();
1084 }
1085
1086 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1087 dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1088 LSCPResultSet result;
1089 try {
1090 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1091 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1092 // Driver type name aliasing...
1093 if (AudioOutputDriver == "ALSA") AudioOutputDriver = "Alsa";
1094 if (AudioOutputDriver == "JACK") AudioOutputDriver = "Jack";
1095 // Check if there's one audio output device already created
1096 // for the intended audio driver type (AudioOutputDriver)...
1097 AudioOutputDevice *pDevice = NULL;
1098 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1099 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1100 for (; iter != devices.end(); iter++) {
1101 if ((iter->second)->Driver() == AudioOutputDriver) {
1102 pDevice = iter->second;
1103 break;
1104 }
1105 }
1106 // If it doesn't exist, create a new one with default parameters...
1107 if (pDevice == NULL) {
1108 std::map<String,String> params;
1109 pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1110 }
1111 // Must have a device...
1112 if (pDevice == NULL)
1113 throw LinuxSamplerException("Internal error: could not create audio output device.");
1114 // Set it as the current channel device...
1115 pSamplerChannel->SetAudioOutputDevice(pDevice);
1116 }
1117 catch (LinuxSamplerException e) {
1118 result.Error(e);
1119 }
1120 return result.Produce();
1121 }
1122
1123 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1124 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1125 LSCPResultSet result;
1126 try {
1127 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1128 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1129 pSamplerChannel->SetMidiInputPort(MIDIPort);
1130 }
1131 catch (LinuxSamplerException e) {
1132 result.Error(e);
1133 }
1134 return result.Produce();
1135 }
1136
1137 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1138 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1139 LSCPResultSet result;
1140 try {
1141 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1142 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1143 pSamplerChannel->SetMidiInputChannel((MidiInputDevice::MidiInputPort::midi_chan_t) MIDIChannel);
1144 }
1145 catch (LinuxSamplerException e) {
1146 result.Error(e);
1147 }
1148 return result.Produce();
1149 }
1150
1151 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1152 dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1153 LSCPResultSet result;
1154 try {
1155 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1156 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1157 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1158 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1159 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1160 pSamplerChannel->SetMidiInputDevice(pDevice);
1161 }
1162 catch (LinuxSamplerException e) {
1163 result.Error(e);
1164 }
1165 return result.Produce();
1166 }
1167
1168 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1169 dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1170 LSCPResultSet result;
1171 try {
1172 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1173 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1174 // Driver type name aliasing...
1175 if (MidiInputDriver == "ALSA") MidiInputDriver = "Alsa";
1176 // Check if there's one MIDI input device already created
1177 // for the intended MIDI driver type (MidiInputDriver)...
1178 MidiInputDevice *pDevice = NULL;
1179 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1180 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1181 for (; iter != devices.end(); iter++) {
1182 if ((iter->second)->Driver() == MidiInputDriver) {
1183 pDevice = iter->second;
1184 break;
1185 }
1186 }
1187 // If it doesn't exist, create a new one with default parameters...
1188 if (pDevice == NULL) {
1189 std::map<String,String> params;
1190 pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1191 // Make it with at least one initial port.
1192 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1193 parameters["ports"]->SetValue("1");
1194 }
1195 // Must have a device...
1196 if (pDevice == NULL)
1197 throw LinuxSamplerException("Internal error: could not create MIDI input device.");
1198 // Set it as the current channel device...
1199 pSamplerChannel->SetMidiInputDevice(pDevice);
1200 }
1201 catch (LinuxSamplerException e) {
1202 result.Error(e);
1203 }
1204 return result.Produce();
1205 }
1206
1207 /**
1208 * Will be called by the parser to change the MIDI input device, port and channel on which
1209 * engine of a particular sampler channel should listen to.
1210 */
1211 String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1212 dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1213 LSCPResultSet result;
1214 try {
1215 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1216 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1217 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1218 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1219 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1220 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (MidiInputDevice::MidiInputPort::midi_chan_t) MIDIChannel);
1221 }
1222 catch (LinuxSamplerException e) {
1223 result.Error(e);
1224 }
1225 return result.Produce();
1226 }
1227
1228 /**
1229 * Will be called by the parser to change the global volume factor on a
1230 * particular sampler channel.
1231 */
1232 String LSCPServer::SetVolume(double Volume, uint uiSamplerChannel) {
1233 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, uiSamplerChannel));
1234 LSCPResultSet result;
1235 try {
1236 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1237 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
1238 Engine* pEngine = pSamplerChannel->GetEngine();
1239 if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
1240 pEngine->Volume(Volume);
1241 }
1242 catch (LinuxSamplerException e) {
1243 result.Error(e);
1244 }
1245 return result.Produce();
1246 }
1247
1248 /**
1249 * Will be called by the parser to reset a particular sampler channel.
1250 */
1251 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
1252 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", 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->Reset();
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 subscribe a client (frontend) on the
1269 * server for receiving event messages.
1270 */
1271 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
1272 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1273 LSCPResultSet result;
1274 SubscriptionMutex.Lock();
1275 eventSubscriptions[type].push_back(currentSocket);
1276 SubscriptionMutex.Unlock();
1277 return result.Produce();
1278 }
1279
1280 /**
1281 * Will be called by the parser to unsubscribe a client on the server
1282 * for not receiving further event messages.
1283 */
1284 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
1285 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1286 LSCPResultSet result;
1287 SubscriptionMutex.Lock();
1288 eventSubscriptions[type].remove(currentSocket);
1289 SubscriptionMutex.Unlock();
1290 return result.Produce();
1291 }
1292
1293
1294 // Instrument loader constructor.
1295 LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)
1296 : Thread(false, 0, -4)
1297 {
1298 this->pEngine = pEngine;
1299 this->Filename = Filename;
1300 this->uiInstrument = uiInstrument;
1301 }
1302
1303 // Instrument loader process.
1304 int LSCPLoadInstrument::Main()
1305 {
1306 try {
1307 pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
1308 }
1309
1310 catch (LinuxSamplerException e) {
1311 e.PrintMessage();
1312 }
1313
1314 // Always re-enable the engine.
1315 pEngine->Enable();
1316
1317 // FIXME: Shoot ourselves on the foot?
1318 delete this;
1319 }

  ViewVC Help
Powered by ViewVC