/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/network/lscpserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2531 - (show annotations) (download)
Wed Mar 5 00:02:21 2014 UTC (5 years, 11 months ago) by schoenebeck
File size: 162946 byte(s)
* LSCP shell: Added support for moving cursor left/right with arrow keys.
* Bumped version (1.0.0.svn35).

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