/[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 1252 - (show annotations) (download)
Sat Jun 23 15:54:18 2007 UTC (16 years, 10 months ago) by schoenebeck
File size: 110156 byte(s)
* LSCP server returns verbose syntax errors (line and column where
  syntax error occured, the unexpected character and the actually
  expected, possible character(s), the latter only if less than 5
  possibilities)

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

  ViewVC Help
Powered by ViewVC