/[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 1848 - (show annotations) (download)
Sat Feb 28 21:23:06 2009 UTC (15 years, 1 month ago) by iliev
File size: 132657 byte(s)
* close all connections when LSCPServer is deleted

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

  ViewVC Help
Powered by ViewVC