/[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 2531 - (show annotations) (download)
Wed Mar 5 00:02:21 2014 UTC (10 years, 1 month ago) by schoenebeck
File size: 162946 byte(s)
* LSCP shell: Added support for moving cursor left/right with arrow keys.
* Bumped version (1.0.0.svn35).

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

  ViewVC Help
Powered by ViewVC