/[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 1541 - (show annotations) (download)
Tue Dec 4 18:09:26 2007 UTC (16 years, 4 months ago) by iliev
File size: 122255 byte(s)
- Added support for monitoring the total number of active disk streams
  (new LSCP commands: GET TOTAL_STREAM_COUNT,
  SUBSCRIBE TOTAL_STREAM_COUNT, UNSUBSCRIBE TOTAL_STREAM_COUNT)

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

  ViewVC Help
Powered by ViewVC