/[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 1161 - (show annotations) (download)
Mon Apr 16 15:51:18 2007 UTC (12 years, 5 months ago) by iliev
File size: 102825 byte(s)
* Implemented instruments database

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

  ViewVC Help
Powered by ViewVC