/[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 2324 - (show annotations) (download)
Sun Mar 4 09:01:32 2012 UTC (12 years ago) by persson
File size: 155137 byte(s)
* plugin bugfix: instrument loading hang when the plugin was loaded a
  second time (this time it's for Linux and Mac, previous similar fix
  was for Windows)
* thread safety fixes for the instrument loading thread
* MME driver: removed compiler warning
* LV2: fixed invalid realtime statement in plugin metadata

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

  ViewVC Help
Powered by ViewVC