/[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 1353 - (show annotations) (download)
Mon Sep 17 23:15:25 2007 UTC (16 years, 6 months ago) by iliev
File size: 110840 byte(s)
* added new LSCP command: FORMAT INSTRUMENTS_DB

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, InstrumentsDb::toEscapedPath(Dir)));
150 }
151
152 void LSCPServer::DbInstrumentsEventHandler::DirectoryInfoChanged(String Dir) {
153 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_dir_info, InstrumentsDb::toEscapedPath(Dir)));
154 }
155
156 void LSCPServer::DbInstrumentsEventHandler::DirectoryNameChanged(String Dir, String NewName) {
157 Dir = "'" + InstrumentsDb::toEscapedPath(Dir) + "'";
158 NewName = "'" + InstrumentsDb::toEscapedPath(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, InstrumentsDb::toEscapedPath(Dir)));
164 }
165
166 void LSCPServer::DbInstrumentsEventHandler::InstrumentInfoChanged(String Instr) {
167 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_db_instr_info, InstrumentsDb::toEscapedPath(Instr)));
168 }
169
170 void LSCPServer::DbInstrumentsEventHandler::InstrumentNameChanged(String Instr, String NewName) {
171 Instr = "'" + InstrumentsDb::toEscapedPath(Instr) + "'";
172 NewName = "'" + InstrumentsDb::toEscapedPath(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 if (pEngineChannel->InstrumentStatus() < 0) throw Exception("No instrument loaded to sampler channel");
2177 Engine* pEngine = pEngineChannel->GetEngine();
2178 InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();
2179 if (!pInstrumentManager) throw Exception("Engine does not provide an instrument manager");
2180 InstrumentManager::instrument_id_t instrumentID;
2181 instrumentID.FileName = pEngineChannel->InstrumentFileName();
2182 instrumentID.Index = pEngineChannel->InstrumentIndex();
2183 pInstrumentManager->LaunchInstrumentEditor(instrumentID);
2184 } catch (Exception e) {
2185 result.Error(e);
2186 }
2187 return result.Produce();
2188 }
2189
2190 /**
2191 * Will be called by the parser to reset a particular sampler channel.
2192 */
2193 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
2194 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2195 LSCPResultSet result;
2196 try {
2197 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2198 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2199 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2200 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2201 pEngineChannel->Reset();
2202 }
2203 catch (Exception e) {
2204 result.Error(e);
2205 }
2206 return result.Produce();
2207 }
2208
2209 /**
2210 * Will be called by the parser to reset the whole sampler.
2211 */
2212 String LSCPServer::ResetSampler() {
2213 dmsg(2,("LSCPServer: ResetSampler()\n"));
2214 pSampler->Reset();
2215 LSCPResultSet result;
2216 return result.Produce();
2217 }
2218
2219 /**
2220 * Will be called by the parser to return general informations about this
2221 * sampler.
2222 */
2223 String LSCPServer::GetServerInfo() {
2224 dmsg(2,("LSCPServer: GetServerInfo()\n"));
2225 LSCPResultSet result;
2226 result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2227 result.Add("VERSION", VERSION);
2228 result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2229 #if HAVE_SQLITE3
2230 result.Add("INSTRUMENTS_DB_SUPPORT", "yes");
2231 #else
2232 result.Add("INSTRUMENTS_DB_SUPPORT", "no");
2233 #endif
2234
2235 return result.Produce();
2236 }
2237
2238 /**
2239 * Will be called by the parser to return the current number of all active voices.
2240 */
2241 String LSCPServer::GetTotalVoiceCount() {
2242 dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2243 LSCPResultSet result;
2244 result.Add(pSampler->GetVoiceCount());
2245 return result.Produce();
2246 }
2247
2248 /**
2249 * Will be called by the parser to return the maximum number of voices.
2250 */
2251 String LSCPServer::GetTotalVoiceCountMax() {
2252 dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2253 LSCPResultSet result;
2254 result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2255 return result.Produce();
2256 }
2257
2258 String LSCPServer::GetGlobalVolume() {
2259 LSCPResultSet result;
2260 result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2261 return result.Produce();
2262 }
2263
2264 String LSCPServer::SetGlobalVolume(double dVolume) {
2265 LSCPResultSet result;
2266 try {
2267 if (dVolume < 0) throw Exception("Volume may not be negative");
2268 GLOBAL_VOLUME = dVolume; // see common/global.cpp
2269 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
2270 } catch (Exception e) {
2271 result.Error(e);
2272 }
2273 return result.Produce();
2274 }
2275
2276 /**
2277 * Will be called by the parser to subscribe a client (frontend) on the
2278 * server for receiving event messages.
2279 */
2280 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
2281 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2282 LSCPResultSet result;
2283 SubscriptionMutex.Lock();
2284 eventSubscriptions[type].push_back(currentSocket);
2285 SubscriptionMutex.Unlock();
2286 return result.Produce();
2287 }
2288
2289 /**
2290 * Will be called by the parser to unsubscribe a client on the server
2291 * for not receiving further event messages.
2292 */
2293 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
2294 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2295 LSCPResultSet result;
2296 SubscriptionMutex.Lock();
2297 eventSubscriptions[type].remove(currentSocket);
2298 SubscriptionMutex.Unlock();
2299 return result.Produce();
2300 }
2301
2302 String LSCPServer::AddDbInstrumentDirectory(String Dir) {
2303 dmsg(2,("LSCPServer: AddDbInstrumentDirectory(Dir=%s)\n", Dir.c_str()));
2304 LSCPResultSet result;
2305 #if HAVE_SQLITE3
2306 try {
2307 InstrumentsDb::GetInstrumentsDb()->AddDirectory(Dir);
2308 } catch (Exception e) {
2309 result.Error(e);
2310 }
2311 #else
2312 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2313 #endif
2314 return result.Produce();
2315 }
2316
2317 String LSCPServer::RemoveDbInstrumentDirectory(String Dir, bool Force) {
2318 dmsg(2,("LSCPServer: RemoveDbInstrumentDirectory(Dir=%s,Force=%d)\n", Dir.c_str(), Force));
2319 LSCPResultSet result;
2320 #if HAVE_SQLITE3
2321 try {
2322 InstrumentsDb::GetInstrumentsDb()->RemoveDirectory(Dir, Force);
2323 } catch (Exception e) {
2324 result.Error(e);
2325 }
2326 #else
2327 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2328 #endif
2329 return result.Produce();
2330 }
2331
2332 String LSCPServer::GetDbInstrumentDirectoryCount(String Dir, bool Recursive) {
2333 dmsg(2,("LSCPServer: GetDbInstrumentDirectoryCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2334 LSCPResultSet result;
2335 #if HAVE_SQLITE3
2336 try {
2337 result.Add(InstrumentsDb::GetInstrumentsDb()->GetDirectoryCount(Dir, Recursive));
2338 } catch (Exception e) {
2339 result.Error(e);
2340 }
2341 #else
2342 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2343 #endif
2344 return result.Produce();
2345 }
2346
2347 String LSCPServer::GetDbInstrumentDirectories(String Dir, bool Recursive) {
2348 dmsg(2,("LSCPServer: GetDbInstrumentDirectories(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2349 LSCPResultSet result;
2350 #if HAVE_SQLITE3
2351 try {
2352 String list;
2353 StringListPtr dirs = InstrumentsDb::GetInstrumentsDb()->GetDirectories(Dir, Recursive);
2354
2355 for (int i = 0; i < dirs->size(); i++) {
2356 if (list != "") list += ",";
2357 list += "'" + InstrumentsDb::toEscapedPath(dirs->at(i)) + "'";
2358 }
2359
2360 result.Add(list);
2361 } catch (Exception e) {
2362 result.Error(e);
2363 }
2364 #else
2365 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2366 #endif
2367 return result.Produce();
2368 }
2369
2370 String LSCPServer::GetDbInstrumentDirectoryInfo(String Dir) {
2371 dmsg(2,("LSCPServer: GetDbInstrumentDirectoryInfo(Dir=%s)\n", Dir.c_str()));
2372 LSCPResultSet result;
2373 #if HAVE_SQLITE3
2374 try {
2375 DbDirectory info = InstrumentsDb::GetInstrumentsDb()->GetDirectoryInfo(Dir);
2376
2377 result.Add("DESCRIPTION", InstrumentsDb::toEscapedText(info.Description));
2378 result.Add("CREATED", info.Created);
2379 result.Add("MODIFIED", info.Modified);
2380 } catch (Exception e) {
2381 result.Error(e);
2382 }
2383 #else
2384 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2385 #endif
2386 return result.Produce();
2387 }
2388
2389 String LSCPServer::SetDbInstrumentDirectoryName(String Dir, String Name) {
2390 dmsg(2,("LSCPServer: SetDbInstrumentDirectoryName(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));
2391 LSCPResultSet result;
2392 #if HAVE_SQLITE3
2393 try {
2394 InstrumentsDb::GetInstrumentsDb()->RenameDirectory(Dir, Name);
2395 } catch (Exception e) {
2396 result.Error(e);
2397 }
2398 #else
2399 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2400 #endif
2401 return result.Produce();
2402 }
2403
2404 String LSCPServer::MoveDbInstrumentDirectory(String Dir, String Dst) {
2405 dmsg(2,("LSCPServer: MoveDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
2406 LSCPResultSet result;
2407 #if HAVE_SQLITE3
2408 try {
2409 InstrumentsDb::GetInstrumentsDb()->MoveDirectory(Dir, Dst);
2410 } catch (Exception e) {
2411 result.Error(e);
2412 }
2413 #else
2414 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2415 #endif
2416 return result.Produce();
2417 }
2418
2419 String LSCPServer::CopyDbInstrumentDirectory(String Dir, String Dst) {
2420 dmsg(2,("LSCPServer: CopyDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
2421 LSCPResultSet result;
2422 #if HAVE_SQLITE3
2423 try {
2424 InstrumentsDb::GetInstrumentsDb()->CopyDirectory(Dir, Dst);
2425 } catch (Exception e) {
2426 result.Error(e);
2427 }
2428 #else
2429 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2430 #endif
2431 return result.Produce();
2432 }
2433
2434 String LSCPServer::SetDbInstrumentDirectoryDescription(String Dir, String Desc) {
2435 dmsg(2,("LSCPServer: SetDbInstrumentDirectoryDescription(Dir=%s,Desc=%s)\n", Dir.c_str(), Desc.c_str()));
2436 LSCPResultSet result;
2437 #if HAVE_SQLITE3
2438 try {
2439 InstrumentsDb::GetInstrumentsDb()->SetDirectoryDescription(Dir, Desc);
2440 } catch (Exception e) {
2441 result.Error(e);
2442 }
2443 #else
2444 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2445 #endif
2446 return result.Produce();
2447 }
2448
2449 String LSCPServer::AddDbInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
2450 dmsg(2,("LSCPServer: AddDbInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));
2451 LSCPResultSet result;
2452 #if HAVE_SQLITE3
2453 try {
2454 int id;
2455 InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
2456 id = db->AddInstruments(DbDir, FilePath, Index, bBackground);
2457 if (bBackground) result = id;
2458 } catch (Exception e) {
2459 result.Error(e);
2460 }
2461 #else
2462 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2463 #endif
2464 return result.Produce();
2465 }
2466
2467 String LSCPServer::AddDbInstruments(String ScanMode, String DbDir, String FsDir, bool bBackground) {
2468 dmsg(2,("LSCPServer: AddDbInstruments(ScanMode=%s,DbDir=%s,FsDir=%s,bBackground=%d)\n", ScanMode.c_str(), DbDir.c_str(), FsDir.c_str(), bBackground));
2469 LSCPResultSet result;
2470 #if HAVE_SQLITE3
2471 try {
2472 int id;
2473 InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
2474 if (ScanMode.compare("RECURSIVE") == 0) {
2475 id = db->AddInstruments(RECURSIVE, DbDir, FsDir, bBackground);
2476 } else if (ScanMode.compare("NON_RECURSIVE") == 0) {
2477 id = db->AddInstruments(NON_RECURSIVE, DbDir, FsDir, bBackground);
2478 } else if (ScanMode.compare("FLAT") == 0) {
2479 id = db->AddInstruments(FLAT, DbDir, FsDir, bBackground);
2480 } else {
2481 throw Exception("Unknown scan mode: " + ScanMode);
2482 }
2483
2484 if (bBackground) result = id;
2485 } catch (Exception e) {
2486 result.Error(e);
2487 }
2488 #else
2489 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2490 #endif
2491 return result.Produce();
2492 }
2493
2494 String LSCPServer::RemoveDbInstrument(String Instr) {
2495 dmsg(2,("LSCPServer: RemoveDbInstrument(Instr=%s)\n", Instr.c_str()));
2496 LSCPResultSet result;
2497 #if HAVE_SQLITE3
2498 try {
2499 InstrumentsDb::GetInstrumentsDb()->RemoveInstrument(Instr);
2500 } catch (Exception e) {
2501 result.Error(e);
2502 }
2503 #else
2504 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2505 #endif
2506 return result.Produce();
2507 }
2508
2509 String LSCPServer::GetDbInstrumentCount(String Dir, bool Recursive) {
2510 dmsg(2,("LSCPServer: GetDbInstrumentCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2511 LSCPResultSet result;
2512 #if HAVE_SQLITE3
2513 try {
2514 result.Add(InstrumentsDb::GetInstrumentsDb()->GetInstrumentCount(Dir, Recursive));
2515 } catch (Exception e) {
2516 result.Error(e);
2517 }
2518 #else
2519 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2520 #endif
2521 return result.Produce();
2522 }
2523
2524 String LSCPServer::GetDbInstruments(String Dir, bool Recursive) {
2525 dmsg(2,("LSCPServer: GetDbInstruments(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
2526 LSCPResultSet result;
2527 #if HAVE_SQLITE3
2528 try {
2529 String list;
2530 StringListPtr instrs = InstrumentsDb::GetInstrumentsDb()->GetInstruments(Dir, Recursive);
2531
2532 for (int i = 0; i < instrs->size(); i++) {
2533 if (list != "") list += ",";
2534 list += "'" + InstrumentsDb::toEscapedPath(instrs->at(i)) + "'";
2535 }
2536
2537 result.Add(list);
2538 } catch (Exception e) {
2539 result.Error(e);
2540 }
2541 #else
2542 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2543 #endif
2544 return result.Produce();
2545 }
2546
2547 String LSCPServer::GetDbInstrumentInfo(String Instr) {
2548 dmsg(2,("LSCPServer: GetDbInstrumentInfo(Instr=%s)\n", Instr.c_str()));
2549 LSCPResultSet result;
2550 #if HAVE_SQLITE3
2551 try {
2552 DbInstrument info = InstrumentsDb::GetInstrumentsDb()->GetInstrumentInfo(Instr);
2553
2554 result.Add("INSTRUMENT_FILE", info.InstrFile);
2555 result.Add("INSTRUMENT_NR", info.InstrNr);
2556 result.Add("FORMAT_FAMILY", info.FormatFamily);
2557 result.Add("FORMAT_VERSION", info.FormatVersion);
2558 result.Add("SIZE", (int)info.Size);
2559 result.Add("CREATED", info.Created);
2560 result.Add("MODIFIED", info.Modified);
2561 result.Add("DESCRIPTION", InstrumentsDb::toEscapedText(info.Description));
2562 result.Add("IS_DRUM", info.IsDrum);
2563 result.Add("PRODUCT", InstrumentsDb::toEscapedText(info.Product));
2564 result.Add("ARTISTS", InstrumentsDb::toEscapedText(info.Artists));
2565 result.Add("KEYWORDS", InstrumentsDb::toEscapedText(info.Keywords));
2566 } catch (Exception e) {
2567 result.Error(e);
2568 }
2569 #else
2570 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2571 #endif
2572 return result.Produce();
2573 }
2574
2575 String LSCPServer::GetDbInstrumentsJobInfo(int JobId) {
2576 dmsg(2,("LSCPServer: GetDbInstrumentsJobInfo(JobId=%d)\n", JobId));
2577 LSCPResultSet result;
2578 #if HAVE_SQLITE3
2579 try {
2580 ScanJob job = InstrumentsDb::GetInstrumentsDb()->Jobs.GetJobById(JobId);
2581
2582 result.Add("FILES_TOTAL", job.FilesTotal);
2583 result.Add("FILES_SCANNED", job.FilesScanned);
2584 result.Add("SCANNING", job.Scanning);
2585 result.Add("STATUS", job.Status);
2586 } catch (Exception e) {
2587 result.Error(e);
2588 }
2589 #else
2590 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2591 #endif
2592 return result.Produce();
2593 }
2594
2595 String LSCPServer::SetDbInstrumentName(String Instr, String Name) {
2596 dmsg(2,("LSCPServer: SetDbInstrumentName(Instr=%s,Name=%s)\n", Instr.c_str(), Name.c_str()));
2597 LSCPResultSet result;
2598 #if HAVE_SQLITE3
2599 try {
2600 InstrumentsDb::GetInstrumentsDb()->RenameInstrument(Instr, Name);
2601 } catch (Exception e) {
2602 result.Error(e);
2603 }
2604 #else
2605 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2606 #endif
2607 return result.Produce();
2608 }
2609
2610 String LSCPServer::MoveDbInstrument(String Instr, String Dst) {
2611 dmsg(2,("LSCPServer: MoveDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
2612 LSCPResultSet result;
2613 #if HAVE_SQLITE3
2614 try {
2615 InstrumentsDb::GetInstrumentsDb()->MoveInstrument(Instr, Dst);
2616 } catch (Exception e) {
2617 result.Error(e);
2618 }
2619 #else
2620 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2621 #endif
2622 return result.Produce();
2623 }
2624
2625 String LSCPServer::CopyDbInstrument(String Instr, String Dst) {
2626 dmsg(2,("LSCPServer: CopyDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
2627 LSCPResultSet result;
2628 #if HAVE_SQLITE3
2629 try {
2630 InstrumentsDb::GetInstrumentsDb()->CopyInstrument(Instr, Dst);
2631 } catch (Exception e) {
2632 result.Error(e);
2633 }
2634 #else
2635 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2636 #endif
2637 return result.Produce();
2638 }
2639
2640 String LSCPServer::SetDbInstrumentDescription(String Instr, String Desc) {
2641 dmsg(2,("LSCPServer: SetDbInstrumentDescription(Instr=%s,Desc=%s)\n", Instr.c_str(), Desc.c_str()));
2642 LSCPResultSet result;
2643 #if HAVE_SQLITE3
2644 try {
2645 InstrumentsDb::GetInstrumentsDb()->SetInstrumentDescription(Instr, Desc);
2646 } catch (Exception e) {
2647 result.Error(e);
2648 }
2649 #else
2650 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2651 #endif
2652 return result.Produce();
2653 }
2654
2655 String LSCPServer::FindDbInstrumentDirectories(String Dir, std::map<String,String> Parameters, bool Recursive) {
2656 dmsg(2,("LSCPServer: FindDbInstrumentDirectories(Dir=%s)\n", Dir.c_str()));
2657 LSCPResultSet result;
2658 #if HAVE_SQLITE3
2659 try {
2660 SearchQuery Query;
2661 std::map<String,String>::iterator iter;
2662 for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
2663 if (iter->first.compare("NAME") == 0) {
2664 Query.Name = iter->second;
2665 } else if (iter->first.compare("CREATED") == 0) {
2666 Query.SetCreated(iter->second);
2667 } else if (iter->first.compare("MODIFIED") == 0) {
2668 Query.SetModified(iter->second);
2669 } else if (iter->first.compare("DESCRIPTION") == 0) {
2670 Query.Description = iter->second;
2671 } else {
2672 throw Exception("Unknown search criteria: " + iter->first);
2673 }
2674 }
2675
2676 String list;
2677 StringListPtr pDirectories =
2678 InstrumentsDb::GetInstrumentsDb()->FindDirectories(Dir, &Query, Recursive);
2679
2680 for (int i = 0; i < pDirectories->size(); i++) {
2681 if (list != "") list += ",";
2682 list += "'" + InstrumentsDb::toEscapedPath(pDirectories->at(i)) + "'";
2683 }
2684
2685 result.Add(list);
2686 } catch (Exception e) {
2687 result.Error(e);
2688 }
2689 #else
2690 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2691 #endif
2692 return result.Produce();
2693 }
2694
2695 String LSCPServer::FindDbInstruments(String Dir, std::map<String,String> Parameters, bool Recursive) {
2696 dmsg(2,("LSCPServer: FindDbInstruments(Dir=%s)\n", Dir.c_str()));
2697 LSCPResultSet result;
2698 #if HAVE_SQLITE3
2699 try {
2700 SearchQuery Query;
2701 std::map<String,String>::iterator iter;
2702 for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
2703 if (iter->first.compare("NAME") == 0) {
2704 Query.Name = iter->second;
2705 } else if (iter->first.compare("FORMAT_FAMILIES") == 0) {
2706 Query.SetFormatFamilies(iter->second);
2707 } else if (iter->first.compare("SIZE") == 0) {
2708 Query.SetSize(iter->second);
2709 } else if (iter->first.compare("CREATED") == 0) {
2710 Query.SetCreated(iter->second);
2711 } else if (iter->first.compare("MODIFIED") == 0) {
2712 Query.SetModified(iter->second);
2713 } else if (iter->first.compare("DESCRIPTION") == 0) {
2714 Query.Description = iter->second;
2715 } else if (iter->first.compare("IS_DRUM") == 0) {
2716 if (!strcasecmp(iter->second.c_str(), "true")) {
2717 Query.InstrType = SearchQuery::DRUM;
2718 } else {
2719 Query.InstrType = SearchQuery::CHROMATIC;
2720 }
2721 } else if (iter->first.compare("PRODUCT") == 0) {
2722 Query.Product = iter->second;
2723 } else if (iter->first.compare("ARTISTS") == 0) {
2724 Query.Artists = iter->second;
2725 } else if (iter->first.compare("KEYWORDS") == 0) {
2726 Query.Keywords = iter->second;
2727 } else {
2728 throw Exception("Unknown search criteria: " + iter->first);
2729 }
2730 }
2731
2732 String list;
2733 StringListPtr pInstruments =
2734 InstrumentsDb::GetInstrumentsDb()->FindInstruments(Dir, &Query, Recursive);
2735
2736 for (int i = 0; i < pInstruments->size(); i++) {
2737 if (list != "") list += ",";
2738 list += "'" + InstrumentsDb::toEscapedPath(pInstruments->at(i)) + "'";
2739 }
2740
2741 result.Add(list);
2742 } catch (Exception e) {
2743 result.Error(e);
2744 }
2745 #else
2746 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2747 #endif
2748 return result.Produce();
2749 }
2750
2751 String LSCPServer::FormatInstrumentsDb() {
2752 dmsg(2,("LSCPServer: FormatInstrumentsDb()\n"));
2753 LSCPResultSet result;
2754 #if HAVE_SQLITE3
2755 try {
2756 InstrumentsDb::GetInstrumentsDb()->Format();
2757 } catch (Exception e) {
2758 result.Error(e);
2759 }
2760 #else
2761 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
2762 #endif
2763 return result.Produce();
2764 }
2765
2766
2767 /**
2768 * Will be called by the parser to enable or disable echo mode; if echo
2769 * mode is enabled, all commands from the client will (immediately) be
2770 * echoed back to the client.
2771 */
2772 String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
2773 dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
2774 LSCPResultSet result;
2775 try {
2776 if (boolean_value == 0) pSession->bVerbose = false;
2777 else if (boolean_value == 1) pSession->bVerbose = true;
2778 else throw Exception("Not a boolean value, must either be 0 or 1");
2779 }
2780 catch (Exception e) {
2781 result.Error(e);
2782 }
2783 return result.Produce();
2784 }

  ViewVC Help
Powered by ViewVC