/[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 1130 - (show annotations) (download)
Sun Mar 25 18:59:14 2007 UTC (17 years ago) by iliev
File size: 95010 byte(s)
* Implemented new, improved notification system

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
7 * *
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "lscpserver.h"
25 #include "lscpresultset.h"
26 #include "lscpevent.h"
27 #include "../common/global.h"
28
29 #include <fcntl.h>
30
31 #if HAVE_SQLITE3
32 # include "sqlite3.h"
33 #endif
34
35 #include "../engines/EngineFactory.h"
36 #include "../engines/EngineChannelFactory.h"
37 #include "../drivers/audio/AudioOutputDeviceFactory.h"
38 #include "../drivers/midi/MidiInputDeviceFactory.h"
39
40 /**
41 * Below are a few static members of the LSCPServer class.
42 * The big assumption here is that LSCPServer is going to remain a singleton.
43 * These members are used to support client connections.
44 * Class handles multiple connections at the same time using select() and non-blocking recv()
45 * Commands are processed by a single LSCPServer thread.
46 * Notifications are delivered either by the thread that originated them
47 * or (if the resultset is currently in progress) by the LSCPServer thread
48 * after the resultset was sent out.
49 * This makes sure that resultsets can not be interrupted by notifications.
50 * This also makes sure that the thread sending notification is not blocked
51 * by the LSCPServer thread.
52 */
53 fd_set LSCPServer::fdSet;
54 int LSCPServer::currentSocket = -1;
55 std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();
56 std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();
57 std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();
58 std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();
59 Mutex LSCPServer::NotifyMutex = Mutex();
60 Mutex LSCPServer::NotifyBufferMutex = Mutex();
61 Mutex LSCPServer::SubscriptionMutex = Mutex();
62 Mutex LSCPServer::RTNotifyMutex = Mutex();
63
64 LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4) {
65 SocketAddress.sin_family = AF_INET;
66 SocketAddress.sin_addr.s_addr = addr;
67 SocketAddress.sin_port = port;
68 this->pSampler = pSampler;
69 LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
70 LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
71 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_count, "MIDI_INPUT_DEVICE_COUNT");
72 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_info, "MIDI_INPUT_DEVICE_INFO");
73 LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");
74 LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
75 LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
76 LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
77 LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");
78 LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_count, "FX_SEND_COUNT");
79 LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_info, "FX_SEND_INFO");
80 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_count, "MIDI_INSTRUMENT_MAP_COUNT");
81 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_info, "MIDI_INSTRUMENT_MAP_INFO");
82 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_count, "MIDI_INSTRUMENT_COUNT");
83 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_info, "MIDI_INSTRUMENT_INFO");
84 LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
85 LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");
86 LSCPEvent::RegisterEvent(LSCPEvent::event_global_info, "GLOBAL_INFO");
87 hSocket = -1;
88 }
89
90 LSCPServer::~LSCPServer() {
91 if (hSocket >= 0) close(hSocket);
92 }
93
94 void LSCPServer::LscpChannelCountListener::ChannelCountChanged(int NewCount) {
95 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_count, NewCount));
96 }
97
98 void LSCPServer::LscpAudioDeviceCountListener::AudioDeviceCountChanged(int NewCount) {
99 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_count, NewCount));
100 }
101
102 void LSCPServer::LscpMidiDeviceCountListener::MidiDeviceCountChanged(int NewCount) {
103 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_count, NewCount));
104 }
105
106 void LSCPServer::LscpMidiInstrumentCountListener::MidiInstrumentCountChanged(int MapId, int NewCount) {
107 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_count, MapId, NewCount));
108 }
109
110 void LSCPServer::LscpMidiInstrumentInfoListener::MidiInstrumentInfoChanged(int MapId, int Bank, int Program) {
111 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_info, MapId, Bank, Program));
112 }
113
114 void LSCPServer::LscpMidiInstrumentMapCountListener::MidiInstrumentMapCountChanged(int NewCount) {
115 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_count, NewCount));
116 }
117
118 void LSCPServer::LscpMidiInstrumentMapInfoListener::MidiInstrumentMapInfoChanged(int MapId) {
119 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_info, MapId));
120 }
121
122 void LSCPServer::LscpFxSendCountListener::FxSendCountChanged(int ChannelId, int NewCount) {
123 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_count, ChannelId, NewCount));
124 }
125
126 void LSCPServer::LscpVoiceCountListener::VoiceCountChanged(int ChannelId, int NewCount) {
127 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_voice_count, ChannelId, NewCount));
128 }
129
130 void LSCPServer::LscpStreamCountListener::StreamCountChanged(int ChannelId, int NewCount) {
131 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_stream_count, ChannelId, NewCount));
132 }
133
134 void LSCPServer::LscpBufferFillListener::BufferFillChanged(int ChannelId, String FillData) {
135 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_buffer_fill, ChannelId, FillData));
136 }
137
138 void LSCPServer::LscpTotalVoiceCountListener::TotalVoiceCountChanged(int NewCount) {
139 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_total_voice_count, NewCount));
140 }
141
142
143 /**
144 * Blocks the calling thread until the LSCP Server is initialized and
145 * accepting socket connections, if the server is already initialized then
146 * this method will return immediately.
147 * @param TimeoutSeconds - optional: max. wait time in seconds
148 * (default: 0s)
149 * @param TimeoutNanoSeconds - optional: max wait time in nano seconds
150 * (default: 0ns)
151 * @returns 0 on success, a value less than 0 if timeout exceeded
152 */
153 int LSCPServer::WaitUntilInitialized(long TimeoutSeconds, long TimeoutNanoSeconds) {
154 return Initialized.WaitAndUnlockIf(false, TimeoutSeconds, TimeoutNanoSeconds);
155 }
156
157 int LSCPServer::Main() {
158 hSocket = socket(AF_INET, SOCK_STREAM, 0);
159 if (hSocket < 0) {
160 std::cerr << "LSCPServer: Could not create server socket." << std::endl;
161 //return -1;
162 exit(EXIT_FAILURE);
163 }
164
165 if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
166 std::cerr << "LSCPServer: Could not bind server socket, retrying for " << ToString(LSCP_SERVER_BIND_TIMEOUT) << " seconds...";
167 for (int trial = 0; true; trial++) { // retry for LSCP_SERVER_BIND_TIMEOUT seconds
168 if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
169 if (trial > LSCP_SERVER_BIND_TIMEOUT) {
170 std::cerr << "gave up!" << std::endl;
171 close(hSocket);
172 //return -1;
173 exit(EXIT_FAILURE);
174 }
175 else sleep(1); // sleep 1s
176 }
177 else break; // success
178 }
179 }
180
181 listen(hSocket, 1);
182 Initialized.Set(true);
183
184 // Registering event listeners
185 pSampler->AddChannelCountListener(&channelCountListener);
186 pSampler->AddAudioDeviceCountListener(&audioDeviceCountListener);
187 pSampler->AddMidiDeviceCountListener(&midiDeviceCountListener);
188 pSampler->AddVoiceCountListener(&voiceCountListener);
189 pSampler->AddStreamCountListener(&streamCountListener);
190 pSampler->AddBufferFillListener(&bufferFillListener);
191 pSampler->AddTotalVoiceCountListener(&totalVoiceCountListener);
192 pSampler->AddFxSendCountListener(&fxSendCountListener);
193 MidiInstrumentMapper::AddMidiInstrumentCountListener(&midiInstrumentCountListener);
194 MidiInstrumentMapper::AddMidiInstrumentInfoListener(&midiInstrumentInfoListener);
195 MidiInstrumentMapper::AddMidiInstrumentMapCountListener(&midiInstrumentMapCountListener);
196 MidiInstrumentMapper::AddMidiInstrumentMapInfoListener(&midiInstrumentMapInfoListener);
197
198 // now wait for client connections and handle their requests
199 sockaddr_in client;
200 int length = sizeof(client);
201 FD_ZERO(&fdSet);
202 FD_SET(hSocket, &fdSet);
203 int maxSessions = hSocket;
204
205 timeval timeout;
206
207 while (true) {
208 // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers
209 {
210 std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
211 std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
212 std::set<EngineChannel*>::iterator itEnd = engineChannels.end();
213 for (; itEngineChannel != itEnd; ++itEngineChannel) {
214 if ((*itEngineChannel)->StatusChanged()) {
215 SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));
216 }
217
218 for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
219 FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
220 if(fxs != NULL && fxs->IsInfoChanged()) {
221 int chn = (*itEngineChannel)->iSamplerChannelIndex;
222 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));
223 fxs->SetInfoChanged(false);
224 }
225 }
226 }
227 }
228
229 //Now let's deliver late notifies (if any)
230 NotifyBufferMutex.Lock();
231 for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
232 #ifdef MSG_NOSIGNAL
233 send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), MSG_NOSIGNAL);
234 #else
235 send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
236 #endif
237 }
238 bufferedNotifies.clear();
239 NotifyBufferMutex.Unlock();
240
241 fd_set selectSet = fdSet;
242 timeout.tv_sec = 0;
243 timeout.tv_usec = 100000;
244
245 int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
246
247 if (retval == 0)
248 continue; //Nothing try again
249 if (retval == -1) {
250 std::cerr << "LSCPServer: Socket select error." << std::endl;
251 close(hSocket);
252 exit(EXIT_FAILURE);
253 }
254
255 //Accept new connections now (if any)
256 if (FD_ISSET(hSocket, &selectSet)) {
257 int socket = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
258 if (socket < 0) {
259 std::cerr << "LSCPServer: Client connection failed." << std::endl;
260 exit(EXIT_FAILURE);
261 }
262
263 if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
264 std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
265 exit(EXIT_FAILURE);
266 }
267
268 // Parser initialization
269 yyparse_param_t yyparse_param;
270 yyparse_param.pServer = this;
271 yyparse_param.hSession = socket;
272
273 Sessions.push_back(yyparse_param);
274 FD_SET(socket, &fdSet);
275 if (socket > maxSessions)
276 maxSessions = socket;
277 dmsg(1,("LSCPServer: Client connection established on socket:%d.\n", socket));
278 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection established on socket", socket));
279 continue; //Maybe this was the only selected socket, better select again
280 }
281
282 //Something was selected and it was not the hSocket, so it must be some command(s) coming.
283 for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {
284 if (FD_ISSET((*iter).hSession, &selectSet)) { //Was it this socket?
285 if (GetLSCPCommand(iter)) { //Have we read the entire command?
286 dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));
287 int dummy; // just a temporary hack to fulfill the restart() function prototype
288 restart(NULL, dummy); // restart the 'scanner'
289 currentSocket = (*iter).hSession; //a hack
290 dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
291 if ((*iter).bVerbose) { // if echo mode enabled
292 AnswerClient(bufferedCommands[currentSocket]);
293 }
294 int result = yyparse(&(*iter));
295 currentSocket = -1; //continuation of a hack
296 dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));
297 if (result == LSCP_QUIT) { //Was it a quit command by any chance?
298 CloseConnection(iter);
299 }
300 }
301 //socket may have been closed, iter may be invalid, get out of the loop for now.
302 //we'll be back if there is data.
303 break;
304 }
305 }
306 }
307 }
308
309 void LSCPServer::CloseConnection( std::vector<yyparse_param_t>::iterator iter ) {
310 int socket = (*iter).hSession;
311 dmsg(1,("LSCPServer: Client connection terminated on socket:%d.\n",socket));
312 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection terminated on socket", socket));
313 Sessions.erase(iter);
314 FD_CLR(socket, &fdSet);
315 SubscriptionMutex.Lock(); //Must unsubscribe this socket from all events (if any)
316 for (std::map< LSCPEvent::event_t, std::list<int> >::iterator iter = eventSubscriptions.begin(); iter != eventSubscriptions.end(); iter++) {
317 iter->second.remove(socket);
318 }
319 SubscriptionMutex.Unlock();
320 NotifyMutex.Lock();
321 bufferedCommands.erase(socket);
322 bufferedNotifies.erase(socket);
323 close(socket);
324 NotifyMutex.Unlock();
325 }
326
327 int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
328 int subs = 0;
329 SubscriptionMutex.Lock();
330 for( std::list<LSCPEvent::event_t>::iterator iter = events.begin();
331 iter != events.end(); iter++)
332 {
333 subs += eventSubscriptions.count(*iter);
334 }
335 SubscriptionMutex.Unlock();
336 return subs;
337 }
338
339 void LSCPServer::SendLSCPNotify( LSCPEvent event ) {
340 SubscriptionMutex.Lock();
341 if (eventSubscriptions.count(event.GetType()) == 0) {
342 SubscriptionMutex.Unlock(); //Nobody is subscribed to this event
343 return;
344 }
345 std::list<int>::iterator iter = eventSubscriptions[event.GetType()].begin();
346 std::list<int>::iterator end = eventSubscriptions[event.GetType()].end();
347 String notify = event.Produce();
348
349 while (true) {
350 if (NotifyMutex.Trylock()) {
351 for(;iter != end; iter++)
352 #ifdef MSG_NOSIGNAL
353 send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);
354 #else
355 send(*iter, notify.c_str(), notify.size(), 0);
356 #endif
357 NotifyMutex.Unlock();
358 break;
359 } else {
360 if (NotifyBufferMutex.Trylock()) {
361 for(;iter != end; iter++)
362 bufferedNotifies[*iter] += notify;
363 NotifyBufferMutex.Unlock();
364 break;
365 }
366 }
367 }
368 SubscriptionMutex.Unlock();
369 }
370
371 extern int GetLSCPCommand( void *buf, int max_size ) {
372 String command = LSCPServer::bufferedCommands[LSCPServer::currentSocket];
373 if (command.size() == 0) { //Parser wants input but we have nothing.
374 strcpy((char*) buf, "\n"); //So give it an empty command
375 return 1; //to keep it happy.
376 }
377
378 if (max_size < command.size()) {
379 std::cerr << "getLSCPCommand: Flex buffer too small, ignoring the command." << std::endl;
380 return 0; //This will never happen
381 }
382
383 strcpy((char*) buf, command.c_str());
384 LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);
385 return command.size();
386 }
387
388 /**
389 * Will be called to try to read the command from the socket
390 * If command is read, it will return true. Otherwise false is returned.
391 * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.
392 */
393 bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
394 int socket = (*iter).hSession;
395 char c;
396 int i = 0;
397 while (true) {
398 int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
399 if (result == 0) { //socket was selected, so 0 here means client has closed the connection
400 CloseConnection(iter);
401 break;
402 }
403 if (result == 1) {
404 if (c == '\r')
405 continue; //Ignore CR
406 if (c == '\n') {
407 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
408 bufferedCommands[socket] += "\r\n";
409 return true; //Complete command was read
410 }
411 bufferedCommands[socket] += c;
412 }
413 if (result == -1) {
414 if (errno == EAGAIN) //Would block, try again later.
415 return false;
416 switch(errno) {
417 case EBADF:
418 dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
419 break;
420 case ECONNREFUSED:
421 dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
422 break;
423 case ENOTCONN:
424 dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
425 break;
426 case ENOTSOCK:
427 dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
428 break;
429 case EAGAIN:
430 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"));
431 break;
432 case EINTR:
433 dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
434 break;
435 case EFAULT:
436 dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
437 break;
438 case EINVAL:
439 dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
440 break;
441 case ENOMEM:
442 dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
443 break;
444 default:
445 dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
446 break;
447 }
448 CloseConnection(iter);
449 break;
450 }
451 }
452 return false;
453 }
454
455 /**
456 * Will be called by the parser whenever it wants to send an answer to the
457 * client / frontend.
458 *
459 * @param ReturnMessage - message that will be send to the client
460 */
461 void LSCPServer::AnswerClient(String ReturnMessage) {
462 dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
463 if (currentSocket != -1) {
464 NotifyMutex.Lock();
465 #ifdef MSG_NOSIGNAL
466 send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
467 #else
468 send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
469 #endif
470 NotifyMutex.Unlock();
471 }
472 }
473
474 /**
475 * Find a created audio output device index.
476 */
477 int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
478 {
479 // Search for the created device to get its index
480 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
481 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
482 for (; iter != devices.end(); iter++) {
483 if (iter->second == pDevice)
484 return iter->first;
485 }
486 // Not found.
487 return -1;
488 }
489
490 /**
491 * Find a created midi input device index.
492 */
493 int LSCPServer::GetMidiInputDeviceIndex ( MidiInputDevice *pDevice )
494 {
495 // Search for the created device to get its index
496 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
497 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
498 for (; iter != devices.end(); iter++) {
499 if (iter->second == pDevice)
500 return iter->first;
501 }
502 // Not found.
503 return -1;
504 }
505
506 String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
507 dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
508 LSCPResultSet result;
509 try {
510 AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
511 // search for the created device to get its index
512 int index = GetAudioOutputDeviceIndex(pDevice);
513 if (index == -1) throw Exception("Internal error: could not find created audio output device.");
514 result = index; // success
515 }
516 catch (Exception e) {
517 result.Error(e);
518 }
519 return result.Produce();
520 }
521
522 String LSCPServer::CreateMidiInputDevice(String Driver, std::map<String,String> Parameters) {
523 dmsg(2,("LSCPServer: CreateMidiInputDevice(Driver=%s)\n", Driver.c_str()));
524 LSCPResultSet result;
525 try {
526 MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
527 // search for the created device to get its index
528 int index = GetMidiInputDeviceIndex(pDevice);
529 if (index == -1) throw Exception("Internal error: could not find created midi input device.");
530 result = index; // success
531 }
532 catch (Exception e) {
533 result.Error(e);
534 }
535 return result.Produce();
536 }
537
538 String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
539 dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
540 LSCPResultSet result;
541 try {
542 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
543 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
544 AudioOutputDevice* pDevice = devices[DeviceIndex];
545 pSampler->DestroyAudioOutputDevice(pDevice);
546 }
547 catch (Exception e) {
548 result.Error(e);
549 }
550 return result.Produce();
551 }
552
553 String LSCPServer::DestroyMidiInputDevice(uint DeviceIndex) {
554 dmsg(2,("LSCPServer: DestroyMidiInputDevice(DeviceIndex=%d)\n", DeviceIndex));
555 LSCPResultSet result;
556 try {
557 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
558 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
559 MidiInputDevice* pDevice = devices[DeviceIndex];
560 pSampler->DestroyMidiInputDevice(pDevice);
561 }
562 catch (Exception e) {
563 result.Error(e);
564 }
565 return result.Produce();
566 }
567
568 /**
569 * Will be called by the parser to load an instrument.
570 */
571 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
572 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
573 LSCPResultSet result;
574 try {
575 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
576 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
577 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
578 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
579 if (!pSamplerChannel->GetAudioOutputDevice())
580 throw Exception("No audio output device connected to sampler channel");
581 if (bBackground) {
582 InstrumentManager::instrument_id_t id;
583 id.FileName = Filename;
584 id.Index = uiInstrument;
585 InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
586 }
587 else {
588 // tell the engine channel which instrument to load
589 pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrument);
590 // actually start to load the instrument (blocks until completed)
591 pEngineChannel->LoadInstrument();
592 }
593 }
594 catch (Exception e) {
595 result.Error(e);
596 }
597 return result.Produce();
598 }
599
600 /**
601 * Will be called by the parser to assign a sampler engine type to a
602 * sampler channel.
603 */
604 String LSCPServer::SetEngineType(String EngineName, uint uiSamplerChannel) {
605 dmsg(2,("LSCPServer: SetEngineType(EngineName=%s,uiSamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
606 LSCPResultSet result;
607 try {
608 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
609 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
610 LockRTNotify();
611 pSamplerChannel->SetEngineType(EngineName);
612 if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
613 UnlockRTNotify();
614 }
615 catch (Exception e) {
616 result.Error(e);
617 }
618 return result.Produce();
619 }
620
621 /**
622 * Will be called by the parser to get the amount of sampler channels.
623 */
624 String LSCPServer::GetChannels() {
625 dmsg(2,("LSCPServer: GetChannels()\n"));
626 LSCPResultSet result;
627 result.Add(pSampler->SamplerChannels());
628 return result.Produce();
629 }
630
631 /**
632 * Will be called by the parser to get the list of sampler channels.
633 */
634 String LSCPServer::ListChannels() {
635 dmsg(2,("LSCPServer: ListChannels()\n"));
636 String list;
637 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
638 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
639 for (; iter != channels.end(); iter++) {
640 if (list != "") list += ",";
641 list += ToString(iter->first);
642 }
643 LSCPResultSet result;
644 result.Add(list);
645 return result.Produce();
646 }
647
648 /**
649 * Will be called by the parser to add a sampler channel.
650 */
651 String LSCPServer::AddChannel() {
652 dmsg(2,("LSCPServer: AddChannel()\n"));
653 LockRTNotify();
654 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
655 UnlockRTNotify();
656 LSCPResultSet result(pSamplerChannel->Index());
657 return result.Produce();
658 }
659
660 /**
661 * Will be called by the parser to remove a sampler channel.
662 */
663 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
664 dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
665 LSCPResultSet result;
666 LockRTNotify();
667 pSampler->RemoveSamplerChannel(uiSamplerChannel);
668 UnlockRTNotify();
669 return result.Produce();
670 }
671
672 /**
673 * Will be called by the parser to get the amount of all available engines.
674 */
675 String LSCPServer::GetAvailableEngines() {
676 dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
677 LSCPResultSet result;
678 try {
679 int n = EngineFactory::AvailableEngineTypes().size();
680 result.Add(n);
681 }
682 catch (Exception e) {
683 result.Error(e);
684 }
685 return result.Produce();
686 }
687
688 /**
689 * Will be called by the parser to get a list of all available engines.
690 */
691 String LSCPServer::ListAvailableEngines() {
692 dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
693 LSCPResultSet result;
694 try {
695 String s = EngineFactory::AvailableEngineTypesAsString();
696 result.Add(s);
697 }
698 catch (Exception e) {
699 result.Error(e);
700 }
701 return result.Produce();
702 }
703
704 /**
705 * Will be called by the parser to get descriptions for a particular
706 * sampler engine.
707 */
708 String LSCPServer::GetEngineInfo(String EngineName) {
709 dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
710 LSCPResultSet result;
711 LockRTNotify();
712 try {
713 Engine* pEngine = EngineFactory::Create(EngineName);
714 result.Add("DESCRIPTION", pEngine->Description());
715 result.Add("VERSION", pEngine->Version());
716 EngineFactory::Destroy(pEngine);
717 }
718 catch (Exception e) {
719 result.Error(e);
720 }
721 UnlockRTNotify();
722 return result.Produce();
723 }
724
725 /**
726 * Will be called by the parser to get informations about a particular
727 * sampler channel.
728 */
729 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
730 dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
731 LSCPResultSet result;
732 try {
733 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
734 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
735 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
736
737 //Defaults values
738 String EngineName = "NONE";
739 float Volume = 0.0f;
740 String InstrumentFileName = "NONE";
741 String InstrumentName = "NONE";
742 int InstrumentIndex = -1;
743 int InstrumentStatus = -1;
744 int AudioOutputChannels = 0;
745 String AudioRouting;
746 int Mute = 0;
747 bool Solo = false;
748 String MidiInstrumentMap = "NONE";
749
750 if (pEngineChannel) {
751 EngineName = pEngineChannel->EngineName();
752 AudioOutputChannels = pEngineChannel->Channels();
753 Volume = pEngineChannel->Volume();
754 InstrumentStatus = pEngineChannel->InstrumentStatus();
755 InstrumentIndex = pEngineChannel->InstrumentIndex();
756 if (InstrumentIndex != -1) {
757 InstrumentFileName = pEngineChannel->InstrumentFileName();
758 InstrumentName = pEngineChannel->InstrumentName();
759 }
760 for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
761 if (AudioRouting != "") AudioRouting += ",";
762 AudioRouting += ToString(pEngineChannel->OutputChannel(chan));
763 }
764 Mute = pEngineChannel->GetMute();
765 Solo = pEngineChannel->GetSolo();
766 if (pEngineChannel->UsesNoMidiInstrumentMap())
767 MidiInstrumentMap = "NONE";
768 else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
769 MidiInstrumentMap = "DEFAULT";
770 else
771 MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
772 }
773
774 result.Add("ENGINE_NAME", EngineName);
775 result.Add("VOLUME", Volume);
776
777 //Some not-so-hardcoded stuff to make GUI look good
778 result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
779 result.Add("AUDIO_OUTPUT_CHANNELS", AudioOutputChannels);
780 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
781
782 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
783 result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
784 if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
785 else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
786
787 result.Add("INSTRUMENT_FILE", InstrumentFileName);
788 result.Add("INSTRUMENT_NR", InstrumentIndex);
789 result.Add("INSTRUMENT_NAME", InstrumentName);
790 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
791 result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
792 result.Add("SOLO", Solo);
793 result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
794 }
795 catch (Exception e) {
796 result.Error(e);
797 }
798 return result.Produce();
799 }
800
801 /**
802 * Will be called by the parser to get the amount of active voices on a
803 * particular sampler channel.
804 */
805 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
806 dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
807 LSCPResultSet result;
808 try {
809 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
810 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
811 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
812 if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");
813 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
814 result.Add(pEngineChannel->GetEngine()->VoiceCount());
815 }
816 catch (Exception e) {
817 result.Error(e);
818 }
819 return result.Produce();
820 }
821
822 /**
823 * Will be called by the parser to get the amount of active disk streams on a
824 * particular sampler channel.
825 */
826 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
827 dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
828 LSCPResultSet result;
829 try {
830 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
831 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
832 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
833 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
834 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
835 result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
836 }
837 catch (Exception e) {
838 result.Error(e);
839 }
840 return result.Produce();
841 }
842
843 /**
844 * Will be called by the parser to get the buffer fill states of all disk
845 * streams on a particular sampler channel.
846 */
847 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
848 dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
849 LSCPResultSet result;
850 try {
851 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
852 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
853 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
854 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
855 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
856 if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
857 else {
858 switch (ResponseType) {
859 case fill_response_bytes:
860 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillBytes());
861 break;
862 case fill_response_percentage:
863 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
864 break;
865 default:
866 throw Exception("Unknown fill response type");
867 }
868 }
869 }
870 catch (Exception e) {
871 result.Error(e);
872 }
873 return result.Produce();
874 }
875
876 String LSCPServer::GetAvailableAudioOutputDrivers() {
877 dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
878 LSCPResultSet result;
879 try {
880 int n = AudioOutputDeviceFactory::AvailableDrivers().size();
881 result.Add(n);
882 }
883 catch (Exception e) {
884 result.Error(e);
885 }
886 return result.Produce();
887 }
888
889 String LSCPServer::ListAvailableAudioOutputDrivers() {
890 dmsg(2,("LSCPServer: ListAvailableAudioOutputDrivers()\n"));
891 LSCPResultSet result;
892 try {
893 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
894 result.Add(s);
895 }
896 catch (Exception e) {
897 result.Error(e);
898 }
899 return result.Produce();
900 }
901
902 String LSCPServer::GetAvailableMidiInputDrivers() {
903 dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
904 LSCPResultSet result;
905 try {
906 int n = MidiInputDeviceFactory::AvailableDrivers().size();
907 result.Add(n);
908 }
909 catch (Exception e) {
910 result.Error(e);
911 }
912 return result.Produce();
913 }
914
915 String LSCPServer::ListAvailableMidiInputDrivers() {
916 dmsg(2,("LSCPServer: ListAvailableMidiInputDrivers()\n"));
917 LSCPResultSet result;
918 try {
919 String s = MidiInputDeviceFactory::AvailableDriversAsString();
920 result.Add(s);
921 }
922 catch (Exception e) {
923 result.Error(e);
924 }
925 return result.Produce();
926 }
927
928 String LSCPServer::GetMidiInputDriverInfo(String Driver) {
929 dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
930 LSCPResultSet result;
931 try {
932 result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
933 result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
934
935 std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
936 if (parameters.size()) { // if there are parameters defined for this driver
937 String s;
938 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
939 for (;iter != parameters.end(); iter++) {
940 if (s != "") s += ",";
941 s += iter->first;
942 }
943 result.Add("PARAMETERS", s);
944 }
945 }
946 catch (Exception e) {
947 result.Error(e);
948 }
949 return result.Produce();
950 }
951
952 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
953 dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
954 LSCPResultSet result;
955 try {
956 result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
957 result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
958
959 std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
960 if (parameters.size()) { // if there are parameters defined for this driver
961 String s;
962 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
963 for (;iter != parameters.end(); iter++) {
964 if (s != "") s += ",";
965 s += iter->first;
966 }
967 result.Add("PARAMETERS", s);
968 }
969 }
970 catch (Exception e) {
971 result.Error(e);
972 }
973 return result.Produce();
974 }
975
976 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
977 dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
978 LSCPResultSet result;
979 try {
980 DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
981 result.Add("TYPE", pParameter->Type());
982 result.Add("DESCRIPTION", pParameter->Description());
983 result.Add("MANDATORY", pParameter->Mandatory());
984 result.Add("FIX", pParameter->Fix());
985 result.Add("MULTIPLICITY", pParameter->Multiplicity());
986 optional<String> oDepends = pParameter->Depends();
987 optional<String> oDefault = pParameter->Default(DependencyList);
988 optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
989 optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
990 optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
991 if (oDepends) result.Add("DEPENDS", *oDepends);
992 if (oDefault) result.Add("DEFAULT", *oDefault);
993 if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
994 if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
995 if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
996 }
997 catch (Exception e) {
998 result.Error(e);
999 }
1000 return result.Produce();
1001 }
1002
1003 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1004 dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
1005 LSCPResultSet result;
1006 try {
1007 DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
1008 result.Add("TYPE", pParameter->Type());
1009 result.Add("DESCRIPTION", pParameter->Description());
1010 result.Add("MANDATORY", pParameter->Mandatory());
1011 result.Add("FIX", pParameter->Fix());
1012 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1013 optional<String> oDepends = pParameter->Depends();
1014 optional<String> oDefault = pParameter->Default(DependencyList);
1015 optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
1016 optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
1017 optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
1018 if (oDepends) result.Add("DEPENDS", *oDepends);
1019 if (oDefault) result.Add("DEFAULT", *oDefault);
1020 if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
1021 if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
1022 if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1023 }
1024 catch (Exception e) {
1025 result.Error(e);
1026 }
1027 return result.Produce();
1028 }
1029
1030 String LSCPServer::GetAudioOutputDeviceCount() {
1031 dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
1032 LSCPResultSet result;
1033 try {
1034 uint count = pSampler->AudioOutputDevices();
1035 result.Add(count); // success
1036 }
1037 catch (Exception e) {
1038 result.Error(e);
1039 }
1040 return result.Produce();
1041 }
1042
1043 String LSCPServer::GetMidiInputDeviceCount() {
1044 dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
1045 LSCPResultSet result;
1046 try {
1047 uint count = pSampler->MidiInputDevices();
1048 result.Add(count); // success
1049 }
1050 catch (Exception e) {
1051 result.Error(e);
1052 }
1053 return result.Produce();
1054 }
1055
1056 String LSCPServer::GetAudioOutputDevices() {
1057 dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
1058 LSCPResultSet result;
1059 try {
1060 String s;
1061 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1062 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1063 for (; iter != devices.end(); iter++) {
1064 if (s != "") s += ",";
1065 s += ToString(iter->first);
1066 }
1067 result.Add(s);
1068 }
1069 catch (Exception e) {
1070 result.Error(e);
1071 }
1072 return result.Produce();
1073 }
1074
1075 String LSCPServer::GetMidiInputDevices() {
1076 dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
1077 LSCPResultSet result;
1078 try {
1079 String s;
1080 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1081 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1082 for (; iter != devices.end(); iter++) {
1083 if (s != "") s += ",";
1084 s += ToString(iter->first);
1085 }
1086 result.Add(s);
1087 }
1088 catch (Exception e) {
1089 result.Error(e);
1090 }
1091 return result.Produce();
1092 }
1093
1094 String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
1095 dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1096 LSCPResultSet result;
1097 try {
1098 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1099 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1100 AudioOutputDevice* pDevice = devices[DeviceIndex];
1101 result.Add("DRIVER", pDevice->Driver());
1102 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1103 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1104 for (; iter != parameters.end(); iter++) {
1105 result.Add(iter->first, iter->second->Value());
1106 }
1107 }
1108 catch (Exception e) {
1109 result.Error(e);
1110 }
1111 return result.Produce();
1112 }
1113
1114 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
1115 dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1116 LSCPResultSet result;
1117 try {
1118 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1119 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1120 MidiInputDevice* pDevice = devices[DeviceIndex];
1121 result.Add("DRIVER", pDevice->Driver());
1122 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1123 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1124 for (; iter != parameters.end(); iter++) {
1125 result.Add(iter->first, iter->second->Value());
1126 }
1127 }
1128 catch (Exception e) {
1129 result.Error(e);
1130 }
1131 return result.Produce();
1132 }
1133 String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
1134 dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
1135 LSCPResultSet result;
1136 try {
1137 // get MIDI input device
1138 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1139 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1140 MidiInputDevice* pDevice = devices[DeviceIndex];
1141
1142 // get MIDI port
1143 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1144 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1145
1146 // return the values of all MIDI port parameters
1147 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1148 std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1149 for (; iter != parameters.end(); iter++) {
1150 result.Add(iter->first, iter->second->Value());
1151 }
1152 }
1153 catch (Exception e) {
1154 result.Error(e);
1155 }
1156 return result.Produce();
1157 }
1158
1159 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
1160 dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
1161 LSCPResultSet result;
1162 try {
1163 // get audio output device
1164 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1165 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1166 AudioOutputDevice* pDevice = devices[DeviceId];
1167
1168 // get audio channel
1169 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1170 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1171
1172 // return the values of all audio channel parameters
1173 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1174 std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1175 for (; iter != parameters.end(); iter++) {
1176 result.Add(iter->first, iter->second->Value());
1177 }
1178 }
1179 catch (Exception e) {
1180 result.Error(e);
1181 }
1182 return result.Produce();
1183 }
1184
1185 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
1186 dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
1187 LSCPResultSet result;
1188 try {
1189 // get MIDI input device
1190 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1191 if (!devices.count(DeviceId)) throw Exception("There is no midi input device with index " + ToString(DeviceId) + ".");
1192 MidiInputDevice* pDevice = devices[DeviceId];
1193
1194 // get midi port
1195 MidiInputPort* pPort = pDevice->GetPort(PortId);
1196 if (!pPort) throw Exception("Midi input device does not have port " + ToString(PortId) + ".");
1197
1198 // get desired port parameter
1199 std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1200 if (!parameters.count(ParameterName)) throw Exception("Midi port does not provide a parameter '" + ParameterName + "'.");
1201 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1202
1203 // return all fields of this audio channel parameter
1204 result.Add("TYPE", pParameter->Type());
1205 result.Add("DESCRIPTION", pParameter->Description());
1206 result.Add("FIX", pParameter->Fix());
1207 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1208 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1209 if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1210 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1211 }
1212 catch (Exception e) {
1213 result.Error(e);
1214 }
1215 return result.Produce();
1216 }
1217
1218 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
1219 dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
1220 LSCPResultSet result;
1221 try {
1222 // get audio output device
1223 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1224 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1225 AudioOutputDevice* pDevice = devices[DeviceId];
1226
1227 // get audio channel
1228 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1229 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1230
1231 // get desired audio channel parameter
1232 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1233 if (!parameters.count(ParameterName)) throw Exception("Audio channel does not provide a parameter '" + ParameterName + "'.");
1234 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1235
1236 // return all fields of this audio channel parameter
1237 result.Add("TYPE", pParameter->Type());
1238 result.Add("DESCRIPTION", pParameter->Description());
1239 result.Add("FIX", pParameter->Fix());
1240 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1241 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1242 if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1243 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1244 }
1245 catch (Exception e) {
1246 result.Error(e);
1247 }
1248 return result.Produce();
1249 }
1250
1251 String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
1252 dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
1253 LSCPResultSet result;
1254 try {
1255 // get audio output device
1256 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1257 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1258 AudioOutputDevice* pDevice = devices[DeviceId];
1259
1260 // get audio channel
1261 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1262 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1263
1264 // get desired audio channel parameter
1265 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1266 if (!parameters.count(ParamKey)) throw Exception("Audio channel does not provide a parameter '" + ParamKey + "'.");
1267 DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1268
1269 // set new channel parameter value
1270 pParameter->SetValue(ParamVal);
1271 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1272 }
1273 catch (Exception e) {
1274 result.Error(e);
1275 }
1276 return result.Produce();
1277 }
1278
1279 String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1280 dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1281 LSCPResultSet result;
1282 try {
1283 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1284 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1285 AudioOutputDevice* pDevice = devices[DeviceIndex];
1286 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1287 if (!parameters.count(ParamKey)) throw Exception("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1288 parameters[ParamKey]->SetValue(ParamVal);
1289 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1290 }
1291 catch (Exception e) {
1292 result.Error(e);
1293 }
1294 return result.Produce();
1295 }
1296
1297 String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1298 dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1299 LSCPResultSet result;
1300 try {
1301 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1302 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1303 MidiInputDevice* pDevice = devices[DeviceIndex];
1304 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1305 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1306 parameters[ParamKey]->SetValue(ParamVal);
1307 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1308 }
1309 catch (Exception e) {
1310 result.Error(e);
1311 }
1312 return result.Produce();
1313 }
1314
1315 String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1316 dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1317 LSCPResultSet result;
1318 try {
1319 // get MIDI input device
1320 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1321 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1322 MidiInputDevice* pDevice = devices[DeviceIndex];
1323
1324 // get MIDI port
1325 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1326 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1327
1328 // set port parameter value
1329 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1330 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1331 parameters[ParamKey]->SetValue(ParamVal);
1332 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1333 }
1334 catch (Exception e) {
1335 result.Error(e);
1336 }
1337 return result.Produce();
1338 }
1339
1340 /**
1341 * Will be called by the parser to change the audio output channel for
1342 * playback on a particular sampler channel.
1343 */
1344 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1345 dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1346 LSCPResultSet result;
1347 try {
1348 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1349 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1350 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1351 if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1352 if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1353 pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1354 }
1355 catch (Exception e) {
1356 result.Error(e);
1357 }
1358 return result.Produce();
1359 }
1360
1361 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1362 dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1363 LSCPResultSet result;
1364 LockRTNotify();
1365 try {
1366 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1367 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1368 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1369 if (!devices.count(AudioDeviceId)) throw Exception("There is no audio output device with index " + ToString(AudioDeviceId));
1370 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1371 pSamplerChannel->SetAudioOutputDevice(pDevice);
1372 }
1373 catch (Exception e) {
1374 result.Error(e);
1375 }
1376 UnlockRTNotify();
1377 return result.Produce();
1378 }
1379
1380 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1381 dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1382 LSCPResultSet result;
1383 LockRTNotify();
1384 try {
1385 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1386 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1387 // Driver type name aliasing...
1388 if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1389 if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1390 // Check if there's one audio output device already created
1391 // for the intended audio driver type (AudioOutputDriver)...
1392 AudioOutputDevice *pDevice = NULL;
1393 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1394 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1395 for (; iter != devices.end(); iter++) {
1396 if ((iter->second)->Driver() == AudioOutputDriver) {
1397 pDevice = iter->second;
1398 break;
1399 }
1400 }
1401 // If it doesn't exist, create a new one with default parameters...
1402 if (pDevice == NULL) {
1403 std::map<String,String> params;
1404 pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1405 }
1406 // Must have a device...
1407 if (pDevice == NULL)
1408 throw Exception("Internal error: could not create audio output device.");
1409 // Set it as the current channel device...
1410 pSamplerChannel->SetAudioOutputDevice(pDevice);
1411 }
1412 catch (Exception e) {
1413 result.Error(e);
1414 }
1415 UnlockRTNotify();
1416 return result.Produce();
1417 }
1418
1419 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1420 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1421 LSCPResultSet result;
1422 try {
1423 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1424 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1425 pSamplerChannel->SetMidiInputPort(MIDIPort);
1426 }
1427 catch (Exception e) {
1428 result.Error(e);
1429 }
1430 return result.Produce();
1431 }
1432
1433 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1434 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1435 LSCPResultSet result;
1436 try {
1437 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1438 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1439 pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1440 }
1441 catch (Exception e) {
1442 result.Error(e);
1443 }
1444 return result.Produce();
1445 }
1446
1447 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1448 dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1449 LSCPResultSet result;
1450 try {
1451 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1452 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1453 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1454 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1455 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1456 pSamplerChannel->SetMidiInputDevice(pDevice);
1457 }
1458 catch (Exception e) {
1459 result.Error(e);
1460 }
1461 return result.Produce();
1462 }
1463
1464 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1465 dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1466 LSCPResultSet result;
1467 try {
1468 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1469 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1470 // Driver type name aliasing...
1471 if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1472 // Check if there's one MIDI input device already created
1473 // for the intended MIDI driver type (MidiInputDriver)...
1474 MidiInputDevice *pDevice = NULL;
1475 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1476 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1477 for (; iter != devices.end(); iter++) {
1478 if ((iter->second)->Driver() == MidiInputDriver) {
1479 pDevice = iter->second;
1480 break;
1481 }
1482 }
1483 // If it doesn't exist, create a new one with default parameters...
1484 if (pDevice == NULL) {
1485 std::map<String,String> params;
1486 pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1487 // Make it with at least one initial port.
1488 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1489 parameters["PORTS"]->SetValue("1");
1490 }
1491 // Must have a device...
1492 if (pDevice == NULL)
1493 throw Exception("Internal error: could not create MIDI input device.");
1494 // Set it as the current channel device...
1495 pSamplerChannel->SetMidiInputDevice(pDevice);
1496 }
1497 catch (Exception e) {
1498 result.Error(e);
1499 }
1500 return result.Produce();
1501 }
1502
1503 /**
1504 * Will be called by the parser to change the MIDI input device, port and channel on which
1505 * engine of a particular sampler channel should listen to.
1506 */
1507 String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1508 dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1509 LSCPResultSet result;
1510 try {
1511 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1512 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1513 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1514 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1515 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1516 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
1517 }
1518 catch (Exception e) {
1519 result.Error(e);
1520 }
1521 return result.Produce();
1522 }
1523
1524 /**
1525 * Will be called by the parser to change the global volume factor on a
1526 * particular sampler channel.
1527 */
1528 String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
1529 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1530 LSCPResultSet result;
1531 try {
1532 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1533 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1534 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1535 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1536 pEngineChannel->Volume(dVolume);
1537 }
1538 catch (Exception e) {
1539 result.Error(e);
1540 }
1541 return result.Produce();
1542 }
1543
1544 /**
1545 * Will be called by the parser to mute/unmute particular sampler channel.
1546 */
1547 String LSCPServer::SetChannelMute(bool bMute, uint uiSamplerChannel) {
1548 dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
1549 LSCPResultSet result;
1550 try {
1551 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1552 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1553
1554 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1555 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1556
1557 if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1558 else pEngineChannel->SetMute(1);
1559 } catch (Exception e) {
1560 result.Error(e);
1561 }
1562 return result.Produce();
1563 }
1564
1565 /**
1566 * Will be called by the parser to solo particular sampler channel.
1567 */
1568 String LSCPServer::SetChannelSolo(bool bSolo, uint uiSamplerChannel) {
1569 dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
1570 LSCPResultSet result;
1571 try {
1572 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1573 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1574
1575 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1576 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1577
1578 bool oldSolo = pEngineChannel->GetSolo();
1579 bool hadSoloChannel = HasSoloChannel();
1580
1581 pEngineChannel->SetSolo(bSolo);
1582
1583 if(!oldSolo && bSolo) {
1584 if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
1585 if(!hadSoloChannel) MuteNonSoloChannels();
1586 }
1587
1588 if(oldSolo && !bSolo) {
1589 if(!HasSoloChannel()) UnmuteChannels();
1590 else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
1591 }
1592 } catch (Exception e) {
1593 result.Error(e);
1594 }
1595 return result.Produce();
1596 }
1597
1598 /**
1599 * Determines whether there is at least one solo channel in the channel list.
1600 *
1601 * @returns true if there is at least one solo channel in the channel list,
1602 * false otherwise.
1603 */
1604 bool LSCPServer::HasSoloChannel() {
1605 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1606 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1607 for (; iter != channels.end(); iter++) {
1608 EngineChannel* c = iter->second->GetEngineChannel();
1609 if(c && c->GetSolo()) return true;
1610 }
1611
1612 return false;
1613 }
1614
1615 /**
1616 * Mutes all unmuted non-solo channels. Notice that the channels are muted
1617 * with -1 which indicates that they are muted because of the presence
1618 * of a solo channel(s). Channels muted with -1 will be automatically unmuted
1619 * when there are no solo channels left.
1620 */
1621 void LSCPServer::MuteNonSoloChannels() {
1622 dmsg(2,("LSCPServer: MuteNonSoloChannels()\n"));
1623 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1624 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1625 for (; iter != channels.end(); iter++) {
1626 EngineChannel* c = iter->second->GetEngineChannel();
1627 if(c && !c->GetSolo() && !c->GetMute()) c->SetMute(-1);
1628 }
1629 }
1630
1631 /**
1632 * Unmutes all channels that are muted because of the presence
1633 * of a solo channel(s).
1634 */
1635 void LSCPServer::UnmuteChannels() {
1636 dmsg(2,("LSCPServer: UnmuteChannels()\n"));
1637 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1638 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1639 for (; iter != channels.end(); iter++) {
1640 EngineChannel* c = iter->second->GetEngineChannel();
1641 if(c && c->GetMute() == -1) c->SetMute(0);
1642 }
1643 }
1644
1645 String LSCPServer::AddOrReplaceMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg, String EngineType, String InstrumentFile, uint InstrumentIndex, float Volume, MidiInstrumentMapper::mode_t LoadMode, String Name, bool bModal) {
1646 dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
1647
1648 midi_prog_index_t idx;
1649 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1650 idx.midi_bank_lsb = MidiBank & 0x7f;
1651 idx.midi_prog = MidiProg;
1652
1653 MidiInstrumentMapper::entry_t entry;
1654 entry.EngineName = EngineType;
1655 entry.InstrumentFile = InstrumentFile;
1656 entry.InstrumentIndex = InstrumentIndex;
1657 entry.LoadMode = LoadMode;
1658 entry.Volume = Volume;
1659 entry.Name = Name;
1660
1661 LSCPResultSet result;
1662 try {
1663 // PERSISTENT mapping commands might block for a long time, so in
1664 // that case we add/replace the mapping in another thread in case
1665 // the NON_MODAL argument was supplied, non persistent mappings
1666 // should return immediately, so we don't need to do that for them
1667 bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
1668 MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1669 } catch (Exception e) {
1670 result.Error(e);
1671 }
1672 return result.Produce();
1673 }
1674
1675 String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1676 dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1677
1678 midi_prog_index_t idx;
1679 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1680 idx.midi_bank_lsb = MidiBank & 0x7f;
1681 idx.midi_prog = MidiProg;
1682
1683 LSCPResultSet result;
1684 try {
1685 MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1686 } catch (Exception e) {
1687 result.Error(e);
1688 }
1689 return result.Produce();
1690 }
1691
1692 String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1693 dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1694 LSCPResultSet result;
1695 try {
1696 result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1697 } catch (Exception e) {
1698 result.Error(e);
1699 }
1700 return result.Produce();
1701 }
1702
1703
1704 String LSCPServer::GetAllMidiInstrumentMappings() {
1705 dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1706 LSCPResultSet result;
1707 std::vector<int> maps = MidiInstrumentMapper::Maps();
1708 int totalMappings = 0;
1709 for (int i = 0; i < maps.size(); i++) {
1710 try {
1711 totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1712 } catch (Exception e) { /*NOOP*/ }
1713 }
1714 result.Add(totalMappings);
1715 return result.Produce();
1716 }
1717
1718 String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1719 dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1720 LSCPResultSet result;
1721 try {
1722 midi_prog_index_t idx;
1723 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1724 idx.midi_bank_lsb = MidiBank & 0x7f;
1725 idx.midi_prog = MidiProg;
1726
1727 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1728 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1729 if (iter == mappings.end()) result.Error("there is no map entry with that index");
1730 else { // found
1731 result.Add("NAME", iter->second.Name);
1732 result.Add("ENGINE_NAME", iter->second.EngineName);
1733 result.Add("INSTRUMENT_FILE", iter->second.InstrumentFile);
1734 result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1735 String instrumentName;
1736 Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1737 if (pEngine) {
1738 if (pEngine->GetInstrumentManager()) {
1739 InstrumentManager::instrument_id_t instrID;
1740 instrID.FileName = iter->second.InstrumentFile;
1741 instrID.Index = iter->second.InstrumentIndex;
1742 instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
1743 }
1744 EngineFactory::Destroy(pEngine);
1745 }
1746 result.Add("INSTRUMENT_NAME", instrumentName);
1747 switch (iter->second.LoadMode) {
1748 case MidiInstrumentMapper::ON_DEMAND:
1749 result.Add("LOAD_MODE", "ON_DEMAND");
1750 break;
1751 case MidiInstrumentMapper::ON_DEMAND_HOLD:
1752 result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
1753 break;
1754 case MidiInstrumentMapper::PERSISTENT:
1755 result.Add("LOAD_MODE", "PERSISTENT");
1756 break;
1757 default:
1758 throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
1759 }
1760 result.Add("VOLUME", iter->second.Volume);
1761 }
1762 } catch (Exception e) {
1763 result.Error(e);
1764 }
1765 return result.Produce();
1766 }
1767
1768 String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
1769 dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
1770 LSCPResultSet result;
1771 try {
1772 String s;
1773 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1774 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1775 for (; iter != mappings.end(); iter++) {
1776 if (s.size()) s += ",";
1777 s += "{" + ToString(MidiMapID) + ","
1778 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1779 + ToString(int(iter->first.midi_prog)) + "}";
1780 }
1781 result.Add(s);
1782 } catch (Exception e) {
1783 result.Error(e);
1784 }
1785 return result.Produce();
1786 }
1787
1788 String LSCPServer::ListAllMidiInstrumentMappings() {
1789 dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
1790 LSCPResultSet result;
1791 try {
1792 std::vector<int> maps = MidiInstrumentMapper::Maps();
1793 String s;
1794 for (int i = 0; i < maps.size(); i++) {
1795 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
1796 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1797 for (; iter != mappings.end(); iter++) {
1798 if (s.size()) s += ",";
1799 s += "{" + ToString(maps[i]) + ","
1800 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1801 + ToString(int(iter->first.midi_prog)) + "}";
1802 }
1803 }
1804 result.Add(s);
1805 } catch (Exception e) {
1806 result.Error(e);
1807 }
1808 return result.Produce();
1809 }
1810
1811 String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
1812 dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
1813 LSCPResultSet result;
1814 try {
1815 MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
1816 } catch (Exception e) {
1817 result.Error(e);
1818 }
1819 return result.Produce();
1820 }
1821
1822 String LSCPServer::ClearAllMidiInstrumentMappings() {
1823 dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
1824 LSCPResultSet result;
1825 try {
1826 std::vector<int> maps = MidiInstrumentMapper::Maps();
1827 for (int i = 0; i < maps.size(); i++)
1828 MidiInstrumentMapper::RemoveAllEntries(maps[i]);
1829 } catch (Exception e) {
1830 result.Error(e);
1831 }
1832 return result.Produce();
1833 }
1834
1835 String LSCPServer::AddMidiInstrumentMap(String MapName) {
1836 dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
1837 LSCPResultSet result;
1838 try {
1839 int MapID = MidiInstrumentMapper::AddMap(MapName);
1840 result = LSCPResultSet(MapID);
1841 } catch (Exception e) {
1842 result.Error(e);
1843 }
1844 return result.Produce();
1845 }
1846
1847 String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
1848 dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
1849 LSCPResultSet result;
1850 try {
1851 MidiInstrumentMapper::RemoveMap(MidiMapID);
1852 } catch (Exception e) {
1853 result.Error(e);
1854 }
1855 return result.Produce();
1856 }
1857
1858 String LSCPServer::RemoveAllMidiInstrumentMaps() {
1859 dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
1860 LSCPResultSet result;
1861 try {
1862 MidiInstrumentMapper::RemoveAllMaps();
1863 } catch (Exception e) {
1864 result.Error(e);
1865 }
1866 return result.Produce();
1867 }
1868
1869 String LSCPServer::GetMidiInstrumentMaps() {
1870 dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
1871 LSCPResultSet result;
1872 try {
1873 result.Add(MidiInstrumentMapper::Maps().size());
1874 } catch (Exception e) {
1875 result.Error(e);
1876 }
1877 return result.Produce();
1878 }
1879
1880 String LSCPServer::ListMidiInstrumentMaps() {
1881 dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
1882 LSCPResultSet result;
1883 try {
1884 std::vector<int> maps = MidiInstrumentMapper::Maps();
1885 String sList;
1886 for (int i = 0; i < maps.size(); i++) {
1887 if (sList != "") sList += ",";
1888 sList += ToString(maps[i]);
1889 }
1890 result.Add(sList);
1891 } catch (Exception e) {
1892 result.Error(e);
1893 }
1894 return result.Produce();
1895 }
1896
1897 String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
1898 dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
1899 LSCPResultSet result;
1900 try {
1901 result.Add("NAME", MidiInstrumentMapper::MapName(MidiMapID));
1902 } catch (Exception e) {
1903 result.Error(e);
1904 }
1905 return result.Produce();
1906 }
1907
1908 String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
1909 dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
1910 LSCPResultSet result;
1911 try {
1912 MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
1913 } catch (Exception e) {
1914 result.Error(e);
1915 }
1916 return result.Produce();
1917 }
1918
1919 /**
1920 * Set the MIDI instrument map the given sampler channel shall use for
1921 * handling MIDI program change messages. There are the following two
1922 * special (negative) values:
1923 *
1924 * - (-1) : set to NONE (ignore program changes)
1925 * - (-2) : set to DEFAULT map
1926 */
1927 String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
1928 dmsg(2,("LSCPServer: SetChannelMap()\n"));
1929 LSCPResultSet result;
1930 try {
1931 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1932 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1933
1934 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1935 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1936
1937 if (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
1938 else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
1939 else pEngineChannel->SetMidiInstrumentMap(MidiMapID);
1940 } catch (Exception e) {
1941 result.Error(e);
1942 }
1943 return result.Produce();
1944 }
1945
1946 String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
1947 dmsg(2,("LSCPServer: CreateFxSend()\n"));
1948 LSCPResultSet result;
1949 try {
1950 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1951 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1952
1953 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1954 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1955
1956 FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
1957 if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
1958
1959 result = LSCPResultSet(pFxSend->Id()); // success
1960 } catch (Exception e) {
1961 result.Error(e);
1962 }
1963 return result.Produce();
1964 }
1965
1966 String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
1967 dmsg(2,("LSCPServer: DestroyFxSend()\n"));
1968 LSCPResultSet result;
1969 try {
1970 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1971 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1972
1973 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1974 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1975
1976 FxSend* pFxSend = NULL;
1977 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1978 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1979 pFxSend = pEngineChannel->GetFxSend(i);
1980 break;
1981 }
1982 }
1983 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1984 pEngineChannel->RemoveFxSend(pFxSend);
1985 } catch (Exception e) {
1986 result.Error(e);
1987 }
1988 return result.Produce();
1989 }
1990
1991 String LSCPServer::GetFxSends(uint uiSamplerChannel) {
1992 dmsg(2,("LSCPServer: GetFxSends()\n"));
1993 LSCPResultSet result;
1994 try {
1995 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1996 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1997
1998 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1999 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2000
2001 result.Add(pEngineChannel->GetFxSendCount());
2002 } catch (Exception e) {
2003 result.Error(e);
2004 }
2005 return result.Produce();
2006 }
2007
2008 String LSCPServer::ListFxSends(uint uiSamplerChannel) {
2009 dmsg(2,("LSCPServer: ListFxSends()\n"));
2010 LSCPResultSet result;
2011 String list;
2012 try {
2013 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2014 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2015
2016 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2017 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2018
2019 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2020 FxSend* pFxSend = pEngineChannel->GetFxSend(i);
2021 if (list != "") list += ",";
2022 list += ToString(pFxSend->Id());
2023 }
2024 result.Add(list);
2025 } catch (Exception e) {
2026 result.Error(e);
2027 }
2028 return result.Produce();
2029 }
2030
2031 String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
2032 dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
2033 LSCPResultSet result;
2034 try {
2035 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2036 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2037
2038 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2039 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2040
2041 FxSend* pFxSend = NULL;
2042 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2043 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2044 pFxSend = pEngineChannel->GetFxSend(i);
2045 break;
2046 }
2047 }
2048 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2049
2050 // gather audio routing informations
2051 String AudioRouting;
2052 for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
2053 if (AudioRouting != "") AudioRouting += ",";
2054 AudioRouting += ToString(pFxSend->DestinationChannel(chan));
2055 }
2056
2057 // success
2058 result.Add("NAME", pFxSend->Name());
2059 result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
2060 result.Add("LEVEL", ToString(pFxSend->Level()));
2061 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
2062 } catch (Exception e) {
2063 result.Error(e);
2064 }
2065 return result.Produce();
2066 }
2067
2068 String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
2069 dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
2070 LSCPResultSet result;
2071 try {
2072 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2073 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2074
2075 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2076 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2077
2078 FxSend* pFxSend = NULL;
2079 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2080 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2081 pFxSend = pEngineChannel->GetFxSend(i);
2082 break;
2083 }
2084 }
2085 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2086
2087 pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2088 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2089 } catch (Exception e) {
2090 result.Error(e);
2091 }
2092 return result.Produce();
2093 }
2094
2095 String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2096 dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2097 LSCPResultSet result;
2098 try {
2099 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2100 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2101
2102 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2103 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2104
2105 FxSend* pFxSend = NULL;
2106 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2107 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2108 pFxSend = pEngineChannel->GetFxSend(i);
2109 break;
2110 }
2111 }
2112 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2113
2114 pFxSend->SetMidiController(MidiController);
2115 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2116 } catch (Exception e) {
2117 result.Error(e);
2118 }
2119 return result.Produce();
2120 }
2121
2122 String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2123 dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2124 LSCPResultSet result;
2125 try {
2126 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2127 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2128
2129 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2130 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
2131
2132 FxSend* pFxSend = NULL;
2133 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2134 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2135 pFxSend = pEngineChannel->GetFxSend(i);
2136 break;
2137 }
2138 }
2139 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2140
2141 pFxSend->SetLevel((float)dLevel);
2142 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2143 } catch (Exception e) {
2144 result.Error(e);
2145 }
2146 return result.Produce();
2147 }
2148
2149 /**
2150 * Will be called by the parser to reset a particular sampler channel.
2151 */
2152 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
2153 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2154 LSCPResultSet result;
2155 try {
2156 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2157 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2158 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2159 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2160 pEngineChannel->Reset();
2161 }
2162 catch (Exception e) {
2163 result.Error(e);
2164 }
2165 return result.Produce();
2166 }
2167
2168 /**
2169 * Will be called by the parser to reset the whole sampler.
2170 */
2171 String LSCPServer::ResetSampler() {
2172 dmsg(2,("LSCPServer: ResetSampler()\n"));
2173 pSampler->Reset();
2174 LSCPResultSet result;
2175 return result.Produce();
2176 }
2177
2178 /**
2179 * Will be called by the parser to return general informations about this
2180 * sampler.
2181 */
2182 String LSCPServer::GetServerInfo() {
2183 dmsg(2,("LSCPServer: GetServerInfo()\n"));
2184 LSCPResultSet result;
2185 result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2186 result.Add("VERSION", VERSION);
2187 result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2188 return result.Produce();
2189 }
2190
2191 /**
2192 * Will be called by the parser to return the current number of all active voices.
2193 */
2194 String LSCPServer::GetTotalVoiceCount() {
2195 dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2196 LSCPResultSet result;
2197 result.Add(pSampler->GetVoiceCount());
2198 return result.Produce();
2199 }
2200
2201 /**
2202 * Will be called by the parser to return the maximum number of voices.
2203 */
2204 String LSCPServer::GetTotalVoiceCountMax() {
2205 dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2206 LSCPResultSet result;
2207 result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2208 return result.Produce();
2209 }
2210
2211 String LSCPServer::GetGlobalVolume() {
2212 LSCPResultSet result;
2213 result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2214 return result.Produce();
2215 }
2216
2217 String LSCPServer::SetGlobalVolume(double dVolume) {
2218 LSCPResultSet result;
2219 try {
2220 if (dVolume < 0) throw Exception("Volume may not be negative");
2221 GLOBAL_VOLUME = dVolume; // see common/global.cpp
2222 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
2223 } catch (Exception e) {
2224 result.Error(e);
2225 }
2226 return result.Produce();
2227 }
2228
2229 /**
2230 * Will be called by the parser to subscribe a client (frontend) on the
2231 * server for receiving event messages.
2232 */
2233 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
2234 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2235 LSCPResultSet result;
2236 SubscriptionMutex.Lock();
2237 eventSubscriptions[type].push_back(currentSocket);
2238 SubscriptionMutex.Unlock();
2239 return result.Produce();
2240 }
2241
2242 /**
2243 * Will be called by the parser to unsubscribe a client on the server
2244 * for not receiving further event messages.
2245 */
2246 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
2247 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2248 LSCPResultSet result;
2249 SubscriptionMutex.Lock();
2250 eventSubscriptions[type].remove(currentSocket);
2251 SubscriptionMutex.Unlock();
2252 return result.Produce();
2253 }
2254
2255 static int select_callback(void * lscpResultSet, int argc,
2256 char **argv, char **azColName)
2257 {
2258 LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;
2259 resultSet->Add(argc, argv);
2260 return 0;
2261 }
2262
2263 String LSCPServer::QueryDatabase(String query) {
2264 LSCPResultSet result;
2265 #if HAVE_SQLITE3
2266 char* zErrMsg = NULL;
2267 sqlite3 *db;
2268 String selectStr = "SELECT " + query;
2269
2270 int rc = sqlite3_open("linuxsampler.db", &db);
2271 if (rc == SQLITE_OK)
2272 {
2273 rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);
2274 }
2275 if ( rc != SQLITE_OK )
2276 {
2277 result.Error(String(zErrMsg), rc);
2278 }
2279 sqlite3_close(db);
2280 #else
2281 result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);
2282 #endif
2283 return result.Produce();
2284 }
2285
2286 /**
2287 * Will be called by the parser to enable or disable echo mode; if echo
2288 * mode is enabled, all commands from the client will (immediately) be
2289 * echoed back to the client.
2290 */
2291 String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
2292 dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
2293 LSCPResultSet result;
2294 try {
2295 if (boolean_value == 0) pSession->bVerbose = false;
2296 else if (boolean_value == 1) pSession->bVerbose = true;
2297 else throw Exception("Not a boolean value, must either be 0 or 1");
2298 }
2299 catch (Exception e) {
2300 result.Error(e);
2301 }
2302 return result.Produce();
2303 }

  ViewVC Help
Powered by ViewVC