/[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 2528 - (show annotations) (download)
Mon Mar 3 12:02:40 2014 UTC (10 years, 1 month ago) by schoenebeck
File size: 162389 byte(s)
* LSCP shell: in case of multiple possibilities or non-terminal symbols,
  show them right to the current command line immediately while typing
  (no double tab required for this feature, as it would be the case in
  other shells)
* LSCP shell: fixed sluggish behavior when doing tab auto complete
* LSCP shell: fixed conflicting behavior between keyboard input and
  LSCP server evaluation result, that caused an inconsistent screen
  output (keybord input is now never printed directly on screen, only
  the result returned from LSCP server)

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 }
758 // backspace character - should only happen with shell
759 if (c == '\b') {
760 if (!bufferedCommands[socket].empty()) {
761 bufferedCommands[socket] = bufferedCommands[socket].substr(
762 0, bufferedCommands[socket].length() - 1
763 );
764 }
765 } else bufferedCommands[socket] += c;
766 // only if the other side is the LSCP shell application:
767 // check the current (incomplete) command line for syntax errors,
768 // possible completions and report everything back to the shell
769 if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
770 String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), true);
771 if (!s.empty() && (*iter).bShellInteract && i == input.size() - 1)
772 AnswerClient(s + "\n");
773 }
774 }
775
776 // handle network errors ...
777 if (result == 0) { //socket was selected, so 0 here means client has closed the connection
778 CloseConnection(iter);
779 return false;
780 }
781 #if defined(WIN32)
782 if (result == SOCKET_ERROR) {
783 int wsa_lasterror = WSAGetLastError();
784 if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.
785 return false;
786 dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));
787 CloseConnection(iter);
788 return false;
789 }
790 #else
791 if (result == -1) {
792 if (errno == EAGAIN) //Would block, try again later.
793 return false;
794 switch(errno) {
795 case EBADF:
796 dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
797 return false;
798 case ECONNREFUSED:
799 dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
800 return false;
801 case ENOTCONN:
802 dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
803 return false;
804 case ENOTSOCK:
805 dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
806 return false;
807 case EAGAIN:
808 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"));
809 return false;
810 case EINTR:
811 dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
812 return false;
813 case EFAULT:
814 dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
815 return false;
816 case EINVAL:
817 dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
818 return false;
819 case ENOMEM:
820 dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
821 return false;
822 default:
823 dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
824 return false;
825 }
826 CloseConnection(iter);
827 return false;
828 }
829 #endif
830
831 return false;
832 }
833
834 /**
835 * Will be called by the parser whenever it wants to send an answer to the
836 * client / frontend.
837 *
838 * @param ReturnMessage - message that will be send to the client
839 */
840 void LSCPServer::AnswerClient(String ReturnMessage) {
841 dmsg(2,("LSCPServer::AnswerClient(ReturnMessage='%s')", ReturnMessage.c_str()));
842 if (currentSocket != -1) {
843 LockGuard lock(NotifyMutex);
844
845 // just if other side is LSCP shell: in case respose is a multi-line
846 // one, then inform client about it before sending the actual mult-line
847 // response
848 if (GetCurrentYaccSession()->bShellInteract) {
849 // check if this is a multi-line response
850 int n = 0;
851 for (int i = 0; i < ReturnMessage.size(); ++i)
852 if (ReturnMessage[i] == '\n') ++n;
853 if (n >= 2) {
854 dmsg(2,("LSCP Shell <- expect mult-line response\n"));
855 String s = LSCP_SHK_EXPECT_MULTI_LINE "\r\n";
856 #ifdef MSG_NOSIGNAL
857 send(currentSocket, s.c_str(), s.size(), MSG_NOSIGNAL);
858 #else
859 send(currentSocket, s.c_str(), s.size(), 0);
860 #endif
861 }
862 }
863
864 #ifdef MSG_NOSIGNAL
865 send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
866 #else
867 send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
868 #endif
869 }
870 }
871
872 /**
873 * Find a created audio output device index.
874 */
875 int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
876 {
877 // Search for the created device to get its index
878 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
879 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
880 for (; iter != devices.end(); iter++) {
881 if (iter->second == pDevice)
882 return iter->first;
883 }
884 // Not found.
885 return -1;
886 }
887
888 /**
889 * Find a created midi input device index.
890 */
891 int LSCPServer::GetMidiInputDeviceIndex ( MidiInputDevice *pDevice )
892 {
893 // Search for the created device to get its index
894 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
895 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
896 for (; iter != devices.end(); iter++) {
897 if (iter->second == pDevice)
898 return iter->first;
899 }
900 // Not found.
901 return -1;
902 }
903
904 String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
905 dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
906 LSCPResultSet result;
907 try {
908 AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
909 // search for the created device to get its index
910 int index = GetAudioOutputDeviceIndex(pDevice);
911 if (index == -1) throw Exception("Internal error: could not find created audio output device.");
912 result = index; // success
913 }
914 catch (Exception e) {
915 result.Error(e);
916 }
917 return result.Produce();
918 }
919
920 String LSCPServer::CreateMidiInputDevice(String Driver, std::map<String,String> Parameters) {
921 dmsg(2,("LSCPServer: CreateMidiInputDevice(Driver=%s)\n", Driver.c_str()));
922 LSCPResultSet result;
923 try {
924 MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
925 // search for the created device to get its index
926 int index = GetMidiInputDeviceIndex(pDevice);
927 if (index == -1) throw Exception("Internal error: could not find created midi input device.");
928 result = index; // success
929 }
930 catch (Exception e) {
931 result.Error(e);
932 }
933 return result.Produce();
934 }
935
936 String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
937 dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
938 LSCPResultSet result;
939 try {
940 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
941 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
942 AudioOutputDevice* pDevice = devices[DeviceIndex];
943 pSampler->DestroyAudioOutputDevice(pDevice);
944 }
945 catch (Exception e) {
946 result.Error(e);
947 }
948 return result.Produce();
949 }
950
951 String LSCPServer::DestroyMidiInputDevice(uint DeviceIndex) {
952 dmsg(2,("LSCPServer: DestroyMidiInputDevice(DeviceIndex=%d)\n", DeviceIndex));
953 LSCPResultSet result;
954 try {
955 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
956 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
957 MidiInputDevice* pDevice = devices[DeviceIndex];
958 pSampler->DestroyMidiInputDevice(pDevice);
959 }
960 catch (Exception e) {
961 result.Error(e);
962 }
963 return result.Produce();
964 }
965
966 EngineChannel* LSCPServer::GetEngineChannel(uint uiSamplerChannel) {
967 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
968 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
969
970 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
971 if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
972
973 return pEngineChannel;
974 }
975
976 /**
977 * Will be called by the parser to load an instrument.
978 */
979 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
980 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
981 LSCPResultSet result;
982 try {
983 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
984 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
985 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
986 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
987 if (!pSamplerChannel->GetAudioOutputDevice())
988 throw Exception("No audio output device connected to sampler channel");
989 if (bBackground) {
990 InstrumentManager::instrument_id_t id;
991 id.FileName = Filename;
992 id.Index = uiInstrument;
993 InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
994 }
995 else {
996 // tell the engine channel which instrument to load
997 pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrument);
998 // actually start to load the instrument (blocks until completed)
999 pEngineChannel->LoadInstrument();
1000 }
1001 }
1002 catch (Exception e) {
1003 result.Error(e);
1004 }
1005 return result.Produce();
1006 }
1007
1008 /**
1009 * Will be called by the parser to assign a sampler engine type to a
1010 * sampler channel.
1011 */
1012 String LSCPServer::SetEngineType(String EngineName, uint uiSamplerChannel) {
1013 dmsg(2,("LSCPServer: SetEngineType(EngineName=%s,uiSamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
1014 LSCPResultSet result;
1015 try {
1016 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1017 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1018 LockGuard lock(RTNotifyMutex);
1019 pSamplerChannel->SetEngineType(EngineName);
1020 if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
1021 }
1022 catch (Exception e) {
1023 result.Error(e);
1024 }
1025 return result.Produce();
1026 }
1027
1028 /**
1029 * Will be called by the parser to get the amount of sampler channels.
1030 */
1031 String LSCPServer::GetChannels() {
1032 dmsg(2,("LSCPServer: GetChannels()\n"));
1033 LSCPResultSet result;
1034 result.Add(pSampler->SamplerChannels());
1035 return result.Produce();
1036 }
1037
1038 /**
1039 * Will be called by the parser to get the list of sampler channels.
1040 */
1041 String LSCPServer::ListChannels() {
1042 dmsg(2,("LSCPServer: ListChannels()\n"));
1043 String list;
1044 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1045 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1046 for (; iter != channels.end(); iter++) {
1047 if (list != "") list += ",";
1048 list += ToString(iter->first);
1049 }
1050 LSCPResultSet result;
1051 result.Add(list);
1052 return result.Produce();
1053 }
1054
1055 /**
1056 * Will be called by the parser to add a sampler channel.
1057 */
1058 String LSCPServer::AddChannel() {
1059 dmsg(2,("LSCPServer: AddChannel()\n"));
1060 SamplerChannel* pSamplerChannel;
1061 {
1062 LockGuard lock(RTNotifyMutex);
1063 pSamplerChannel = pSampler->AddSamplerChannel();
1064 }
1065 LSCPResultSet result(pSamplerChannel->Index());
1066 return result.Produce();
1067 }
1068
1069 /**
1070 * Will be called by the parser to remove a sampler channel.
1071 */
1072 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
1073 dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
1074 LSCPResultSet result;
1075 {
1076 LockGuard lock(RTNotifyMutex);
1077 pSampler->RemoveSamplerChannel(uiSamplerChannel);
1078 }
1079 return result.Produce();
1080 }
1081
1082 /**
1083 * Will be called by the parser to get the amount of all available engines.
1084 */
1085 String LSCPServer::GetAvailableEngines() {
1086 dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
1087 LSCPResultSet result;
1088 try {
1089 int n = EngineFactory::AvailableEngineTypes().size();
1090 result.Add(n);
1091 }
1092 catch (Exception e) {
1093 result.Error(e);
1094 }
1095 return result.Produce();
1096 }
1097
1098 /**
1099 * Will be called by the parser to get a list of all available engines.
1100 */
1101 String LSCPServer::ListAvailableEngines() {
1102 dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
1103 LSCPResultSet result;
1104 try {
1105 String s = EngineFactory::AvailableEngineTypesAsString();
1106 result.Add(s);
1107 }
1108 catch (Exception e) {
1109 result.Error(e);
1110 }
1111 return result.Produce();
1112 }
1113
1114 /**
1115 * Will be called by the parser to get descriptions for a particular
1116 * sampler engine.
1117 */
1118 String LSCPServer::GetEngineInfo(String EngineName) {
1119 dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
1120 LSCPResultSet result;
1121 {
1122 LockGuard lock(RTNotifyMutex);
1123 try {
1124 Engine* pEngine = EngineFactory::Create(EngineName);
1125 result.Add("DESCRIPTION", _escapeLscpResponse(pEngine->Description()));
1126 result.Add("VERSION", pEngine->Version());
1127 EngineFactory::Destroy(pEngine);
1128 }
1129 catch (Exception e) {
1130 result.Error(e);
1131 }
1132 }
1133 return result.Produce();
1134 }
1135
1136 /**
1137 * Will be called by the parser to get informations about a particular
1138 * sampler channel.
1139 */
1140 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
1141 dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
1142 LSCPResultSet result;
1143 try {
1144 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1145 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1146 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1147
1148 //Defaults values
1149 String EngineName = "NONE";
1150 float Volume = 0.0f;
1151 String InstrumentFileName = "NONE";
1152 String InstrumentName = "NONE";
1153 int InstrumentIndex = -1;
1154 int InstrumentStatus = -1;
1155 int AudioOutputChannels = 0;
1156 String AudioRouting;
1157 int Mute = 0;
1158 bool Solo = false;
1159 String MidiInstrumentMap = "NONE";
1160
1161 if (pEngineChannel) {
1162 EngineName = pEngineChannel->EngineName();
1163 AudioOutputChannels = pEngineChannel->Channels();
1164 Volume = pEngineChannel->Volume();
1165 InstrumentStatus = pEngineChannel->InstrumentStatus();
1166 InstrumentIndex = pEngineChannel->InstrumentIndex();
1167 if (InstrumentIndex != -1) {
1168 InstrumentFileName = pEngineChannel->InstrumentFileName();
1169 InstrumentName = pEngineChannel->InstrumentName();
1170 }
1171 for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
1172 if (AudioRouting != "") AudioRouting += ",";
1173 AudioRouting += ToString(pEngineChannel->OutputChannel(chan));
1174 }
1175 Mute = pEngineChannel->GetMute();
1176 Solo = pEngineChannel->GetSolo();
1177 if (pEngineChannel->UsesNoMidiInstrumentMap())
1178 MidiInstrumentMap = "NONE";
1179 else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
1180 MidiInstrumentMap = "DEFAULT";
1181 else
1182 MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
1183 }
1184
1185 result.Add("ENGINE_NAME", EngineName);
1186 result.Add("VOLUME", Volume);
1187
1188 //Some not-so-hardcoded stuff to make GUI look good
1189 result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
1190 result.Add("AUDIO_OUTPUT_CHANNELS", AudioOutputChannels);
1191 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
1192
1193 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
1194 result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
1195 if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
1196 else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
1197
1198 // convert the filename into the correct encoding as defined for LSCP
1199 // (especially in terms of special characters -> escape sequences)
1200 if (InstrumentFileName != "NONE" && InstrumentFileName != "") {
1201 #if WIN32
1202 InstrumentFileName = Path::fromWindows(InstrumentFileName).toLscp();
1203 #else
1204 // assuming POSIX
1205 InstrumentFileName = Path::fromPosix(InstrumentFileName).toLscp();
1206 #endif
1207 }
1208
1209 result.Add("INSTRUMENT_FILE", InstrumentFileName);
1210 result.Add("INSTRUMENT_NR", InstrumentIndex);
1211 result.Add("INSTRUMENT_NAME", _escapeLscpResponse(InstrumentName));
1212 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
1213 result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
1214 result.Add("SOLO", Solo);
1215 result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
1216 }
1217 catch (Exception e) {
1218 result.Error(e);
1219 }
1220 return result.Produce();
1221 }
1222
1223 /**
1224 * Will be called by the parser to get the amount of active voices on a
1225 * particular sampler channel.
1226 */
1227 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
1228 dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
1229 LSCPResultSet result;
1230 try {
1231 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1232 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1233 result.Add(pEngineChannel->GetEngine()->VoiceCount());
1234 }
1235 catch (Exception e) {
1236 result.Error(e);
1237 }
1238 return result.Produce();
1239 }
1240
1241 /**
1242 * Will be called by the parser to get the amount of active disk streams on a
1243 * particular sampler channel.
1244 */
1245 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
1246 dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
1247 LSCPResultSet result;
1248 try {
1249 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1250 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1251 result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
1252 }
1253 catch (Exception e) {
1254 result.Error(e);
1255 }
1256 return result.Produce();
1257 }
1258
1259 /**
1260 * Will be called by the parser to get the buffer fill states of all disk
1261 * streams on a particular sampler channel.
1262 */
1263 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
1264 dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
1265 LSCPResultSet result;
1266 try {
1267 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1268 if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
1269 if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
1270 else {
1271 switch (ResponseType) {
1272 case fill_response_bytes:
1273 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillBytes());
1274 break;
1275 case fill_response_percentage:
1276 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
1277 break;
1278 default:
1279 throw Exception("Unknown fill response type");
1280 }
1281 }
1282 }
1283 catch (Exception e) {
1284 result.Error(e);
1285 }
1286 return result.Produce();
1287 }
1288
1289 String LSCPServer::GetAvailableAudioOutputDrivers() {
1290 dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
1291 LSCPResultSet result;
1292 try {
1293 int n = AudioOutputDeviceFactory::AvailableDrivers().size();
1294 result.Add(n);
1295 }
1296 catch (Exception e) {
1297 result.Error(e);
1298 }
1299 return result.Produce();
1300 }
1301
1302 String LSCPServer::ListAvailableAudioOutputDrivers() {
1303 dmsg(2,("LSCPServer: ListAvailableAudioOutputDrivers()\n"));
1304 LSCPResultSet result;
1305 try {
1306 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
1307 result.Add(s);
1308 }
1309 catch (Exception e) {
1310 result.Error(e);
1311 }
1312 return result.Produce();
1313 }
1314
1315 String LSCPServer::GetAvailableMidiInputDrivers() {
1316 dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
1317 LSCPResultSet result;
1318 try {
1319 int n = MidiInputDeviceFactory::AvailableDrivers().size();
1320 result.Add(n);
1321 }
1322 catch (Exception e) {
1323 result.Error(e);
1324 }
1325 return result.Produce();
1326 }
1327
1328 String LSCPServer::ListAvailableMidiInputDrivers() {
1329 dmsg(2,("LSCPServer: ListAvailableMidiInputDrivers()\n"));
1330 LSCPResultSet result;
1331 try {
1332 String s = MidiInputDeviceFactory::AvailableDriversAsString();
1333 result.Add(s);
1334 }
1335 catch (Exception e) {
1336 result.Error(e);
1337 }
1338 return result.Produce();
1339 }
1340
1341 String LSCPServer::GetMidiInputDriverInfo(String Driver) {
1342 dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
1343 LSCPResultSet result;
1344 try {
1345 result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
1346 result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
1347
1348 std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
1349 if (parameters.size()) { // if there are parameters defined for this driver
1350 String s;
1351 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1352 for (;iter != parameters.end(); iter++) {
1353 if (s != "") s += ",";
1354 s += iter->first;
1355 delete iter->second;
1356 }
1357 result.Add("PARAMETERS", s);
1358 }
1359 }
1360 catch (Exception e) {
1361 result.Error(e);
1362 }
1363 return result.Produce();
1364 }
1365
1366 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
1367 dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
1368 LSCPResultSet result;
1369 try {
1370 result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
1371 result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
1372
1373 std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
1374 if (parameters.size()) { // if there are parameters defined for this driver
1375 String s;
1376 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1377 for (;iter != parameters.end(); iter++) {
1378 if (s != "") s += ",";
1379 s += iter->first;
1380 delete iter->second;
1381 }
1382 result.Add("PARAMETERS", s);
1383 }
1384 }
1385 catch (Exception e) {
1386 result.Error(e);
1387 }
1388 return result.Produce();
1389 }
1390
1391 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1392 dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
1393 LSCPResultSet result;
1394 try {
1395 DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
1396 result.Add("TYPE", pParameter->Type());
1397 result.Add("DESCRIPTION", pParameter->Description());
1398 result.Add("MANDATORY", pParameter->Mandatory());
1399 result.Add("FIX", pParameter->Fix());
1400 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1401 optional<String> oDepends = pParameter->Depends();
1402 optional<String> oDefault = pParameter->Default(DependencyList);
1403 optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
1404 optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
1405 optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
1406 if (oDepends) result.Add("DEPENDS", *oDepends);
1407 if (oDefault) result.Add("DEFAULT", *oDefault);
1408 if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
1409 if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
1410 if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1411 delete pParameter;
1412 }
1413 catch (Exception e) {
1414 result.Error(e);
1415 }
1416 return result.Produce();
1417 }
1418
1419 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1420 dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
1421 LSCPResultSet result;
1422 try {
1423 DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
1424 result.Add("TYPE", pParameter->Type());
1425 result.Add("DESCRIPTION", pParameter->Description());
1426 result.Add("MANDATORY", pParameter->Mandatory());
1427 result.Add("FIX", pParameter->Fix());
1428 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1429 optional<String> oDepends = pParameter->Depends();
1430 optional<String> oDefault = pParameter->Default(DependencyList);
1431 optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
1432 optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
1433 optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
1434 if (oDepends) result.Add("DEPENDS", *oDepends);
1435 if (oDefault) result.Add("DEFAULT", *oDefault);
1436 if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
1437 if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
1438 if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1439 delete pParameter;
1440 }
1441 catch (Exception e) {
1442 result.Error(e);
1443 }
1444 return result.Produce();
1445 }
1446
1447 String LSCPServer::GetAudioOutputDeviceCount() {
1448 dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
1449 LSCPResultSet result;
1450 try {
1451 uint count = pSampler->AudioOutputDevices();
1452 result.Add(count); // success
1453 }
1454 catch (Exception e) {
1455 result.Error(e);
1456 }
1457 return result.Produce();
1458 }
1459
1460 String LSCPServer::GetMidiInputDeviceCount() {
1461 dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
1462 LSCPResultSet result;
1463 try {
1464 uint count = pSampler->MidiInputDevices();
1465 result.Add(count); // success
1466 }
1467 catch (Exception e) {
1468 result.Error(e);
1469 }
1470 return result.Produce();
1471 }
1472
1473 String LSCPServer::GetAudioOutputDevices() {
1474 dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
1475 LSCPResultSet result;
1476 try {
1477 String s;
1478 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1479 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1480 for (; iter != devices.end(); iter++) {
1481 if (s != "") s += ",";
1482 s += ToString(iter->first);
1483 }
1484 result.Add(s);
1485 }
1486 catch (Exception e) {
1487 result.Error(e);
1488 }
1489 return result.Produce();
1490 }
1491
1492 String LSCPServer::GetMidiInputDevices() {
1493 dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
1494 LSCPResultSet result;
1495 try {
1496 String s;
1497 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1498 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1499 for (; iter != devices.end(); iter++) {
1500 if (s != "") s += ",";
1501 s += ToString(iter->first);
1502 }
1503 result.Add(s);
1504 }
1505 catch (Exception e) {
1506 result.Error(e);
1507 }
1508 return result.Produce();
1509 }
1510
1511 String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
1512 dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1513 LSCPResultSet result;
1514 try {
1515 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1516 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1517 AudioOutputDevice* pDevice = devices[DeviceIndex];
1518 result.Add("DRIVER", pDevice->Driver());
1519 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1520 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1521 for (; iter != parameters.end(); iter++) {
1522 result.Add(iter->first, iter->second->Value());
1523 }
1524 }
1525 catch (Exception e) {
1526 result.Error(e);
1527 }
1528 return result.Produce();
1529 }
1530
1531 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
1532 dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1533 LSCPResultSet result;
1534 try {
1535 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1536 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1537 MidiInputDevice* pDevice = devices[DeviceIndex];
1538 result.Add("DRIVER", pDevice->Driver());
1539 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1540 std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1541 for (; iter != parameters.end(); iter++) {
1542 result.Add(iter->first, iter->second->Value());
1543 }
1544 }
1545 catch (Exception e) {
1546 result.Error(e);
1547 }
1548 return result.Produce();
1549 }
1550 String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
1551 dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
1552 LSCPResultSet result;
1553 try {
1554 // get MIDI input device
1555 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1556 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1557 MidiInputDevice* pDevice = devices[DeviceIndex];
1558
1559 // get MIDI port
1560 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1561 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1562
1563 // return the values of all MIDI port parameters
1564 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1565 std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1566 for (; iter != parameters.end(); iter++) {
1567 result.Add(iter->first, iter->second->Value());
1568 }
1569 }
1570 catch (Exception e) {
1571 result.Error(e);
1572 }
1573 return result.Produce();
1574 }
1575
1576 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
1577 dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
1578 LSCPResultSet result;
1579 try {
1580 // get audio output device
1581 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1582 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1583 AudioOutputDevice* pDevice = devices[DeviceId];
1584
1585 // get audio channel
1586 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1587 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1588
1589 // return the values of all audio channel parameters
1590 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1591 std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1592 for (; iter != parameters.end(); iter++) {
1593 result.Add(iter->first, iter->second->Value());
1594 }
1595 }
1596 catch (Exception e) {
1597 result.Error(e);
1598 }
1599 return result.Produce();
1600 }
1601
1602 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
1603 dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
1604 LSCPResultSet result;
1605 try {
1606 // get MIDI input device
1607 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1608 if (!devices.count(DeviceId)) throw Exception("There is no midi input device with index " + ToString(DeviceId) + ".");
1609 MidiInputDevice* pDevice = devices[DeviceId];
1610
1611 // get midi port
1612 MidiInputPort* pPort = pDevice->GetPort(PortId);
1613 if (!pPort) throw Exception("Midi input device does not have port " + ToString(PortId) + ".");
1614
1615 // get desired port parameter
1616 std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1617 if (!parameters.count(ParameterName)) throw Exception("Midi port does not provide a parameter '" + ParameterName + "'.");
1618 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1619
1620 // return all fields of this audio channel parameter
1621 result.Add("TYPE", pParameter->Type());
1622 result.Add("DESCRIPTION", pParameter->Description());
1623 result.Add("FIX", pParameter->Fix());
1624 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1625 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1626 if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1627 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1628 }
1629 catch (Exception e) {
1630 result.Error(e);
1631 }
1632 return result.Produce();
1633 }
1634
1635 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
1636 dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
1637 LSCPResultSet result;
1638 try {
1639 // get audio output device
1640 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1641 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1642 AudioOutputDevice* pDevice = devices[DeviceId];
1643
1644 // get audio channel
1645 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1646 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1647
1648 // get desired audio channel parameter
1649 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1650 if (!parameters.count(ParameterName)) throw Exception("Audio channel does not provide a parameter '" + ParameterName + "'.");
1651 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1652
1653 // return all fields of this audio channel parameter
1654 result.Add("TYPE", pParameter->Type());
1655 result.Add("DESCRIPTION", pParameter->Description());
1656 result.Add("FIX", pParameter->Fix());
1657 result.Add("MULTIPLICITY", pParameter->Multiplicity());
1658 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1659 if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1660 if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1661 }
1662 catch (Exception e) {
1663 result.Error(e);
1664 }
1665 return result.Produce();
1666 }
1667
1668 String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
1669 dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
1670 LSCPResultSet result;
1671 try {
1672 // get audio output device
1673 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1674 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1675 AudioOutputDevice* pDevice = devices[DeviceId];
1676
1677 // get audio channel
1678 AudioChannel* pChannel = pDevice->Channel(ChannelId);
1679 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1680
1681 // get desired audio channel parameter
1682 std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1683 if (!parameters.count(ParamKey)) throw Exception("Audio channel does not provide a parameter '" + ParamKey + "'.");
1684 DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1685
1686 // set new channel parameter value
1687 pParameter->SetValue(ParamVal);
1688 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1689 }
1690 catch (Exception e) {
1691 result.Error(e);
1692 }
1693 return result.Produce();
1694 }
1695
1696 String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1697 dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1698 LSCPResultSet result;
1699 try {
1700 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1701 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1702 AudioOutputDevice* pDevice = devices[DeviceIndex];
1703 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1704 if (!parameters.count(ParamKey)) throw Exception("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1705 parameters[ParamKey]->SetValue(ParamVal);
1706 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1707 }
1708 catch (Exception e) {
1709 result.Error(e);
1710 }
1711 return result.Produce();
1712 }
1713
1714 String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1715 dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1716 LSCPResultSet result;
1717 try {
1718 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1719 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1720 MidiInputDevice* pDevice = devices[DeviceIndex];
1721 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1722 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1723 parameters[ParamKey]->SetValue(ParamVal);
1724 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1725 }
1726 catch (Exception e) {
1727 result.Error(e);
1728 }
1729 return result.Produce();
1730 }
1731
1732 String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1733 dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1734 LSCPResultSet result;
1735 try {
1736 // get MIDI input device
1737 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1738 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1739 MidiInputDevice* pDevice = devices[DeviceIndex];
1740
1741 // get MIDI port
1742 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1743 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1744
1745 // set port parameter value
1746 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1747 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1748 parameters[ParamKey]->SetValue(ParamVal);
1749 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1750 }
1751 catch (Exception e) {
1752 result.Error(e);
1753 }
1754 return result.Produce();
1755 }
1756
1757 /**
1758 * Will be called by the parser to change the audio output channel for
1759 * playback on a particular sampler channel.
1760 */
1761 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1762 dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1763 LSCPResultSet result;
1764 try {
1765 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1766 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1767 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1768 if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1769 if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1770 pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1771 }
1772 catch (Exception e) {
1773 result.Error(e);
1774 }
1775 return result.Produce();
1776 }
1777
1778 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1779 dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1780 LSCPResultSet result;
1781 {
1782 LockGuard lock(RTNotifyMutex);
1783 try {
1784 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1785 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1786 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1787 if (!devices.count(AudioDeviceId)) throw Exception("There is no audio output device with index " + ToString(AudioDeviceId));
1788 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1789 pSamplerChannel->SetAudioOutputDevice(pDevice);
1790 }
1791 catch (Exception e) {
1792 result.Error(e);
1793 }
1794 }
1795 return result.Produce();
1796 }
1797
1798 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1799 dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1800 LSCPResultSet result;
1801 {
1802 LockGuard lock(RTNotifyMutex);
1803 try {
1804 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1805 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1806 // Driver type name aliasing...
1807 if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1808 if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1809 // Check if there's one audio output device already created
1810 // for the intended audio driver type (AudioOutputDriver)...
1811 AudioOutputDevice *pDevice = NULL;
1812 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1813 std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1814 for (; iter != devices.end(); iter++) {
1815 if ((iter->second)->Driver() == AudioOutputDriver) {
1816 pDevice = iter->second;
1817 break;
1818 }
1819 }
1820 // If it doesn't exist, create a new one with default parameters...
1821 if (pDevice == NULL) {
1822 std::map<String,String> params;
1823 pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1824 }
1825 // Must have a device...
1826 if (pDevice == NULL)
1827 throw Exception("Internal error: could not create audio output device.");
1828 // Set it as the current channel device...
1829 pSamplerChannel->SetAudioOutputDevice(pDevice);
1830 }
1831 catch (Exception e) {
1832 result.Error(e);
1833 }
1834 }
1835 return result.Produce();
1836 }
1837
1838 String LSCPServer::AddChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId, uint MIDIPort) {
1839 dmsg(2,("LSCPServer: AddChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d, MIDIPort=%d)\n",uiSamplerChannel,MIDIDeviceId,MIDIPort));
1840 LSCPResultSet result;
1841 try {
1842 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1843 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1844
1845 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1846 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1847 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1848
1849 MidiInputPort* pPort = pDevice->GetPort(MIDIPort);
1850 if (!pPort) throw Exception("There is no MIDI input port with index " + ToString(MIDIPort) + " on MIDI input device with index " + ToString(MIDIDeviceId));
1851
1852 pSamplerChannel->Connect(pPort);
1853 } catch (Exception e) {
1854 result.Error(e);
1855 }
1856 return result.Produce();
1857 }
1858
1859 String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel) {
1860 dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d)\n",uiSamplerChannel));
1861 LSCPResultSet result;
1862 try {
1863 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1864 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1865 pSamplerChannel->DisconnectAllMidiInputPorts();
1866 } catch (Exception e) {
1867 result.Error(e);
1868 }
1869 return result.Produce();
1870 }
1871
1872 String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId) {
1873 dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d)\n",uiSamplerChannel,MIDIDeviceId));
1874 LSCPResultSet result;
1875 try {
1876 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1877 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1878
1879 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1880 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1881 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1882
1883 std::vector<MidiInputPort*> vPorts = pSamplerChannel->GetMidiInputPorts();
1884 for (int i = 0; i < vPorts.size(); ++i)
1885 if (vPorts[i]->GetDevice() == pDevice)
1886 pSamplerChannel->Disconnect(vPorts[i]);
1887
1888 } catch (Exception e) {
1889 result.Error(e);
1890 }
1891 return result.Produce();
1892 }
1893
1894 String LSCPServer::RemoveChannelMidiInput(uint uiSamplerChannel, uint MIDIDeviceId, uint MIDIPort) {
1895 dmsg(2,("LSCPServer: RemoveChannelMidiInput(uiSamplerChannel=%d, MIDIDeviceId=%d, MIDIPort=%d)\n",uiSamplerChannel,MIDIDeviceId,MIDIPort));
1896 LSCPResultSet result;
1897 try {
1898 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1899 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1900
1901 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1902 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1903 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1904
1905 MidiInputPort* pPort = pDevice->GetPort(MIDIPort);
1906 if (!pPort) throw Exception("There is no MIDI input port with index " + ToString(MIDIPort) + " on MIDI input device with index " + ToString(MIDIDeviceId));
1907
1908 pSamplerChannel->Disconnect(pPort);
1909 } catch (Exception e) {
1910 result.Error(e);
1911 }
1912 return result.Produce();
1913 }
1914
1915 String LSCPServer::ListChannelMidiInputs(uint uiSamplerChannel) {
1916 dmsg(2,("LSCPServer: ListChannelMidiInputs(uiSamplerChannel=%d)\n",uiSamplerChannel));
1917 LSCPResultSet result;
1918 try {
1919 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1920 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1921 std::vector<MidiInputPort*> vPorts = pSamplerChannel->GetMidiInputPorts();
1922
1923 String s;
1924 for (int i = 0; i < vPorts.size(); ++i) {
1925 const int iDeviceID = vPorts[i]->GetDevice()->MidiInputDeviceID();
1926 const int iPortNr = vPorts[i]->GetPortNumber();
1927 if (s.size()) s += ",";
1928 s += "{" + ToString(iDeviceID) + ","
1929 + ToString(iPortNr) + "}";
1930 }
1931 result.Add(s);
1932 } catch (Exception e) {
1933 result.Error(e);
1934 }
1935 return result.Produce();
1936 }
1937
1938 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1939 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1940 LSCPResultSet result;
1941 try {
1942 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1943 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1944 pSamplerChannel->SetMidiInputPort(MIDIPort);
1945 }
1946 catch (Exception e) {
1947 result.Error(e);
1948 }
1949 return result.Produce();
1950 }
1951
1952 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1953 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1954 LSCPResultSet result;
1955 try {
1956 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1957 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1958 pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1959 }
1960 catch (Exception e) {
1961 result.Error(e);
1962 }
1963 return result.Produce();
1964 }
1965
1966 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1967 dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1968 LSCPResultSet result;
1969 try {
1970 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1971 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1972 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1973 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1974 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1975 pSamplerChannel->SetMidiInputDevice(pDevice);
1976 }
1977 catch (Exception e) {
1978 result.Error(e);
1979 }
1980 return result.Produce();
1981 }
1982
1983 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1984 dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1985 LSCPResultSet result;
1986 try {
1987 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1988 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1989 // Driver type name aliasing...
1990 if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1991 // Check if there's one MIDI input device already created
1992 // for the intended MIDI driver type (MidiInputDriver)...
1993 MidiInputDevice *pDevice = NULL;
1994 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1995 std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1996 for (; iter != devices.end(); iter++) {
1997 if ((iter->second)->Driver() == MidiInputDriver) {
1998 pDevice = iter->second;
1999 break;
2000 }
2001 }
2002 // If it doesn't exist, create a new one with default parameters...
2003 if (pDevice == NULL) {
2004 std::map<String,String> params;
2005 pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
2006 // Make it with at least one initial port.
2007 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
2008 }
2009 // Must have a device...
2010 if (pDevice == NULL)
2011 throw Exception("Internal error: could not create MIDI input device.");
2012 // Set it as the current channel device...
2013 pSamplerChannel->SetMidiInputDevice(pDevice);
2014 }
2015 catch (Exception e) {
2016 result.Error(e);
2017 }
2018 return result.Produce();
2019 }
2020
2021 /**
2022 * Will be called by the parser to change the MIDI input device, port and channel on which
2023 * engine of a particular sampler channel should listen to.
2024 */
2025 String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
2026 dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
2027 LSCPResultSet result;
2028 try {
2029 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2030 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2031 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
2032 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
2033 MidiInputDevice* pDevice = devices[MIDIDeviceId];
2034 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
2035 }
2036 catch (Exception e) {
2037 result.Error(e);
2038 }
2039 return result.Produce();
2040 }
2041
2042 /**
2043 * Will be called by the parser to change the global volume factor on a
2044 * particular sampler channel.
2045 */
2046 String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
2047 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
2048 LSCPResultSet result;
2049 try {
2050 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2051 pEngineChannel->Volume(dVolume);
2052 }
2053 catch (Exception e) {
2054 result.Error(e);
2055 }
2056 return result.Produce();
2057 }
2058
2059 /**
2060 * Will be called by the parser to mute/unmute particular sampler channel.
2061 */
2062 String LSCPServer::SetChannelMute(bool bMute, uint uiSamplerChannel) {
2063 dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
2064 LSCPResultSet result;
2065 try {
2066 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2067
2068 if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
2069 else pEngineChannel->SetMute(1);
2070 } catch (Exception e) {
2071 result.Error(e);
2072 }
2073 return result.Produce();
2074 }
2075
2076 /**
2077 * Will be called by the parser to solo particular sampler channel.
2078 */
2079 String LSCPServer::SetChannelSolo(bool bSolo, uint uiSamplerChannel) {
2080 dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
2081 LSCPResultSet result;
2082 try {
2083 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2084
2085 bool oldSolo = pEngineChannel->GetSolo();
2086 bool hadSoloChannel = HasSoloChannel();
2087
2088 pEngineChannel->SetSolo(bSolo);
2089
2090 if(!oldSolo && bSolo) {
2091 if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
2092 if(!hadSoloChannel) MuteNonSoloChannels();
2093 }
2094
2095 if(oldSolo && !bSolo) {
2096 if(!HasSoloChannel()) UnmuteChannels();
2097 else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
2098 }
2099 } catch (Exception e) {
2100 result.Error(e);
2101 }
2102 return result.Produce();
2103 }
2104
2105 /**
2106 * Determines whether there is at least one solo channel in the channel list.
2107 *
2108 * @returns true if there is at least one solo channel in the channel list,
2109 * false otherwise.
2110 */
2111 bool LSCPServer::HasSoloChannel() {
2112 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
2113 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
2114 for (; iter != channels.end(); iter++) {
2115 EngineChannel* c = iter->second->GetEngineChannel();
2116 if(c && c->GetSolo()) return true;
2117 }
2118
2119 return false;
2120 }
2121
2122 /**
2123 * Mutes all unmuted non-solo channels. Notice that the channels are muted
2124 * with -1 which indicates that they are muted because of the presence
2125 * of a solo channel(s). Channels muted with -1 will be automatically unmuted
2126 * when there are no solo channels left.
2127 */
2128 void LSCPServer::MuteNonSoloChannels() {
2129 dmsg(2,("LSCPServer: MuteNonSoloChannels()\n"));
2130 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
2131 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
2132 for (; iter != channels.end(); iter++) {
2133 EngineChannel* c = iter->second->GetEngineChannel();
2134 if(c && !c->GetSolo() && !c->GetMute()) c->SetMute(-1);
2135 }
2136 }
2137
2138 /**
2139 * Unmutes all channels that are muted because of the presence
2140 * of a solo channel(s).
2141 */
2142 void LSCPServer::UnmuteChannels() {
2143 dmsg(2,("LSCPServer: UnmuteChannels()\n"));
2144 std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
2145 std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
2146 for (; iter != channels.end(); iter++) {
2147 EngineChannel* c = iter->second->GetEngineChannel();
2148 if(c && c->GetMute() == -1) c->SetMute(0);
2149 }
2150 }
2151
2152 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) {
2153 dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
2154
2155 midi_prog_index_t idx;
2156 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
2157 idx.midi_bank_lsb = MidiBank & 0x7f;
2158 idx.midi_prog = MidiProg;
2159
2160 MidiInstrumentMapper::entry_t entry;
2161 entry.EngineName = EngineType;
2162 entry.InstrumentFile = InstrumentFile;
2163 entry.InstrumentIndex = InstrumentIndex;
2164 entry.LoadMode = LoadMode;
2165 entry.Volume = Volume;
2166 entry.Name = Name;
2167
2168 LSCPResultSet result;
2169 try {
2170 // PERSISTENT mapping commands might block for a long time, so in
2171 // that case we add/replace the mapping in another thread in case
2172 // the NON_MODAL argument was supplied, non persistent mappings
2173 // should return immediately, so we don't need to do that for them
2174 bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
2175 MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
2176 } catch (Exception e) {
2177 result.Error(e);
2178 }
2179 return result.Produce();
2180 }
2181
2182 String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
2183 dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
2184
2185 midi_prog_index_t idx;
2186 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
2187 idx.midi_bank_lsb = MidiBank & 0x7f;
2188 idx.midi_prog = MidiProg;
2189
2190 LSCPResultSet result;
2191 try {
2192 MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
2193 } catch (Exception e) {
2194 result.Error(e);
2195 }
2196 return result.Produce();
2197 }
2198
2199 String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
2200 dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
2201 LSCPResultSet result;
2202 try {
2203 result.Add(MidiInstrumentMapper::GetInstrumentCount(MidiMapID));
2204 } catch (Exception e) {
2205 result.Error(e);
2206 }
2207 return result.Produce();
2208 }
2209
2210
2211 String LSCPServer::GetAllMidiInstrumentMappings() {
2212 dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
2213 LSCPResultSet result;
2214 try {
2215 result.Add(MidiInstrumentMapper::GetInstrumentCount());
2216 } catch (Exception e) {
2217 result.Error(e);
2218 }
2219 return result.Produce();
2220 }
2221
2222 String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
2223 dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
2224 LSCPResultSet result;
2225 try {
2226 MidiInstrumentMapper::entry_t entry = MidiInstrumentMapper::GetEntry(MidiMapID, MidiBank, MidiProg);
2227 // convert the filename into the correct encoding as defined for LSCP
2228 // (especially in terms of special characters -> escape sequences)
2229 #if WIN32
2230 const String instrumentFileName = Path::fromWindows(entry.InstrumentFile).toLscp();
2231 #else
2232 // assuming POSIX
2233 const String instrumentFileName = Path::fromPosix(entry.InstrumentFile).toLscp();
2234 #endif
2235
2236 result.Add("NAME", _escapeLscpResponse(entry.Name));
2237 result.Add("ENGINE_NAME", entry.EngineName);
2238 result.Add("INSTRUMENT_FILE", instrumentFileName);
2239 result.Add("INSTRUMENT_NR", (int) entry.InstrumentIndex);
2240 String instrumentName;
2241 Engine* pEngine = EngineFactory::Create(entry.EngineName);
2242 if (pEngine) {
2243 if (pEngine->GetInstrumentManager()) {
2244 InstrumentManager::instrument_id_t instrID;
2245 instrID.FileName = entry.InstrumentFile;
2246 instrID.Index = entry.InstrumentIndex;
2247 instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
2248 }
2249 EngineFactory::Destroy(pEngine);
2250 }
2251 result.Add("INSTRUMENT_NAME", _escapeLscpResponse(instrumentName));
2252 switch (entry.LoadMode) {
2253 case MidiInstrumentMapper::ON_DEMAND:
2254 result.Add("LOAD_MODE", "ON_DEMAND");
2255 break;
2256 case MidiInstrumentMapper::ON_DEMAND_HOLD:
2257 result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
2258 break;
2259 case MidiInstrumentMapper::PERSISTENT:
2260 result.Add("LOAD_MODE", "PERSISTENT");
2261 break;
2262 default:
2263 throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
2264 }
2265 result.Add("VOLUME", entry.Volume);
2266 } catch (Exception e) {
2267 result.Error(e);
2268 }
2269 return result.Produce();
2270 }
2271
2272 String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
2273 dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
2274 LSCPResultSet result;
2275 try {
2276 String s;
2277 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
2278 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
2279 for (; iter != mappings.end(); iter++) {
2280 if (s.size()) s += ",";
2281 s += "{" + ToString(MidiMapID) + ","
2282 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
2283 + ToString(int(iter->first.midi_prog)) + "}";
2284 }
2285 result.Add(s);
2286 } catch (Exception e) {
2287 result.Error(e);
2288 }
2289 return result.Produce();
2290 }
2291
2292 String LSCPServer::ListAllMidiInstrumentMappings() {
2293 dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
2294 LSCPResultSet result;
2295 try {
2296 std::vector<int> maps = MidiInstrumentMapper::Maps();
2297 String s;
2298 for (int i = 0; i < maps.size(); i++) {
2299 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
2300 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
2301 for (; iter != mappings.end(); iter++) {
2302 if (s.size()) s += ",";
2303 s += "{" + ToString(maps[i]) + ","
2304 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
2305 + ToString(int(iter->first.midi_prog)) + "}";
2306 }
2307 }
2308 result.Add(s);
2309 } catch (Exception e) {
2310 result.Error(e);
2311 }
2312 return result.Produce();
2313 }
2314
2315 String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
2316 dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
2317 LSCPResultSet result;
2318 try {
2319 MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
2320 } catch (Exception e) {
2321 result.Error(e);
2322 }
2323 return result.Produce();
2324 }
2325
2326 String LSCPServer::ClearAllMidiInstrumentMappings() {
2327 dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
2328 LSCPResultSet result;
2329 try {
2330 std::vector<int> maps = MidiInstrumentMapper::Maps();
2331 for (int i = 0; i < maps.size(); i++)
2332 MidiInstrumentMapper::RemoveAllEntries(maps[i]);
2333 } catch (Exception e) {
2334 result.Error(e);
2335 }
2336 return result.Produce();
2337 }
2338
2339 String LSCPServer::AddMidiInstrumentMap(String MapName) {
2340 dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
2341 LSCPResultSet result;
2342 try {
2343 int MapID = MidiInstrumentMapper::AddMap(MapName);
2344 result = LSCPResultSet(MapID);
2345 } catch (Exception e) {
2346 result.Error(e);
2347 }
2348 return result.Produce();
2349 }
2350
2351 String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
2352 dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
2353 LSCPResultSet result;
2354 try {
2355 MidiInstrumentMapper::RemoveMap(MidiMapID);
2356 } catch (Exception e) {
2357 result.Error(e);
2358 }
2359 return result.Produce();
2360 }
2361
2362 String LSCPServer::RemoveAllMidiInstrumentMaps() {
2363 dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
2364 LSCPResultSet result;
2365 try {
2366 MidiInstrumentMapper::RemoveAllMaps();
2367 } catch (Exception e) {
2368 result.Error(e);
2369 }
2370 return result.Produce();
2371 }
2372
2373 String LSCPServer::GetMidiInstrumentMaps() {
2374 dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
2375 LSCPResultSet result;
2376 try {
2377 result.Add(MidiInstrumentMapper::Maps().size());
2378 } catch (Exception e) {
2379 result.Error(e);
2380 }
2381 return result.Produce();
2382 }
2383
2384 String LSCPServer::ListMidiInstrumentMaps() {
2385 dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
2386 LSCPResultSet result;
2387 try {
2388 std::vector<int> maps = MidiInstrumentMapper::Maps();
2389 String sList;
2390 for (int i = 0; i < maps.size(); i++) {
2391 if (sList != "") sList += ",";
2392 sList += ToString(maps[i]);
2393 }
2394 result.Add(sList);
2395 } catch (Exception e) {
2396 result.Error(e);
2397 }
2398 return result.Produce();
2399 }
2400
2401 String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
2402 dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
2403 LSCPResultSet result;
2404 try {
2405 result.Add("NAME", _escapeLscpResponse(MidiInstrumentMapper::MapName(MidiMapID)));
2406 result.Add("DEFAULT", MidiInstrumentMapper::GetDefaultMap() == MidiMapID);
2407 } catch (Exception e) {
2408 result.Error(e);
2409 }
2410 return result.Produce();
2411 }
2412
2413 String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
2414 dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
2415 LSCPResultSet result;
2416 try {
2417 MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
2418 } catch (Exception e) {
2419 result.Error(e);
2420 }
2421 return result.Produce();
2422 }
2423
2424 /**
2425 * Set the MIDI instrument map the given sampler channel shall use for
2426 * handling MIDI program change messages. There are the following two
2427 * special (negative) values:
2428 *
2429 * - (-1) : set to NONE (ignore program changes)
2430 * - (-2) : set to DEFAULT map
2431 */
2432 String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
2433 dmsg(2,("LSCPServer: SetChannelMap()\n"));
2434 LSCPResultSet result;
2435 try {
2436 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2437
2438 if (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
2439 else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
2440 else pEngineChannel->SetMidiInstrumentMap(MidiMapID);
2441 } catch (Exception e) {
2442 result.Error(e);
2443 }
2444 return result.Produce();
2445 }
2446
2447 String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
2448 dmsg(2,("LSCPServer: CreateFxSend()\n"));
2449 LSCPResultSet result;
2450 try {
2451 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2452
2453 FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
2454 if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
2455
2456 result = LSCPResultSet(pFxSend->Id()); // success
2457 } catch (Exception e) {
2458 result.Error(e);
2459 }
2460 return result.Produce();
2461 }
2462
2463 String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
2464 dmsg(2,("LSCPServer: DestroyFxSend()\n"));
2465 LSCPResultSet result;
2466 try {
2467 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2468
2469 FxSend* pFxSend = NULL;
2470 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2471 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2472 pFxSend = pEngineChannel->GetFxSend(i);
2473 break;
2474 }
2475 }
2476 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2477 pEngineChannel->RemoveFxSend(pFxSend);
2478 } catch (Exception e) {
2479 result.Error(e);
2480 }
2481 return result.Produce();
2482 }
2483
2484 String LSCPServer::GetFxSends(uint uiSamplerChannel) {
2485 dmsg(2,("LSCPServer: GetFxSends()\n"));
2486 LSCPResultSet result;
2487 try {
2488 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2489
2490 result.Add(pEngineChannel->GetFxSendCount());
2491 } catch (Exception e) {
2492 result.Error(e);
2493 }
2494 return result.Produce();
2495 }
2496
2497 String LSCPServer::ListFxSends(uint uiSamplerChannel) {
2498 dmsg(2,("LSCPServer: ListFxSends()\n"));
2499 LSCPResultSet result;
2500 String list;
2501 try {
2502 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2503
2504 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2505 FxSend* pFxSend = pEngineChannel->GetFxSend(i);
2506 if (list != "") list += ",";
2507 list += ToString(pFxSend->Id());
2508 }
2509 result.Add(list);
2510 } catch (Exception e) {
2511 result.Error(e);
2512 }
2513 return result.Produce();
2514 }
2515
2516 FxSend* LSCPServer::GetFxSend(uint uiSamplerChannel, uint FxSendID) {
2517 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2518
2519 FxSend* pFxSend = NULL;
2520 for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2521 if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2522 pFxSend = pEngineChannel->GetFxSend(i);
2523 break;
2524 }
2525 }
2526 if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2527 return pFxSend;
2528 }
2529
2530 String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
2531 dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
2532 LSCPResultSet result;
2533 try {
2534 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2535 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2536
2537 // gather audio routing informations
2538 String AudioRouting;
2539 for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
2540 if (AudioRouting != "") AudioRouting += ",";
2541 AudioRouting += ToString(pFxSend->DestinationChannel(chan));
2542 }
2543
2544 const String sEffectRouting =
2545 (pFxSend->DestinationEffectChain() >= 0 && pFxSend->DestinationEffectChainPosition() >= 0)
2546 ? ToString(pFxSend->DestinationEffectChain()) + "," + ToString(pFxSend->DestinationEffectChainPosition())
2547 : "NONE";
2548
2549 // success
2550 result.Add("NAME", _escapeLscpResponse(pFxSend->Name()));
2551 result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
2552 result.Add("LEVEL", ToString(pFxSend->Level()));
2553 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
2554 result.Add("EFFECT", sEffectRouting);
2555 } catch (Exception e) {
2556 result.Error(e);
2557 }
2558 return result.Produce();
2559 }
2560
2561 String LSCPServer::SetFxSendName(uint uiSamplerChannel, uint FxSendID, String Name) {
2562 dmsg(2,("LSCPServer: SetFxSendName()\n"));
2563 LSCPResultSet result;
2564 try {
2565 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2566
2567 pFxSend->SetName(Name);
2568 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2569 } catch (Exception e) {
2570 result.Error(e);
2571 }
2572 return result.Produce();
2573 }
2574
2575 String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
2576 dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
2577 LSCPResultSet result;
2578 try {
2579 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2580
2581 pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2582 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2583 } catch (Exception e) {
2584 result.Error(e);
2585 }
2586 return result.Produce();
2587 }
2588
2589 String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2590 dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2591 LSCPResultSet result;
2592 try {
2593 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2594
2595 pFxSend->SetMidiController(MidiController);
2596 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2597 } catch (Exception e) {
2598 result.Error(e);
2599 }
2600 return result.Produce();
2601 }
2602
2603 String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2604 dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2605 LSCPResultSet result;
2606 try {
2607 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2608
2609 pFxSend->SetLevel((float)dLevel);
2610 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2611 } catch (Exception e) {
2612 result.Error(e);
2613 }
2614 return result.Produce();
2615 }
2616
2617 String LSCPServer::SetFxSendEffect(uint uiSamplerChannel, uint FxSendID, int iSendEffectChain, int iEffectChainPosition) {
2618 dmsg(2,("LSCPServer: SetFxSendEffect(%d,%d)\n", iSendEffectChain, iEffectChainPosition));
2619 LSCPResultSet result;
2620 try {
2621 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2622
2623 pFxSend->SetDestinationEffect(iSendEffectChain, iEffectChainPosition);
2624 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2625 } catch (Exception e) {
2626 result.Error(e);
2627 }
2628 return result.Produce();
2629 }
2630
2631 String LSCPServer::GetAvailableEffects() {
2632 dmsg(2,("LSCPServer: GetAvailableEffects()\n"));
2633 LSCPResultSet result;
2634 try {
2635 int n = EffectFactory::AvailableEffectsCount();
2636 result.Add(n);
2637 }
2638 catch (Exception e) {
2639 result.Error(e);
2640 }
2641 return result.Produce();
2642 }
2643
2644 String LSCPServer::ListAvailableEffects() {
2645 dmsg(2,("LSCPServer: ListAvailableEffects()\n"));
2646 LSCPResultSet result;
2647 String list;
2648 try {
2649 //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
2650 int n = EffectFactory::AvailableEffectsCount();
2651 for (int i = 0; i < n; i++) {
2652 if (i) list += ",";
2653 list += ToString(i);
2654 }
2655 }
2656 catch (Exception e) {
2657 result.Error(e);
2658 }
2659 result.Add(list);
2660 return result.Produce();
2661 }
2662
2663 String LSCPServer::GetEffectInfo(int iEffectIndex) {
2664 dmsg(2,("LSCPServer: GetEffectInfo(%d)\n", iEffectIndex));
2665 LSCPResultSet result;
2666 try {
2667 EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(iEffectIndex);
2668 if (!pEffectInfo)
2669 throw Exception("There is no effect with index " + ToString(iEffectIndex));
2670
2671 // convert the filename into the correct encoding as defined for LSCP
2672 // (especially in terms of special characters -> escape sequences)
2673 #if WIN32
2674 const String dllFileName = Path::fromWindows(pEffectInfo->Module()).toLscp();
2675 #else
2676 // assuming POSIX
2677 const String dllFileName = Path::fromPosix(pEffectInfo->Module()).toLscp();
2678 #endif
2679
2680 result.Add("SYSTEM", pEffectInfo->EffectSystem());
2681 result.Add("MODULE", dllFileName);
2682 result.Add("NAME", _escapeLscpResponse(pEffectInfo->Name()));
2683 result.Add("DESCRIPTION", _escapeLscpResponse(pEffectInfo->Description()));
2684 }
2685 catch (Exception e) {
2686 result.Error(e);
2687 }
2688 return result.Produce();
2689 }
2690
2691 String LSCPServer::GetEffectInstanceInfo(int iEffectInstance) {
2692 dmsg(2,("LSCPServer: GetEffectInstanceInfo(%d)\n", iEffectInstance));
2693 LSCPResultSet result;
2694 try {
2695 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2696 if (!pEffect)
2697 throw Exception("There is no effect instance with ID " + ToString(iEffectInstance));
2698
2699 EffectInfo* pEffectInfo = pEffect->GetEffectInfo();
2700
2701 // convert the filename into the correct encoding as defined for LSCP
2702 // (especially in terms of special characters -> escape sequences)
2703 #if WIN32
2704 const String dllFileName = Path::fromWindows(pEffectInfo->Module()).toLscp();
2705 #else
2706 // assuming POSIX
2707 const String dllFileName = Path::fromPosix(pEffectInfo->Module()).toLscp();
2708 #endif
2709
2710 result.Add("SYSTEM", pEffectInfo->EffectSystem());
2711 result.Add("MODULE", dllFileName);
2712 result.Add("NAME", _escapeLscpResponse(pEffectInfo->Name()));
2713 result.Add("DESCRIPTION", _escapeLscpResponse(pEffectInfo->Description()));
2714 result.Add("INPUT_CONTROLS", ToString(pEffect->InputControlCount()));
2715 }
2716 catch (Exception e) {
2717 result.Error(e);
2718 }
2719 return result.Produce();
2720 }
2721
2722 String LSCPServer::GetEffectInstanceInputControlInfo(int iEffectInstance, int iInputControlIndex) {
2723 dmsg(2,("LSCPServer: GetEffectInstanceInputControlInfo(%d,%d)\n", iEffectInstance, iInputControlIndex));
2724 LSCPResultSet result;
2725 try {
2726 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2727 if (!pEffect)
2728 throw Exception("There is no effect instance with ID " + ToString(iEffectInstance));
2729
2730 EffectControl* pEffectControl = pEffect->InputControl(iInputControlIndex);
2731 if (!pEffectControl)
2732 throw Exception(
2733 "Effect instance " + ToString(iEffectInstance) +
2734 " does not have an input control with index " +
2735 ToString(iInputControlIndex)
2736 );
2737
2738 result.Add("DESCRIPTION", _escapeLscpResponse(pEffectControl->Description()));
2739 result.Add("VALUE", pEffectControl->Value());
2740 if (pEffectControl->MinValue())
2741 result.Add("RANGE_MIN", *pEffectControl->MinValue());
2742 if (pEffectControl->MaxValue())
2743 result.Add("RANGE_MAX", *pEffectControl->MaxValue());
2744 if (!pEffectControl->Possibilities().empty())
2745 result.Add("POSSIBILITIES", pEffectControl->Possibilities());
2746 if (pEffectControl->DefaultValue())
2747 result.Add("DEFAULT", *pEffectControl->DefaultValue());
2748 } catch (Exception e) {
2749 result.Error(e);
2750 }
2751 return result.Produce();
2752 }
2753
2754 String LSCPServer::SetEffectInstanceInputControlValue(int iEffectInstance, int iInputControlIndex, double dValue) {
2755 dmsg(2,("LSCPServer: SetEffectInstanceInputControlValue(%d,%d,%f)\n", iEffectInstance, iInputControlIndex, dValue));
2756 LSCPResultSet result;
2757 try {
2758 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2759 if (!pEffect)
2760 throw Exception("There is no effect instance with ID " + ToString(iEffectInstance));
2761
2762 EffectControl* pEffectControl = pEffect->InputControl(iInputControlIndex);
2763 if (!pEffectControl)
2764 throw Exception(
2765 "Effect instance " + ToString(iEffectInstance) +
2766 " does not have an input control with index " +
2767 ToString(iInputControlIndex)
2768 );
2769
2770 pEffectControl->SetValue(dValue);
2771 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_instance_info, iEffectInstance));
2772 } catch (Exception e) {
2773 result.Error(e);
2774 }
2775 return result.Produce();
2776 }
2777
2778 String LSCPServer::CreateEffectInstance(int iEffectIndex) {
2779 dmsg(2,("LSCPServer: CreateEffectInstance(%d)\n", iEffectIndex));
2780 LSCPResultSet result;
2781 try {
2782 EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(iEffectIndex);
2783 if (!pEffectInfo)
2784 throw Exception("There is no effect with index " + ToString(iEffectIndex));
2785 Effect* pEffect = EffectFactory::Create(pEffectInfo);
2786 result = pEffect->ID(); // success
2787 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_instance_count, EffectFactory::EffectInstancesCount()));
2788 } catch (Exception e) {
2789 result.Error(e);
2790 }
2791 return result.Produce();
2792 }
2793
2794 String LSCPServer::CreateEffectInstance(String effectSystem, String module, String effectName) {
2795 dmsg(2,("LSCPServer: CreateEffectInstance('%s','%s','%s')\n", effectSystem.c_str(), module.c_str(), effectName.c_str()));
2796 LSCPResultSet result;
2797 try {
2798 // to allow loading the same LSCP session file on different systems
2799 // successfully, probably with different effect plugin DLL paths or even
2800 // running completely different operating systems, we do the following
2801 // for finding the right effect:
2802 //
2803 // first try to search for an exact match of the effect plugin DLL
2804 // (a.k.a 'module'), to avoid picking the wrong DLL with the same
2805 // effect name ...
2806 EffectInfo* pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_MATCH_EXACTLY);
2807 // ... if no effect with exactly matchin DLL filename was found, then
2808 // try to lower the restrictions of matching the effect plugin DLL
2809 // filename and try again and again ...
2810 if (!pEffectInfo) {
2811 dmsg(2,("no exact module match, trying MODULE_IGNORE_PATH\n"));
2812 pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH);
2813 }
2814 if (!pEffectInfo) {
2815 dmsg(2,("no module match, trying MODULE_IGNORE_PATH | MODULE_IGNORE_CASE\n"));
2816 pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH | EffectFactory::MODULE_IGNORE_CASE);
2817 }
2818 if (!pEffectInfo) {
2819 dmsg(2,("no module match, trying MODULE_IGNORE_PATH | MODULE_IGNORE_CASE | MODULE_IGNORE_EXTENSION\n"));
2820 pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_PATH | EffectFactory::MODULE_IGNORE_CASE | EffectFactory::MODULE_IGNORE_EXTENSION);
2821 }
2822 // ... if there was still no effect found, then completely ignore the
2823 // DLL plugin filename argument and just search for the matching effect
2824 // system type and effect name
2825 if (!pEffectInfo) {
2826 dmsg(2,("no module match, trying MODULE_IGNORE_ALL\n"));
2827 pEffectInfo = EffectFactory::GetEffectInfo(effectSystem, module, effectName, EffectFactory::MODULE_IGNORE_ALL);
2828 }
2829 if (!pEffectInfo)
2830 throw Exception("There is no such effect '" + effectSystem + "' '" + module + "' '" + effectName + "'");
2831
2832 Effect* pEffect = EffectFactory::Create(pEffectInfo);
2833 result = LSCPResultSet(pEffect->ID());
2834 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_instance_count, EffectFactory::EffectInstancesCount()));
2835 } catch (Exception e) {
2836 result.Error(e);
2837 }
2838 return result.Produce();
2839 }
2840
2841 String LSCPServer::DestroyEffectInstance(int iEffectInstance) {
2842 dmsg(2,("LSCPServer: DestroyEffectInstance(%d)\n", iEffectInstance));
2843 LSCPResultSet result;
2844 try {
2845 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
2846 if (!pEffect)
2847 throw Exception("There is no effect instance with ID " + ToString(iEffectInstance));
2848 EffectFactory::Destroy(pEffect);
2849 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_instance_count, EffectFactory::EffectInstancesCount()));
2850 } catch (Exception e) {
2851 result.Error(e);
2852 }
2853 return result.Produce();
2854 }
2855
2856 String LSCPServer::GetEffectInstances() {
2857 dmsg(2,("LSCPServer: GetEffectInstances()\n"));
2858 LSCPResultSet result;
2859 try {
2860 int n = EffectFactory::EffectInstancesCount();
2861 result.Add(n);
2862 } catch (Exception e) {
2863 result.Error(e);
2864 }
2865 return result.Produce();
2866 }
2867
2868 String LSCPServer::ListEffectInstances() {
2869 dmsg(2,("LSCPServer: ListEffectInstances()\n"));
2870 LSCPResultSet result;
2871 String list;
2872 try {
2873 int n = EffectFactory::EffectInstancesCount();
2874 for (int i = 0; i < n; i++) {
2875 Effect* pEffect = EffectFactory::GetEffectInstance(i);
2876 if (i) list += ",";
2877 list += ToString(pEffect->ID());
2878 }
2879 } catch (Exception e) {
2880 result.Error(e);
2881 }
2882 result.Add(list);
2883 return result.Produce();
2884 }
2885
2886 String LSCPServer::GetSendEffectChains(int iAudioOutputDevice) {
2887 dmsg(2,("LSCPServer: GetSendEffectChains(%d)\n", iAudioOutputDevice));
2888 LSCPResultSet result;
2889 try {
2890 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2891 if (!devices.count(iAudioOutputDevice))
2892 throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2893 AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2894 int n = pDevice->SendEffectChainCount();
2895 result.Add(n);
2896 } catch (Exception e) {
2897 result.Error(e);
2898 }
2899 return result.Produce();
2900 }
2901
2902 String LSCPServer::ListSendEffectChains(int iAudioOutputDevice) {
2903 dmsg(2,("LSCPServer: ListSendEffectChains(%d)\n", iAudioOutputDevice));
2904 LSCPResultSet result;
2905 String list;
2906 try {
2907 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2908 if (!devices.count(iAudioOutputDevice))
2909 throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2910 AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2911 int n = pDevice->SendEffectChainCount();
2912 for (int i = 0; i < n; i++) {
2913 EffectChain* pEffectChain = pDevice->SendEffectChain(i);
2914 if (i) list += ",";
2915 list += ToString(pEffectChain->ID());
2916 }
2917 } catch (Exception e) {
2918 result.Error(e);
2919 }
2920 result.Add(list);
2921 return result.Produce();
2922 }
2923
2924 String LSCPServer::AddSendEffectChain(int iAudioOutputDevice) {
2925 dmsg(2,("LSCPServer: AddSendEffectChain(%d)\n", iAudioOutputDevice));
2926 LSCPResultSet result;
2927 try {
2928 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2929 if (!devices.count(iAudioOutputDevice))
2930 throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2931 AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2932 EffectChain* pEffectChain = pDevice->AddSendEffectChain();
2933 result = pEffectChain->ID();
2934 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_send_fx_chain_count, iAudioOutputDevice, pDevice->SendEffectChainCount()));
2935 } catch (Exception e) {
2936 result.Error(e);
2937 }
2938 return result.Produce();
2939 }
2940
2941 String LSCPServer::RemoveSendEffectChain(int iAudioOutputDevice, int iSendEffectChain) {
2942 dmsg(2,("LSCPServer: RemoveSendEffectChain(%d,%d)\n", iAudioOutputDevice, iSendEffectChain));
2943 LSCPResultSet result;
2944 try {
2945 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2946 if (!devices.count(iAudioOutputDevice))
2947 throw Exception("There is no audio output device with index " + ToString(iAudioOutputDevice) + ".");
2948
2949 std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
2950 std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
2951 std::set<EngineChannel*>::iterator itEnd = engineChannels.end();
2952 for (; itEngineChannel != itEnd; ++itEngineChannel) {
2953 AudioOutputDevice* pDev = (*itEngineChannel)->GetAudioOutputDevice();
2954 if (pDev != NULL && pDev->deviceId() == iAudioOutputDevice) {
2955 for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
2956 FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
2957 if(fxs != NULL && fxs->DestinationEffectChain() == iSendEffectChain) {
2958 throw Exception("The effect chain is still in use by channel " + ToString((*itEngineChannel)->GetSamplerChannel()->Index()));
2959 }
2960 }
2961 }
2962 }
2963
2964 AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2965 for (int i = 0; i < pDevice->SendEffectChainCount(); i++) {
2966 EffectChain* pEffectChain = pDevice->SendEffectChain(i);
2967 if (pEffectChain->ID() == iSendEffectChain) {
2968 pDevice->RemoveSendEffectChain(i);
2969 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_send_fx_chain_count, iAudioOutputDevice, pDevice->SendEffectChainCount()));
2970 return result.Produce();
2971 }
2972 }
2973 throw Exception(
2974 "There is no send effect chain with ID " +
2975 ToString(iSendEffectChain) + " for audio output device " +
2976 ToString(iAudioOutputDevice) + "."
2977 );
2978 } catch (Exception e) {
2979 result.Error(e);
2980 }
2981 return result.Produce();
2982 }
2983
2984 static EffectChain* _getSendEffectChain(Sampler* pSampler, int iAudioOutputDevice, int iSendEffectChain) throw (Exception) {
2985 std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
2986 if (!devices.count(iAudioOutputDevice))
2987 throw Exception(
2988 "There is no audio output device with index " +
2989 ToString(iAudioOutputDevice) + "."
2990 );
2991 AudioOutputDevice* pDevice = devices[iAudioOutputDevice];
2992 EffectChain* pEffectChain = pDevice->SendEffectChainByID(iSendEffectChain);
2993 if(pEffectChain != NULL) return pEffectChain;
2994 throw Exception(
2995 "There is no send effect chain with ID " +
2996 ToString(iSendEffectChain) + " for audio output device " +
2997 ToString(iAudioOutputDevice) + "."
2998 );
2999 }
3000
3001 String LSCPServer::GetSendEffectChainInfo(int iAudioOutputDevice, int iSendEffectChain) {
3002 dmsg(2,("LSCPServer: GetSendEffectChainInfo(%d,%d)\n", iAudioOutputDevice, iSendEffectChain));
3003 LSCPResultSet result;
3004 try {
3005 EffectChain* pEffectChain =
3006 _getSendEffectChain(pSampler, iAudioOutputDevice, iSendEffectChain);
3007 String sEffectSequence;
3008 for (int i = 0; i < pEffectChain->EffectCount(); i++) {
3009 if (i) sEffectSequence += ",";
3010 sEffectSequence += ToString(pEffectChain->GetEffect(i)->ID());
3011 }
3012 result.Add("EFFECT_COUNT", pEffectChain->EffectCount());
3013 result.Add("EFFECT_SEQUENCE", sEffectSequence);
3014 } catch (Exception e) {
3015 result.Error(e);
3016 }
3017 return result.Produce();
3018 }
3019
3020 String LSCPServer::AppendSendEffectChainEffect(int iAudioOutputDevice, int iSendEffectChain, int iEffectInstance) {
3021 dmsg(2,("LSCPServer: AppendSendEffectChainEffect(%d,%d,%d)\n", iAudioOutputDevice, iSendEffectChain, iEffectInstance));
3022 LSCPResultSet result;
3023 try {
3024 EffectChain* pEffectChain =
3025 _getSendEffectChain(pSampler, iAudioOutputDevice, iSendEffectChain);
3026 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
3027 if (!pEffect)
3028 throw Exception("There is no effect instance with ID " + ToString(iEffectInstance));
3029 pEffectChain->AppendEffect(pEffect);
3030 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_send_fx_chain_info, iAudioOutputDevice, iSendEffectChain, pEffectChain->EffectCount()));
3031 } catch (Exception e) {
3032 result.Error(e);
3033 }
3034 return result.Produce();
3035 }
3036
3037 String LSCPServer::InsertSendEffectChainEffect(int iAudioOutputDevice, int iSendEffectChain, int iEffectChainPosition, int iEffectInstance) {
3038 dmsg(2,("LSCPServer: InsertSendEffectChainEffect(%d,%d,%d,%d)\n", iAudioOutputDevice, iSendEffectChain, iEffectChainPosition, iEffectInstance));
3039 LSCPResultSet result;
3040 try {
3041 EffectChain* pEffectChain =
3042 _getSendEffectChain(pSampler, iAudioOutputDevice, iSendEffectChain);
3043 Effect* pEffect = EffectFactory::GetEffectInstanceByID(iEffectInstance);
3044 if (!pEffect)
3045 throw Exception("There is no effect instance with index " + ToString(iEffectInstance));
3046 pEffectChain->InsertEffect(pEffect, iEffectChainPosition);
3047 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_send_fx_chain_info, iAudioOutputDevice, iSendEffectChain, pEffectChain->EffectCount()));
3048 } catch (Exception e) {
3049 result.Error(e);
3050 }
3051 return result.Produce();
3052 }
3053
3054 String LSCPServer::RemoveSendEffectChainEffect(int iAudioOutputDevice, int iSendEffectChain, int iEffectChainPosition) {
3055 dmsg(2,("LSCPServer: RemoveSendEffectChainEffect(%d,%d,%d)\n", iAudioOutputDevice, iSendEffectChain, iEffectChainPosition));
3056 LSCPResultSet result;
3057 try {
3058 EffectChain* pEffectChain =
3059 _getSendEffectChain(pSampler, iAudioOutputDevice, iSendEffectChain);
3060
3061 std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
3062 std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
3063 std::set<EngineChannel*>::iterator itEnd = engineChannels.end();
3064 for (; itEngineChannel != itEnd; ++itEngineChannel) {
3065 AudioOutputDevice* pDev = (*itEngineChannel)->GetAudioOutputDevice();
3066 if (pDev != NULL && pDev->deviceId() == iAudioOutputDevice) {
3067 for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
3068 FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
3069 if(fxs != NULL && fxs->DestinationEffectChain() == iSendEffectChain && fxs->DestinationEffectChainPosition() == iEffectChainPosition) {
3070 throw Exception("The effect instance is still in use by channel " + ToString((*itEngineChannel)->GetSamplerChannel()->Index()));
3071 }
3072 }
3073 }
3074 }
3075
3076 pEffectChain->RemoveEffect(iEffectChainPosition);
3077 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_send_fx_chain_info, iAudioOutputDevice, iSendEffectChain, pEffectChain->EffectCount()));
3078 } catch (Exception e) {
3079 result.Error(e);
3080 }
3081 return result.Produce();
3082 }
3083
3084 String LSCPServer::EditSamplerChannelInstrument(uint uiSamplerChannel) {
3085 dmsg(2,("LSCPServer: EditSamplerChannelInstrument(SamplerChannel=%d)\n", uiSamplerChannel));
3086 LSCPResultSet result;
3087 try {
3088 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
3089 if (pEngineChannel->InstrumentStatus() < 0) throw Exception("No instrument loaded to sampler channel");
3090 Engine* pEngine = pEngineChannel->GetEngine();
3091 InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();
3092 if (!pInstrumentManager) throw Exception("Engine does not provide an instrument manager");
3093 InstrumentManager::instrument_id_t instrumentID;
3094 instrumentID.FileName = pEngineChannel->InstrumentFileName();
3095 instrumentID.Index = pEngineChannel->InstrumentIndex();
3096 pInstrumentManager->LaunchInstrumentEditor(instrumentID);
3097 } catch (Exception e) {
3098 result.Error(e);
3099 }
3100 return result.Produce();
3101 }
3102
3103 String LSCPServer::SendChannelMidiData(String MidiMsg, uint uiSamplerChannel, uint Arg1, uint Arg2) {
3104 dmsg(2,("LSCPServer: SendChannelMidiData(MidiMsg=%s,uiSamplerChannel=%d,Arg1=%d,Arg2=%d)\n", MidiMsg.c_str(), uiSamplerChannel, Arg1, Arg2));
3105 LSCPResultSet result;
3106 try {
3107 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
3108
3109 if (Arg1 > 127 || Arg2 > 127) {
3110 throw Exception("Invalid MIDI message");
3111 }
3112
3113 VirtualMidiDevice* pMidiDevice = NULL;
3114 std::vector<EventHandler::midi_listener_entry>::iterator iter = eventHandler.channelMidiListeners.begin();
3115 for (; iter != eventHandler.channelMidiListeners.end(); ++iter) {
3116 if ((*iter).pEngineChannel == pEngineChannel) {
3117 pMidiDevice = (*iter).pMidiListener;
3118 break;
3119 }
3120 }
3121
3122 if(pMidiDevice == NULL) throw Exception("Couldn't find virtual MIDI device");
3123
3124 if (MidiMsg == "NOTE_ON") {
3125 pMidiDevice->SendNoteOnToDevice(Arg1, Arg2);
3126 bool b = pMidiDevice->SendNoteOnToSampler(Arg1, Arg2);
3127 if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
3128 } else if (MidiMsg == "NOTE_OFF") {
3129 pMidiDevice->SendNoteOffToDevice(Arg1, Arg2);
3130 bool b = pMidiDevice->SendNoteOffToSampler(Arg1, Arg2);
3131 if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
3132 } else if (MidiMsg == "CC") {
3133 pMidiDevice->SendCCToDevice(Arg1, Arg2);
3134 bool b = pMidiDevice->SendCCToSampler(Arg1, Arg2);
3135 if (!b) throw Exception("MIDI event failed: " + MidiMsg + " " + ToString(Arg1) + " " + ToString(Arg2));
3136 } else {
3137 throw Exception("Unknown MIDI message type: " + MidiMsg);
3138 }
3139 } catch (Exception e) {
3140 result.Error(e);
3141 }
3142 return result.Produce();
3143 }
3144
3145 /**
3146 * Will be called by the parser to reset a particular sampler channel.
3147 */
3148 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
3149 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
3150 LSCPResultSet result;
3151 try {
3152 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
3153 pEngineChannel->Reset();
3154 }
3155 catch (Exception e) {
3156 result.Error(e);
3157 }
3158 return result.Produce();
3159 }
3160
3161 /**
3162 * Will be called by the parser to reset the whole sampler.
3163 */
3164 String LSCPServer::ResetSampler() {
3165 dmsg(2,("LSCPServer: ResetSampler()\n"));
3166 pSampler->Reset();
3167 LSCPResultSet result;
3168 return result.Produce();
3169 }
3170
3171 /**
3172 * Will be called by the parser to return general informations about this
3173 * sampler.
3174 */
3175 String LSCPServer::GetServerInfo() {
3176 dmsg(2,("LSCPServer: GetServerInfo()\n"));
3177 const std::string description =
3178 _escapeLscpResponse("LinuxSampler - modular, streaming capable sampler");
3179 LSCPResultSet result;
3180 result.Add("DESCRIPTION", description);
3181 result.Add("VERSION", VERSION);
3182 result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
3183 #if HAVE_SQLITE3
3184 result.Add("INSTRUMENTS_DB_SUPPORT", "yes");
3185 #else
3186 result.Add("INSTRUMENTS_DB_SUPPORT", "no");
3187 #endif
3188
3189 return result.Produce();
3190 }
3191
3192 /**
3193 * Will be called by the parser to return the current number of all active streams.
3194 */
3195 String LSCPServer::GetTotalStreamCount() {
3196 dmsg(2,("LSCPServer: GetTotalStreamCount()\n"));
3197 LSCPResultSet result;
3198 result.Add(pSampler->GetDiskStreamCount());
3199 return result.Produce();
3200 }
3201
3202 /**
3203 * Will be called by the parser to return the current number of all active voices.
3204 */
3205 String LSCPServer::GetTotalVoiceCount() {
3206 dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
3207 LSCPResultSet result;
3208 result.Add(pSampler->GetVoiceCount());
3209 return result.Produce();
3210 }
3211
3212 /**
3213 * Will be called by the parser to return the maximum number of voices.
3214 */
3215 String LSCPServer::GetTotalVoiceCountMax() {
3216 dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
3217 LSCPResultSet result;
3218 result.Add(EngineFactory::EngineInstances().size() * pSampler->GetGlobalMaxVoices());
3219 return result.Produce();
3220 }
3221
3222 /**
3223 * Will be called by the parser to return the sampler global maximum
3224 * allowed number of voices.
3225 */
3226 String LSCPServer::GetGlobalMaxVoices() {
3227 dmsg(2,("LSCPServer: GetGlobalMaxVoices()\n"));
3228 LSCPResultSet result;
3229 result.Add(pSampler->GetGlobalMaxVoices());
3230 return result.Produce();
3231 }
3232
3233 /**
3234 * Will be called by the parser to set the sampler global maximum number of
3235 * voices.
3236 */
3237 String LSCPServer::SetGlobalMaxVoices(int iVoices) {
3238 dmsg(2,("LSCPServer: SetGlobalMaxVoices(%d)\n", iVoices));
3239 LSCPResultSet result;
3240 try {
3241 pSampler->SetGlobalMaxVoices(iVoices);
3242 LSCPServer::SendLSCPNotify(
3243 LSCPEvent(LSCPEvent::event_global_info, "VOICES", pSampler->GetGlobalMaxVoices())
3244 );
3245 } catch (Exception e) {
3246 result.Error(e);
3247 }
3248 return result.Produce();
3249 }
3250
3251 /**
3252 * Will be called by the parser to return the sampler global maximum
3253 * allowed number of disk streams.
3254 */
3255 String LSCPServer::GetGlobalMaxStreams() {
3256 dmsg(2,("LSCPServer: GetGlobalMaxStreams()\n"));
3257 LSCPResultSet result;
3258 result.Add(pSampler->GetGlobalMaxStreams());
3259 return result.Produce();
3260 }
3261
3262 /**
3263 * Will be called by the parser to set the sampler global maximum number of
3264 * disk streams.
3265 */
3266 String LSCPServer::SetGlobalMaxStreams(int iStreams) {
3267 dmsg(2,("LSCPServer: SetGlobalMaxStreams(%d)\n", iStreams));
3268 LSCPResultSet result;
3269 try {
3270 pSampler->SetGlobalMaxStreams(iStreams);
3271 LSCPServer::SendLSCPNotify(
3272 LSCPEvent(LSCPEvent::event_global_info, "STREAMS", pSampler->GetGlobalMaxStreams())
3273 );
3274 } catch (Exception e) {
3275 result.Error(e);
3276 }
3277 return result.Produce();
3278 }
3279
3280 String LSCPServer::GetGlobalVolume() {
3281 LSCPResultSet result;
3282 result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
3283 return result.Produce();
3284 }
3285
3286 String LSCPServer::SetGlobalVolume(double dVolume) {
3287 LSCPResultSet result;
3288 try {
3289 if (dVolume < 0) throw Exception("Volume may not be negative");
3290 GLOBAL_VOLUME = dVolume; // see common/global_private.cpp
3291 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
3292 } catch (Exception e) {
3293 result.Error(e);
3294 }
3295 return result.Produce();
3296 }
3297
3298 String LSCPServer::GetFileInstruments(String Filename) {
3299 dmsg(2,("LSCPServer: GetFileInstruments(String Filename=%s)\n",Filename.c_str()));
3300 LSCPResultSet result;
3301 try {
3302 VerifyFile(Filename);
3303 } catch (Exception e) {
3304 result.Error(e);
3305 return result.Produce();
3306 }
3307 // try to find a sampler engine that can handle the file
3308 bool bFound = false;
3309 std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
3310 for (int i = 0; !bFound && i < engineTypes.size(); i++) {
3311 Engine* pEngine = NULL;
3312 try {
3313 pEngine = EngineFactory::Create(engineTypes[i]);
3314 if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
3315 InstrumentManager* pManager = pEngine->GetInstrumentManager();
3316 if (pManager) {
3317 std::vector<InstrumentManager::instrument_id_t> IDs =
3318 pManager->GetInstrumentFileContent(Filename);
3319 // return the amount of instruments in the file
3320 result.Add(IDs.size());
3321 // no more need to ask other engine types
3322 bFound = true;
3323 } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
3324 } catch (Exception e) {
3325 // NOOP, as exception is thrown if engine doesn't support file
3326 }
3327 if (pEngine) EngineFactory::Destroy(pEngine);
3328 }
3329
3330 if (!bFound) result.Error("Unknown file format");
3331 return result.Produce();
3332 }
3333
3334 String LSCPServer::ListFileInstruments(String Filename) {
3335 dmsg(2,("LSCPServer: ListFileInstruments(String Filename=%s)\n",Filename.c_str()));
3336 LSCPResultSet result;
3337 try {
3338 VerifyFile(Filename);
3339 } catch (Exception e) {
3340 result.Error(e);
3341 return result.Produce();
3342 }
3343 // try to find a sampler engine that can handle the file
3344 bool bFound = false;
3345 std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
3346 for (int i = 0; !bFound && i < engineTypes.size(); i++) {
3347 Engine* pEngine = NULL;
3348 try {
3349 pEngine = EngineFactory::Create(engineTypes[i]);
3350 if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
3351 InstrumentManager* pManager = pEngine->GetInstrumentManager();
3352 if (pManager) {
3353 std::vector<InstrumentManager::instrument_id_t> IDs =
3354 pManager->GetInstrumentFileContent(Filename);
3355 // return a list of IDs of the instruments in the file
3356 String s;
3357 for (int j = 0; j < IDs.size(); j++) {
3358 if (s.size()) s += ",";
3359 s += ToString(IDs[j].Index);
3360 }
3361 result.Add(s);
3362 // no more need to ask other engine types
3363 bFound = true;
3364 } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
3365 } catch (Exception e) {
3366 // NOOP, as exception is thrown if engine doesn't support file
3367 }
3368 if (pEngine) EngineFactory::Destroy(pEngine);
3369 }
3370
3371 if (!bFound) result.Error("Unknown file format");
3372 return result.Produce();
3373 }
3374
3375 String LSCPServer::GetFileInstrumentInfo(String Filename, uint InstrumentID) {
3376 dmsg(2,("LSCPServer: GetFileInstrumentInfo(String Filename=%s, InstrumentID=%d)\n",Filename.c_str(),InstrumentID));
3377 LSCPResultSet result;
3378 try {
3379 VerifyFile(Filename);
3380 } catch (Exception e) {
3381 result.Error(e);
3382 return result.Produce();
3383 }
3384 InstrumentManager::instrument_id_t id;
3385 id.FileName = Filename;
3386 id.Index = InstrumentID;
3387 // try to find a sampler engine that can handle the file
3388 bool bFound = false;
3389 bool bFatalErr = false;
3390 std::vector<String> engineTypes = EngineFactory::AvailableEngineTypes();
3391 for (int i = 0; !bFound && !bFatalErr && i < engineTypes.size(); i++) {
3392 Engine* pEngine = NULL;
3393 try {
3394 pEngine = EngineFactory::Create(engineTypes[i]);
3395 if (!pEngine) throw Exception("Internal error: could not create '" + engineTypes[i] + "' engine");
3396 InstrumentManager* pManager = pEngine->GetInstrumentManager();
3397 if (pManager) {
3398 // check if the instrument index is valid
3399 // FIXME: this won't work if an engine only supports parts of the instrument file
3400 std::vector<InstrumentManager::instrument_id_t> IDs =
3401 pManager->GetInstrumentFileContent(Filename);
3402 if (std::find(IDs.begin(), IDs.end(), id) == IDs.end()) {
3403 std::stringstream ss;
3404 ss << "Invalid instrument index " << InstrumentID << " for instrument file '" << Filename << "'";
3405 bFatalErr = true;
3406 throw Exception(ss.str());
3407 }
3408 // get the info of the requested instrument
3409 InstrumentManager::instrument_info_t info =
3410 pManager->GetInstrumentInfo(id);
3411 // return detailed informations about the file
3412 result.Add("NAME", info.InstrumentName);
3413 result.Add("FORMAT_FAMILY", engineTypes[i]);
3414 result.Add("FORMAT_VERSION", info.FormatVersion);
3415 result.Add("PRODUCT", info.Product);
3416 result.Add("ARTISTS", info.Artists);
3417
3418 std::stringstream ss;
3419 bool b = false;
3420 for (int i = 0; i < 128; i++) {
3421 if (info.KeyBindings[i]) {
3422 if (b) ss << ',';
3423 ss << i; b = true;
3424 }
3425 }
3426 result.Add("KEY_BINDINGS", ss.str());
3427
3428 b = false;
3429 std::stringstream ss2;
3430 for (int i = 0; i < 128; i++) {
3431 if (info.KeySwitchBindings[i]) {
3432 if (b) ss2 << ',';
3433 ss2 << i; b = true;
3434 }
3435 }
3436 result.Add("KEYSWITCH_BINDINGS", ss2.str());
3437 // no more need to ask other engine types
3438 bFound = true;
3439 } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
3440 } catch (Exception e) {
3441 // usually NOOP, as exception is thrown if engine doesn't support file
3442 if (bFatalErr) result.Error(e);
3443 }
3444 if (pEngine) EngineFactory::Destroy(pEngine);
3445 }
3446
3447 if (!bFound && !bFatalErr) result.Error("Unknown file format");
3448 return result.Produce();
3449 }
3450
3451 void LSCPServer::VerifyFile(String Filename) {
3452 #if WIN32
3453 WIN32_FIND_DATA win32FileAttributeData;
3454 BOOL res = GetFileAttributesEx( Filename.c_str(), GetFileExInfoStandard, &win32FileAttributeData );
3455 if (!res) {
3456 std::stringstream ss;
3457 ss << "File does not exist, GetFileAttributesEx failed `" << Filename << "`: Error " << GetLastError();
3458 throw Exception(ss.str());
3459 }
3460 if ( win32FileAttributeData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
3461 throw Exception("Directory is specified");
3462 }
3463 #else
3464 File f(Filename);
3465 if(!f.Exist()) throw Exception(f.GetErrorMsg());
3466 if (f.IsDirectory()) throw Exception("Directory is specified");
3467 #endif
3468 }
3469
3470 /**
3471 * Will be called by the parser to subscribe a client (frontend) on the
3472 * server for receiving event messages.
3473 */
3474 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
3475 dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
3476 LSCPResultSet result;
3477 {
3478 LockGuard lock(SubscriptionMutex);
3479 eventSubscriptions[type].push_back(currentSocket);
3480 }
3481 return result.Produce();
3482 }
3483
3484 /**
3485 * Will be called by the parser to unsubscribe a client on the server
3486 * for not receiving further event messages.
3487 */
3488 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
3489 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
3490 LSCPResultSet result;
3491 {
3492 LockGuard lock(SubscriptionMutex);
3493 eventSubscriptions[type].remove(currentSocket);
3494 }
3495 return result.Produce();
3496 }
3497
3498 String LSCPServer::AddDbInstrumentDirectory(String Dir) {
3499 dmsg(2,("LSCPServer: AddDbInstrumentDirectory(Dir=%s)\n", Dir.c_str()));
3500 LSCPResultSet result;
3501 #if HAVE_SQLITE3
3502 try {
3503 InstrumentsDb::GetInstrumentsDb()->AddDirectory(Dir);
3504 } catch (Exception e) {
3505 result.Error(e);
3506 }
3507 #else
3508 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3509 #endif
3510 return result.Produce();
3511 }
3512
3513 String LSCPServer::RemoveDbInstrumentDirectory(String Dir, bool Force) {
3514 dmsg(2,("LSCPServer: RemoveDbInstrumentDirectory(Dir=%s,Force=%d)\n", Dir.c_str(), Force));
3515 LSCPResultSet result;
3516 #if HAVE_SQLITE3
3517 try {
3518 InstrumentsDb::GetInstrumentsDb()->RemoveDirectory(Dir, Force);
3519 } catch (Exception e) {
3520 result.Error(e);
3521 }
3522 #else
3523 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3524 #endif
3525 return result.Produce();
3526 }
3527
3528 String LSCPServer::GetDbInstrumentDirectoryCount(String Dir, bool Recursive) {
3529 dmsg(2,("LSCPServer: GetDbInstrumentDirectoryCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
3530 LSCPResultSet result;
3531 #if HAVE_SQLITE3
3532 try {
3533 result.Add(InstrumentsDb::GetInstrumentsDb()->GetDirectoryCount(Dir, Recursive));
3534 } catch (Exception e) {
3535 result.Error(e);
3536 }
3537 #else
3538 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3539 #endif
3540 return result.Produce();
3541 }
3542
3543 String LSCPServer::GetDbInstrumentDirectories(String Dir, bool Recursive) {
3544 dmsg(2,("LSCPServer: GetDbInstrumentDirectories(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
3545 LSCPResultSet result;
3546 #if HAVE_SQLITE3
3547 try {
3548 String list;
3549 StringListPtr dirs = InstrumentsDb::GetInstrumentsDb()->GetDirectories(Dir, Recursive);
3550
3551 for (int i = 0; i < dirs->size(); i++) {
3552 if (list != "") list += ",";
3553 list += "'" + InstrumentsDb::toEscapedPath(dirs->at(i)) + "'";
3554 }
3555
3556 result.Add(list);
3557 } catch (Exception e) {
3558 result.Error(e);
3559 }
3560 #else
3561 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3562 #endif
3563 return result.Produce();
3564 }
3565
3566 String LSCPServer::GetDbInstrumentDirectoryInfo(String Dir) {
3567 dmsg(2,("LSCPServer: GetDbInstrumentDirectoryInfo(Dir=%s)\n", Dir.c_str()));
3568 LSCPResultSet result;
3569 #if HAVE_SQLITE3
3570 try {
3571 DbDirectory info = InstrumentsDb::GetInstrumentsDb()->GetDirectoryInfo(Dir);
3572
3573 result.Add("DESCRIPTION", _escapeLscpResponse(info.Description));
3574 result.Add("CREATED", info.Created);
3575 result.Add("MODIFIED", info.Modified);
3576 } catch (Exception e) {
3577 result.Error(e);
3578 }
3579 #else
3580 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3581 #endif
3582 return result.Produce();
3583 }
3584
3585 String LSCPServer::SetDbInstrumentDirectoryName(String Dir, String Name) {
3586 dmsg(2,("LSCPServer: SetDbInstrumentDirectoryName(Dir=%s,Name=%s)\n", Dir.c_str(), Name.c_str()));
3587 LSCPResultSet result;
3588 #if HAVE_SQLITE3
3589 try {
3590 InstrumentsDb::GetInstrumentsDb()->RenameDirectory(Dir, Name);
3591 } catch (Exception e) {
3592 result.Error(e);
3593 }
3594 #else
3595 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3596 #endif
3597 return result.Produce();
3598 }
3599
3600 String LSCPServer::MoveDbInstrumentDirectory(String Dir, String Dst) {
3601 dmsg(2,("LSCPServer: MoveDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
3602 LSCPResultSet result;
3603 #if HAVE_SQLITE3
3604 try {
3605 InstrumentsDb::GetInstrumentsDb()->MoveDirectory(Dir, Dst);
3606 } catch (Exception e) {
3607 result.Error(e);
3608 }
3609 #else
3610 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3611 #endif
3612 return result.Produce();
3613 }
3614
3615 String LSCPServer::CopyDbInstrumentDirectory(String Dir, String Dst) {
3616 dmsg(2,("LSCPServer: CopyDbInstrumentDirectory(Dir=%s,Dst=%s)\n", Dir.c_str(), Dst.c_str()));
3617 LSCPResultSet result;
3618 #if HAVE_SQLITE3
3619 try {
3620 InstrumentsDb::GetInstrumentsDb()->CopyDirectory(Dir, Dst);
3621 } catch (Exception e) {
3622 result.Error(e);
3623 }
3624 #else
3625 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3626 #endif
3627 return result.Produce();
3628 }
3629
3630 String LSCPServer::SetDbInstrumentDirectoryDescription(String Dir, String Desc) {
3631 dmsg(2,("LSCPServer: SetDbInstrumentDirectoryDescription(Dir=%s,Desc=%s)\n", Dir.c_str(), Desc.c_str()));
3632 LSCPResultSet result;
3633 #if HAVE_SQLITE3
3634 try {
3635 InstrumentsDb::GetInstrumentsDb()->SetDirectoryDescription(Dir, Desc);
3636 } catch (Exception e) {
3637 result.Error(e);
3638 }
3639 #else
3640 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3641 #endif
3642 return result.Produce();
3643 }
3644
3645 String LSCPServer::AddDbInstruments(String DbDir, String FilePath, int Index, bool bBackground) {
3646 dmsg(2,("LSCPServer: AddDbInstruments(DbDir=%s,FilePath=%s,Index=%d,bBackground=%d)\n", DbDir.c_str(), FilePath.c_str(), Index, bBackground));
3647 LSCPResultSet result;
3648 #if HAVE_SQLITE3
3649 try {
3650 int id;
3651 InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
3652 id = db->AddInstruments(DbDir, FilePath, Index, bBackground);
3653 if (bBackground) result = id;
3654 } catch (Exception e) {
3655 result.Error(e);
3656 }
3657 #else
3658 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3659 #endif
3660 return result.Produce();
3661 }
3662
3663 String LSCPServer::AddDbInstruments(String ScanMode, String DbDir, String FsDir, bool bBackground, bool insDir) {
3664 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));
3665 LSCPResultSet result;
3666 #if HAVE_SQLITE3
3667 try {
3668 int id;
3669 InstrumentsDb* db = InstrumentsDb::GetInstrumentsDb();
3670 if (ScanMode.compare("RECURSIVE") == 0) {
3671 id = db->AddInstruments(RECURSIVE, DbDir, FsDir, bBackground, insDir);
3672 } else if (ScanMode.compare("NON_RECURSIVE") == 0) {
3673 id = db->AddInstruments(NON_RECURSIVE, DbDir, FsDir, bBackground, insDir);
3674 } else if (ScanMode.compare("FLAT") == 0) {
3675 id = db->AddInstruments(FLAT, DbDir, FsDir, bBackground, insDir);
3676 } else {
3677 throw Exception("Unknown scan mode: " + ScanMode);
3678 }
3679
3680 if (bBackground) result = id;
3681 } catch (Exception e) {
3682 result.Error(e);
3683 }
3684 #else
3685 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3686 #endif
3687 return result.Produce();
3688 }
3689
3690 String LSCPServer::RemoveDbInstrument(String Instr) {
3691 dmsg(2,("LSCPServer: RemoveDbInstrument(Instr=%s)\n", Instr.c_str()));
3692 LSCPResultSet result;
3693 #if HAVE_SQLITE3
3694 try {
3695 InstrumentsDb::GetInstrumentsDb()->RemoveInstrument(Instr);
3696 } catch (Exception e) {
3697 result.Error(e);
3698 }
3699 #else
3700 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3701 #endif
3702 return result.Produce();
3703 }
3704
3705 String LSCPServer::GetDbInstrumentCount(String Dir, bool Recursive) {
3706 dmsg(2,("LSCPServer: GetDbInstrumentCount(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
3707 LSCPResultSet result;
3708 #if HAVE_SQLITE3
3709 try {
3710 result.Add(InstrumentsDb::GetInstrumentsDb()->GetInstrumentCount(Dir, Recursive));
3711 } catch (Exception e) {
3712 result.Error(e);
3713 }
3714 #else
3715 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3716 #endif
3717 return result.Produce();
3718 }
3719
3720 String LSCPServer::GetDbInstruments(String Dir, bool Recursive) {
3721 dmsg(2,("LSCPServer: GetDbInstruments(Dir=%s,Recursive=%d)\n", Dir.c_str(), Recursive));
3722 LSCPResultSet result;
3723 #if HAVE_SQLITE3
3724 try {
3725 String list;
3726 StringListPtr instrs = InstrumentsDb::GetInstrumentsDb()->GetInstruments(Dir, Recursive);
3727
3728 for (int i = 0; i < instrs->size(); i++) {
3729 if (list != "") list += ",";
3730 list += "'" + InstrumentsDb::toEscapedPath(instrs->at(i)) + "'";
3731 }
3732
3733 result.Add(list);
3734 } catch (Exception e) {
3735 result.Error(e);
3736 }
3737 #else
3738 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3739 #endif
3740 return result.Produce();
3741 }
3742
3743 String LSCPServer::GetDbInstrumentInfo(String Instr) {
3744 dmsg(2,("LSCPServer: GetDbInstrumentInfo(Instr=%s)\n", Instr.c_str()));
3745 LSCPResultSet result;
3746 #if HAVE_SQLITE3
3747 try {
3748 DbInstrument info = InstrumentsDb::GetInstrumentsDb()->GetInstrumentInfo(Instr);
3749
3750 result.Add("INSTRUMENT_FILE", info.InstrFile);
3751 result.Add("INSTRUMENT_NR", info.InstrNr);
3752 result.Add("FORMAT_FAMILY", info.FormatFamily);
3753 result.Add("FORMAT_VERSION", info.FormatVersion);
3754 result.Add("SIZE", (int)info.Size);
3755 result.Add("CREATED", info.Created);
3756 result.Add("MODIFIED", info.Modified);
3757 result.Add("DESCRIPTION", _escapeLscpResponse(info.Description));
3758 result.Add("IS_DRUM", info.IsDrum);
3759 result.Add("PRODUCT", _escapeLscpResponse(info.Product));
3760 result.Add("ARTISTS", _escapeLscpResponse(info.Artists));
3761 result.Add("KEYWORDS", _escapeLscpResponse(info.Keywords));
3762 } catch (Exception e) {
3763 result.Error(e);
3764 }
3765 #else
3766 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3767 #endif
3768 return result.Produce();
3769 }
3770
3771 String LSCPServer::GetDbInstrumentsJobInfo(int JobId) {
3772 dmsg(2,("LSCPServer: GetDbInstrumentsJobInfo(JobId=%d)\n", JobId));
3773 LSCPResultSet result;
3774 #if HAVE_SQLITE3
3775 try {
3776 ScanJob job = InstrumentsDb::GetInstrumentsDb()->Jobs.GetJobById(JobId);
3777
3778 result.Add("FILES_TOTAL", job.FilesTotal);
3779 result.Add("FILES_SCANNED", job.FilesScanned);
3780 result.Add("SCANNING", job.Scanning);
3781 result.Add("STATUS", job.Status);
3782 } catch (Exception e) {
3783 result.Error(e);
3784 }
3785 #else
3786 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3787 #endif
3788 return result.Produce();
3789 }
3790
3791 String LSCPServer::SetDbInstrumentName(String Instr, String Name) {
3792 dmsg(2,("LSCPServer: SetDbInstrumentName(Instr=%s,Name=%s)\n", Instr.c_str(), Name.c_str()));
3793 LSCPResultSet result;
3794 #if HAVE_SQLITE3
3795 try {
3796 InstrumentsDb::GetInstrumentsDb()->RenameInstrument(Instr, Name);
3797 } catch (Exception e) {
3798 result.Error(e);
3799 }
3800 #else
3801 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3802 #endif
3803 return result.Produce();
3804 }
3805
3806 String LSCPServer::MoveDbInstrument(String Instr, String Dst) {
3807 dmsg(2,("LSCPServer: MoveDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
3808 LSCPResultSet result;
3809 #if HAVE_SQLITE3
3810 try {
3811 InstrumentsDb::GetInstrumentsDb()->MoveInstrument(Instr, Dst);
3812 } catch (Exception e) {
3813 result.Error(e);
3814 }
3815 #else
3816 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3817 #endif
3818 return result.Produce();
3819 }
3820
3821 String LSCPServer::CopyDbInstrument(String Instr, String Dst) {
3822 dmsg(2,("LSCPServer: CopyDbInstrument(Instr=%s,Dst=%s)\n", Instr.c_str(), Dst.c_str()));
3823 LSCPResultSet result;
3824 #if HAVE_SQLITE3
3825 try {
3826 InstrumentsDb::GetInstrumentsDb()->CopyInstrument(Instr, Dst);
3827 } catch (Exception e) {
3828 result.Error(e);
3829 }
3830 #else
3831 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3832 #endif
3833 return result.Produce();
3834 }
3835
3836 String LSCPServer::SetDbInstrumentDescription(String Instr, String Desc) {
3837 dmsg(2,("LSCPServer: SetDbInstrumentDescription(Instr=%s,Desc=%s)\n", Instr.c_str(), Desc.c_str()));
3838 LSCPResultSet result;
3839 #if HAVE_SQLITE3
3840 try {
3841 InstrumentsDb::GetInstrumentsDb()->SetInstrumentDescription(Instr, Desc);
3842 } catch (Exception e) {
3843 result.Error(e);
3844 }
3845 #else
3846 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3847 #endif
3848 return result.Produce();
3849 }
3850
3851 String LSCPServer::SetDbInstrumentFilePath(String OldPath, String NewPath) {
3852 dmsg(2,("LSCPServer: SetDbInstrumentFilePath(OldPath=%s,NewPath=%s)\n", OldPath.c_str(), NewPath.c_str()));
3853 LSCPResultSet result;
3854 #if HAVE_SQLITE3
3855 try {
3856 InstrumentsDb::GetInstrumentsDb()->SetInstrumentFilePath(OldPath, NewPath);
3857 } catch (Exception e) {
3858 result.Error(e);
3859 }
3860 #else
3861 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3862 #endif
3863 return result.Produce();
3864 }
3865
3866 String LSCPServer::FindLostDbInstrumentFiles() {
3867 dmsg(2,("LSCPServer: FindLostDbInstrumentFiles()\n"));
3868 LSCPResultSet result;
3869 #if HAVE_SQLITE3
3870 try {
3871 String list;
3872 StringListPtr pLostFiles = InstrumentsDb::GetInstrumentsDb()->FindLostInstrumentFiles();
3873
3874 for (int i = 0; i < pLostFiles->size(); i++) {
3875 if (list != "") list += ",";
3876 list += "'" + pLostFiles->at(i) + "'";
3877 }
3878
3879 result.Add(list);
3880 } catch (Exception e) {
3881 result.Error(e);
3882 }
3883 #else
3884 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3885 #endif
3886 return result.Produce();
3887 }
3888
3889 String LSCPServer::FindDbInstrumentDirectories(String Dir, std::map<String,String> Parameters, bool Recursive) {
3890 dmsg(2,("LSCPServer: FindDbInstrumentDirectories(Dir=%s)\n", Dir.c_str()));
3891 LSCPResultSet result;
3892 #if HAVE_SQLITE3
3893 try {
3894 SearchQuery Query;
3895 std::map<String,String>::iterator iter;
3896 for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
3897 if (iter->first.compare("NAME") == 0) {
3898 Query.Name = iter->second;
3899 } else if (iter->first.compare("CREATED") == 0) {
3900 Query.SetCreated(iter->second);
3901 } else if (iter->first.compare("MODIFIED") == 0) {
3902 Query.SetModified(iter->second);
3903 } else if (iter->first.compare("DESCRIPTION") == 0) {
3904 Query.Description = iter->second;
3905 } else {
3906 throw Exception("Unknown search criteria: " + iter->first);
3907 }
3908 }
3909
3910 String list;
3911 StringListPtr pDirectories =
3912 InstrumentsDb::GetInstrumentsDb()->FindDirectories(Dir, &Query, Recursive);
3913
3914 for (int i = 0; i < pDirectories->size(); i++) {
3915 if (list != "") list += ",";
3916 list += "'" + InstrumentsDb::toEscapedPath(pDirectories->at(i)) + "'";
3917 }
3918
3919 result.Add(list);
3920 } catch (Exception e) {
3921 result.Error(e);
3922 }
3923 #else
3924 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3925 #endif
3926 return result.Produce();
3927 }
3928
3929 String LSCPServer::FindDbInstruments(String Dir, std::map<String,String> Parameters, bool Recursive) {
3930 dmsg(2,("LSCPServer: FindDbInstruments(Dir=%s)\n", Dir.c_str()));
3931 LSCPResultSet result;
3932 #if HAVE_SQLITE3
3933 try {
3934 SearchQuery Query;
3935 std::map<String,String>::iterator iter;
3936 for (iter = Parameters.begin(); iter != Parameters.end(); iter++) {
3937 if (iter->first.compare("NAME") == 0) {
3938 Query.Name = iter->second;
3939 } else if (iter->first.compare("FORMAT_FAMILIES") == 0) {
3940 Query.SetFormatFamilies(iter->second);
3941 } else if (iter->first.compare("SIZE") == 0) {
3942 Query.SetSize(iter->second);
3943 } else if (iter->first.compare("CREATED") == 0) {
3944 Query.SetCreated(iter->second);
3945 } else if (iter->first.compare("MODIFIED") == 0) {
3946 Query.SetModified(iter->second);
3947 } else if (iter->first.compare("DESCRIPTION") == 0) {
3948 Query.Description = iter->second;
3949 } else if (iter->first.compare("IS_DRUM") == 0) {
3950 if (!strcasecmp(iter->second.c_str(), "true")) {
3951 Query.InstrType = SearchQuery::DRUM;
3952 } else {
3953 Query.InstrType = SearchQuery::CHROMATIC;
3954 }
3955 } else if (iter->first.compare("PRODUCT") == 0) {
3956 Query.Product = iter->second;
3957 } else if (iter->first.compare("ARTISTS") == 0) {
3958 Query.Artists = iter->second;
3959 } else if (iter->first.compare("KEYWORDS") == 0) {
3960 Query.Keywords = iter->second;
3961 } else {
3962 throw Exception("Unknown search criteria: " + iter->first);
3963 }
3964 }
3965
3966 String list;
3967 StringListPtr pInstruments =
3968 InstrumentsDb::GetInstrumentsDb()->FindInstruments(Dir, &Query, Recursive);
3969
3970 for (int i = 0; i < pInstruments->size(); i++) {
3971 if (list != "") list += ",";
3972 list += "'" + InstrumentsDb::toEscapedPath(pInstruments->at(i)) + "'";
3973 }
3974
3975 result.Add(list);
3976 } catch (Exception e) {
3977 result.Error(e);
3978 }
3979 #else
3980 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3981 #endif
3982 return result.Produce();
3983 }
3984
3985 String LSCPServer::FormatInstrumentsDb() {
3986 dmsg(2,("LSCPServer: FormatInstrumentsDb()\n"));
3987 LSCPResultSet result;
3988 #if HAVE_SQLITE3
3989 try {
3990 InstrumentsDb::GetInstrumentsDb()->Format();
3991 } catch (Exception e) {
3992 result.Error(e);
3993 }
3994 #else
3995 result.Error(String(DOESNT_HAVE_SQLITE3), 0);
3996 #endif
3997 return result.Produce();
3998 }
3999
4000
4001 /**
4002 * Will be called by the parser to enable or disable echo mode; if echo
4003 * mode is enabled, all commands from the client will (immediately) be
4004 * echoed back to the client.
4005 */
4006 String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
4007 dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
4008 LSCPResultSet result;
4009 try {
4010 if (boolean_value == 0) pSession->bVerbose = false;
4011 else if (boolean_value == 1) pSession->bVerbose = true;
4012 else throw Exception("Not a boolean value, must either be 0 or 1");
4013 }
4014 catch (Exception e) {
4015 result.Error(e);
4016 }
4017 return result.Produce();
4018 }
4019
4020 String LSCPServer::SetShellInteract(yyparse_param_t* pSession, double boolean_value) {
4021 dmsg(2,("LSCPServer: SetShellInteract(val=%f)\n", boolean_value));
4022 LSCPResultSet result;
4023 try {
4024 if (boolean_value == 0) pSession->bShellInteract = false;
4025 else if (boolean_value == 1) pSession->bShellInteract = true;
4026 else throw Exception("Not a boolean value, must either be 0 or 1");
4027 } catch (Exception e) {
4028 result.Error(e);
4029 }
4030 return result.Produce();
4031 }
4032
4033 String LSCPServer::SetShellAutoCorrect(yyparse_param_t* pSession, double boolean_value) {
4034 dmsg(2,("LSCPServer: SetShellAutoCorrect(val=%f)\n", boolean_value));
4035 LSCPResultSet result;
4036 try {
4037 if (boolean_value == 0) pSession->bShellAutoCorrect = false;
4038 else if (boolean_value == 1) pSession->bShellAutoCorrect = true;
4039 else throw Exception("Not a boolean value, must either be 0 or 1");
4040 } catch (Exception e) {
4041 result.Error(e);
4042 }
4043 return result.Produce();
4044 }
4045
4046 }

  ViewVC Help
Powered by ViewVC