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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1135 - (hide annotations) (download)
Thu Mar 29 09:40:45 2007 UTC (17 years ago) by iliev
File size: 92323 byte(s)
* Added new LSCP command - SET FX_SEND NAME
* The default map is now the first available map

1 schoenebeck 35 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 56 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 1009 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
7 schoenebeck 35 * *
8 schoenebeck 385 * This library is free software; you can redistribute it and/or modify *
9 schoenebeck 35 * 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 schoenebeck 385 * This library is distributed in the hope that it will be useful, *
14 schoenebeck 35 * 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 schoenebeck 385 * along with this library; if not, write to the Free Software *
20 schoenebeck 35 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21     * MA 02111-1307 USA *
22     ***************************************************************************/
23    
24     #include "lscpserver.h"
25 senkov 113 #include "lscpresultset.h"
26 senkov 170 #include "lscpevent.h"
27 schoenebeck 1005 #include "../common/global.h"
28 schoenebeck 35
29 schoenebeck 411 #include <fcntl.h>
30    
31 schoenebeck 401 #if HAVE_SQLITE3
32     # include "sqlite3.h"
33 senkov 397 #endif
34    
35 schoenebeck 411 #include "../engines/EngineFactory.h"
36 schoenebeck 660 #include "../engines/EngineChannelFactory.h"
37 schoenebeck 203 #include "../drivers/audio/AudioOutputDeviceFactory.h"
38     #include "../drivers/midi/MidiInputDeviceFactory.h"
39 schoenebeck 53
40 senkov 170 /**
41     * Below are a few static members of the LSCPServer class.
42     * The big assumption here is that LSCPServer is going to remain a singleton.
43     * These members are used to support client connections.
44     * Class handles multiple connections at the same time using select() and non-blocking recv()
45     * Commands are processed by a single LSCPServer thread.
46     * Notifications are delivered either by the thread that originated them
47     * or (if the resultset is currently in progress) by the LSCPServer thread
48     * after the resultset was sent out.
49     * This makes sure that resultsets can not be interrupted by notifications.
50     * This also makes sure that the thread sending notification is not blocked
51     * by the LSCPServer thread.
52     */
53     fd_set LSCPServer::fdSet;
54     int LSCPServer::currentSocket = -1;
55 schoenebeck 210 std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();
56 senkov 170 std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();
57     std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();
58     std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();
59     Mutex LSCPServer::NotifyMutex = Mutex();
60     Mutex LSCPServer::NotifyBufferMutex = Mutex();
61     Mutex LSCPServer::SubscriptionMutex = Mutex();
62 senkov 360 Mutex LSCPServer::RTNotifyMutex = Mutex();
63 senkov 170
64 senkov 667 LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4) {
65     SocketAddress.sin_family = AF_INET;
66     SocketAddress.sin_addr.s_addr = addr;
67     SocketAddress.sin_port = port;
68 schoenebeck 53 this->pSampler = pSampler;
69 iliev 981 LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
70     LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
71     LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_count, "MIDI_INPUT_DEVICE_COUNT");
72     LSCPEvent::RegisterEvent(LSCPEvent::event_midi_device_info, "MIDI_INPUT_DEVICE_INFO");
73 schoenebeck 556 LSCPEvent::RegisterEvent(LSCPEvent::event_channel_count, "CHANNEL_COUNT");
74 senkov 170 LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
75     LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
76     LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
77 schoenebeck 556 LSCPEvent::RegisterEvent(LSCPEvent::event_channel_info, "CHANNEL_INFO");
78 iliev 1108 LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_count, "FX_SEND_COUNT");
79     LSCPEvent::RegisterEvent(LSCPEvent::event_fx_send_info, "FX_SEND_INFO");
80 iliev 981 LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_count, "MIDI_INSTRUMENT_MAP_COUNT");
81     LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_map_info, "MIDI_INSTRUMENT_MAP_INFO");
82     LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_count, "MIDI_INSTRUMENT_COUNT");
83     LSCPEvent::RegisterEvent(LSCPEvent::event_midi_instr_info, "MIDI_INSTRUMENT_INFO");
84 senkov 170 LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
85 iliev 778 LSCPEvent::RegisterEvent(LSCPEvent::event_total_voice_count, "TOTAL_VOICE_COUNT");
86 iliev 1108 LSCPEvent::RegisterEvent(LSCPEvent::event_global_info, "GLOBAL_INFO");
87 schoenebeck 475 hSocket = -1;
88 schoenebeck 35 }
89    
90 schoenebeck 475 LSCPServer::~LSCPServer() {
91     if (hSocket >= 0) close(hSocket);
92     }
93    
94 iliev 1133 void LSCPServer::EventHandler::ChannelCountChanged(int NewCount) {
95 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_count, NewCount));
96     }
97    
98 iliev 1133 void LSCPServer::EventHandler::AudioDeviceCountChanged(int NewCount) {
99 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_count, NewCount));
100     }
101    
102 iliev 1133 void LSCPServer::EventHandler::MidiDeviceCountChanged(int NewCount) {
103 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_count, NewCount));
104     }
105    
106 iliev 1133 void LSCPServer::EventHandler::MidiInstrumentCountChanged(int MapId, int NewCount) {
107 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_count, MapId, NewCount));
108     }
109    
110 iliev 1133 void LSCPServer::EventHandler::MidiInstrumentInfoChanged(int MapId, int Bank, int Program) {
111 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_info, MapId, Bank, Program));
112     }
113    
114 iliev 1133 void LSCPServer::EventHandler::MidiInstrumentMapCountChanged(int NewCount) {
115 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_count, NewCount));
116     }
117    
118 iliev 1133 void LSCPServer::EventHandler::MidiInstrumentMapInfoChanged(int MapId) {
119 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_instr_map_info, MapId));
120     }
121    
122 iliev 1133 void LSCPServer::EventHandler::FxSendCountChanged(int ChannelId, int NewCount) {
123 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_count, ChannelId, NewCount));
124     }
125    
126 iliev 1133 void LSCPServer::EventHandler::VoiceCountChanged(int ChannelId, int NewCount) {
127 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_voice_count, ChannelId, NewCount));
128     }
129    
130 iliev 1133 void LSCPServer::EventHandler::StreamCountChanged(int ChannelId, int NewCount) {
131 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_stream_count, ChannelId, NewCount));
132     }
133    
134 iliev 1133 void LSCPServer::EventHandler::BufferFillChanged(int ChannelId, String FillData) {
135 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_buffer_fill, ChannelId, FillData));
136     }
137    
138 iliev 1133 void LSCPServer::EventHandler::TotalVoiceCountChanged(int NewCount) {
139 iliev 1130 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_total_voice_count, NewCount));
140     }
141    
142    
143 schoenebeck 211 /**
144     * Blocks the calling thread until the LSCP Server is initialized and
145     * accepting socket connections, if the server is already initialized then
146     * this method will return immediately.
147     * @param TimeoutSeconds - optional: max. wait time in seconds
148     * (default: 0s)
149     * @param TimeoutNanoSeconds - optional: max wait time in nano seconds
150     * (default: 0ns)
151     * @returns 0 on success, a value less than 0 if timeout exceeded
152     */
153     int LSCPServer::WaitUntilInitialized(long TimeoutSeconds, long TimeoutNanoSeconds) {
154     return Initialized.WaitAndUnlockIf(false, TimeoutSeconds, TimeoutNanoSeconds);
155     }
156    
157 schoenebeck 35 int LSCPServer::Main() {
158 schoenebeck 475 hSocket = socket(AF_INET, SOCK_STREAM, 0);
159 schoenebeck 35 if (hSocket < 0) {
160     std::cerr << "LSCPServer: Could not create server socket." << std::endl;
161 schoenebeck 53 //return -1;
162     exit(EXIT_FAILURE);
163 schoenebeck 35 }
164    
165     if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
166 schoenebeck 227 std::cerr << "LSCPServer: Could not bind server socket, retrying for " << ToString(LSCP_SERVER_BIND_TIMEOUT) << " seconds...";
167     for (int trial = 0; true; trial++) { // retry for LSCP_SERVER_BIND_TIMEOUT seconds
168     if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
169     if (trial > LSCP_SERVER_BIND_TIMEOUT) {
170     std::cerr << "gave up!" << std::endl;
171     close(hSocket);
172     //return -1;
173     exit(EXIT_FAILURE);
174     }
175     else sleep(1); // sleep 1s
176     }
177     else break; // success
178     }
179 schoenebeck 35 }
180    
181     listen(hSocket, 1);
182 schoenebeck 211 Initialized.Set(true);
183 iliev 1130
184     // Registering event listeners
185 iliev 1133 pSampler->AddChannelCountListener(&eventHandler);
186     pSampler->AddAudioDeviceCountListener(&eventHandler);
187     pSampler->AddMidiDeviceCountListener(&eventHandler);
188     pSampler->AddVoiceCountListener(&eventHandler);
189     pSampler->AddStreamCountListener(&eventHandler);
190     pSampler->AddBufferFillListener(&eventHandler);
191     pSampler->AddTotalVoiceCountListener(&eventHandler);
192     pSampler->AddFxSendCountListener(&eventHandler);
193     MidiInstrumentMapper::AddMidiInstrumentCountListener(&eventHandler);
194     MidiInstrumentMapper::AddMidiInstrumentInfoListener(&eventHandler);
195     MidiInstrumentMapper::AddMidiInstrumentMapCountListener(&eventHandler);
196     MidiInstrumentMapper::AddMidiInstrumentMapInfoListener(&eventHandler);
197 schoenebeck 35
198     // now wait for client connections and handle their requests
199     sockaddr_in client;
200     int length = sizeof(client);
201 senkov 170 FD_ZERO(&fdSet);
202     FD_SET(hSocket, &fdSet);
203     int maxSessions = hSocket;
204 schoenebeck 203
205 iliev 793 timeval timeout;
206    
207 schoenebeck 35 while (true) {
208 iliev 793 // check if some engine channel's parameter / status changed, if so notify the respective LSCP event subscribers
209     {
210     std::set<EngineChannel*> engineChannels = EngineChannelFactory::EngineChannelInstances();
211     std::set<EngineChannel*>::iterator itEngineChannel = engineChannels.begin();
212     std::set<EngineChannel*>::iterator itEnd = engineChannels.end();
213     for (; itEngineChannel != itEnd; ++itEngineChannel) {
214     if ((*itEngineChannel)->StatusChanged()) {
215     SendLSCPNotify(LSCPEvent(LSCPEvent::event_channel_info, (*itEngineChannel)->iSamplerChannelIndex));
216     }
217 iliev 1108
218     for (int i = 0; i < (*itEngineChannel)->GetFxSendCount(); i++) {
219     FxSend* fxs = (*itEngineChannel)->GetFxSend(i);
220     if(fxs != NULL && fxs->IsInfoChanged()) {
221     int chn = (*itEngineChannel)->iSamplerChannelIndex;
222     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, chn, fxs->Id()));
223     fxs->SetInfoChanged(false);
224     }
225     }
226 iliev 793 }
227     }
228    
229     //Now let's deliver late notifies (if any)
230     NotifyBufferMutex.Lock();
231     for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
232 wylder 814 #ifdef MSG_NOSIGNAL
233 iliev 793 send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), MSG_NOSIGNAL);
234 wylder 814 #else
235     send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
236     #endif
237 iliev 793 }
238 persson 836 bufferedNotifies.clear();
239 iliev 793 NotifyBufferMutex.Unlock();
240    
241     fd_set selectSet = fdSet;
242     timeout.tv_sec = 0;
243     timeout.tv_usec = 100000;
244    
245     int retval = select(maxSessions+1, &selectSet, NULL, NULL, &timeout);
246    
247 senkov 170 if (retval == 0)
248 senkov 198 continue; //Nothing try again
249 senkov 170 if (retval == -1) {
250     std::cerr << "LSCPServer: Socket select error." << std::endl;
251     close(hSocket);
252     exit(EXIT_FAILURE);
253     }
254 schoenebeck 203
255 senkov 170 //Accept new connections now (if any)
256     if (FD_ISSET(hSocket, &selectSet)) {
257     int socket = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
258     if (socket < 0) {
259     std::cerr << "LSCPServer: Client connection failed." << std::endl;
260     exit(EXIT_FAILURE);
261     }
262 schoenebeck 35
263 senkov 170 if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
264     std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
265     exit(EXIT_FAILURE);
266     }
267 schoenebeck 35
268 schoenebeck 210 // Parser initialization
269     yyparse_param_t yyparse_param;
270     yyparse_param.pServer = this;
271     yyparse_param.hSession = socket;
272    
273     Sessions.push_back(yyparse_param);
274 senkov 170 FD_SET(socket, &fdSet);
275     if (socket > maxSessions)
276     maxSessions = socket;
277     dmsg(1,("LSCPServer: Client connection established on socket:%d.\n", socket));
278     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection established on socket", socket));
279     continue; //Maybe this was the only selected socket, better select again
280     }
281 schoenebeck 35
282 senkov 170 //Something was selected and it was not the hSocket, so it must be some command(s) coming.
283 schoenebeck 210 for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {
284     if (FD_ISSET((*iter).hSession, &selectSet)) { //Was it this socket?
285 senkov 170 if (GetLSCPCommand(iter)) { //Have we read the entire command?
286     dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));
287 schoenebeck 219 int dummy; // just a temporary hack to fulfill the restart() function prototype
288     restart(NULL, dummy); // restart the 'scanner'
289 schoenebeck 210 currentSocket = (*iter).hSession; //a hack
290 schoenebeck 475 dmsg(2,("LSCPServer: [%s]\n",bufferedCommands[currentSocket].c_str()));
291 schoenebeck 210 if ((*iter).bVerbose) { // if echo mode enabled
292     AnswerClient(bufferedCommands[currentSocket]);
293     }
294     int result = yyparse(&(*iter));
295 senkov 170 currentSocket = -1; //continuation of a hack
296     dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));
297     if (result == LSCP_QUIT) { //Was it a quit command by any chance?
298     CloseConnection(iter);
299     }
300     }
301     //socket may have been closed, iter may be invalid, get out of the loop for now.
302     //we'll be back if there is data.
303 schoenebeck 203 break;
304 senkov 170 }
305     }
306 schoenebeck 35 }
307     }
308    
309 schoenebeck 210 void LSCPServer::CloseConnection( std::vector<yyparse_param_t>::iterator iter ) {
310     int socket = (*iter).hSession;
311 senkov 170 dmsg(1,("LSCPServer: Client connection terminated on socket:%d.\n",socket));
312     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection terminated on socket", socket));
313 schoenebeck 210 Sessions.erase(iter);
314 senkov 170 FD_CLR(socket, &fdSet);
315     SubscriptionMutex.Lock(); //Must unsubscribe this socket from all events (if any)
316     for (std::map< LSCPEvent::event_t, std::list<int> >::iterator iter = eventSubscriptions.begin(); iter != eventSubscriptions.end(); iter++) {
317     iter->second.remove(socket);
318     }
319     SubscriptionMutex.Unlock();
320     NotifyMutex.Lock();
321     bufferedCommands.erase(socket);
322     bufferedNotifies.erase(socket);
323     close(socket);
324     NotifyMutex.Unlock();
325     }
326    
327 senkov 360 int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
328     int subs = 0;
329     SubscriptionMutex.Lock();
330     for( std::list<LSCPEvent::event_t>::iterator iter = events.begin();
331     iter != events.end(); iter++)
332     {
333     subs += eventSubscriptions.count(*iter);
334     }
335     SubscriptionMutex.Unlock();
336     return subs;
337     }
338    
339 senkov 170 void LSCPServer::SendLSCPNotify( LSCPEvent event ) {
340     SubscriptionMutex.Lock();
341     if (eventSubscriptions.count(event.GetType()) == 0) {
342     SubscriptionMutex.Unlock(); //Nobody is subscribed to this event
343     return;
344     }
345     std::list<int>::iterator iter = eventSubscriptions[event.GetType()].begin();
346     std::list<int>::iterator end = eventSubscriptions[event.GetType()].end();
347     String notify = event.Produce();
348    
349     while (true) {
350     if (NotifyMutex.Trylock()) {
351     for(;iter != end; iter++)
352 wylder 814 #ifdef MSG_NOSIGNAL
353 iliev 707 send(*iter, notify.c_str(), notify.size(), MSG_NOSIGNAL);
354 wylder 814 #else
355     send(*iter, notify.c_str(), notify.size(), 0);
356     #endif
357 senkov 170 NotifyMutex.Unlock();
358     break;
359     } else {
360     if (NotifyBufferMutex.Trylock()) {
361     for(;iter != end; iter++)
362     bufferedNotifies[*iter] += notify;
363     NotifyBufferMutex.Unlock();
364     break;
365     }
366     }
367     }
368     SubscriptionMutex.Unlock();
369     }
370    
371     extern int GetLSCPCommand( void *buf, int max_size ) {
372     String command = LSCPServer::bufferedCommands[LSCPServer::currentSocket];
373     if (command.size() == 0) { //Parser wants input but we have nothing.
374     strcpy((char*) buf, "\n"); //So give it an empty command
375     return 1; //to keep it happy.
376     }
377    
378     if (max_size < command.size()) {
379     std::cerr << "getLSCPCommand: Flex buffer too small, ignoring the command." << std::endl;
380     return 0; //This will never happen
381     }
382    
383     strcpy((char*) buf, command.c_str());
384     LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);
385     return command.size();
386     }
387    
388 schoenebeck 35 /**
389 senkov 170 * Will be called to try to read the command from the socket
390     * If command is read, it will return true. Otherwise false is returned.
391     * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.
392     */
393 schoenebeck 210 bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
394     int socket = (*iter).hSession;
395 senkov 170 char c;
396     int i = 0;
397     while (true) {
398     int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
399     if (result == 0) { //socket was selected, so 0 here means client has closed the connection
400     CloseConnection(iter);
401     break;
402     }
403     if (result == 1) {
404 schoenebeck 203 if (c == '\r')
405 senkov 170 continue; //Ignore CR
406     if (c == '\n') {
407 senkov 184 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
408 iliev 907 bufferedCommands[socket] += "\r\n";
409 senkov 170 return true; //Complete command was read
410     }
411     bufferedCommands[socket] += c;
412     }
413     if (result == -1) {
414     if (errno == EAGAIN) //Would block, try again later.
415     return false;
416     switch(errno) {
417     case EBADF:
418     dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
419     break;
420     case ECONNREFUSED:
421     dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
422     break;
423     case ENOTCONN:
424     dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
425     break;
426     case ENOTSOCK:
427     dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
428     break;
429     case EAGAIN:
430     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"));
431 schoenebeck 203 break;
432     case EINTR:
433 senkov 170 dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
434 schoenebeck 203 break;
435     case EFAULT:
436     dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
437     break;
438     case EINVAL:
439     dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
440     break;
441     case ENOMEM:
442     dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
443     break;
444     default:
445     dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
446     break;
447     }
448 senkov 170 CloseConnection(iter);
449     break;
450     }
451     }
452     return false;
453     }
454    
455     /**
456 schoenebeck 35 * Will be called by the parser whenever it wants to send an answer to the
457     * client / frontend.
458     *
459     * @param ReturnMessage - message that will be send to the client
460     */
461     void LSCPServer::AnswerClient(String ReturnMessage) {
462     dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
463 senkov 170 if (currentSocket != -1) {
464     NotifyMutex.Lock();
465 wylder 814 #ifdef MSG_NOSIGNAL
466 iliev 707 send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), MSG_NOSIGNAL);
467 wylder 814 #else
468     send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
469     #endif
470 senkov 170 NotifyMutex.Unlock();
471     }
472 schoenebeck 35 }
473    
474 capela 143 /**
475     * Find a created audio output device index.
476     */
477     int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
478     {
479     // Search for the created device to get its index
480     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
481     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
482     for (; iter != devices.end(); iter++) {
483     if (iter->second == pDevice)
484     return iter->first;
485     }
486     // Not found.
487     return -1;
488     }
489    
490 senkov 155 /**
491     * Find a created midi input device index.
492     */
493     int LSCPServer::GetMidiInputDeviceIndex ( MidiInputDevice *pDevice )
494     {
495     // Search for the created device to get its index
496     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
497     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
498     for (; iter != devices.end(); iter++) {
499     if (iter->second == pDevice)
500     return iter->first;
501     }
502     // Not found.
503     return -1;
504     }
505    
506 schoenebeck 123 String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
507     dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
508     LSCPResultSet result;
509     try {
510     AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
511     // search for the created device to get its index
512 capela 143 int index = GetAudioOutputDeviceIndex(pDevice);
513 schoenebeck 880 if (index == -1) throw Exception("Internal error: could not find created audio output device.");
514 schoenebeck 123 result = index; // success
515     }
516 schoenebeck 880 catch (Exception e) {
517 schoenebeck 123 result.Error(e);
518     }
519     return result.Produce();
520     }
521    
522 senkov 155 String LSCPServer::CreateMidiInputDevice(String Driver, std::map<String,String> Parameters) {
523     dmsg(2,("LSCPServer: CreateMidiInputDevice(Driver=%s)\n", Driver.c_str()));
524     LSCPResultSet result;
525     try {
526     MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
527     // search for the created device to get its index
528     int index = GetMidiInputDeviceIndex(pDevice);
529 schoenebeck 880 if (index == -1) throw Exception("Internal error: could not find created midi input device.");
530 senkov 155 result = index; // success
531     }
532 schoenebeck 880 catch (Exception e) {
533 senkov 155 result.Error(e);
534     }
535     return result.Produce();
536     }
537    
538 schoenebeck 123 String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
539     dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
540     LSCPResultSet result;
541     try {
542     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
543 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
544 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
545     pSampler->DestroyAudioOutputDevice(pDevice);
546     }
547 schoenebeck 880 catch (Exception e) {
548 schoenebeck 123 result.Error(e);
549     }
550     return result.Produce();
551     }
552    
553 senkov 155 String LSCPServer::DestroyMidiInputDevice(uint DeviceIndex) {
554     dmsg(2,("LSCPServer: DestroyMidiInputDevice(DeviceIndex=%d)\n", DeviceIndex));
555     LSCPResultSet result;
556     try {
557     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
558 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
559 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
560     pSampler->DestroyMidiInputDevice(pDevice);
561     }
562 schoenebeck 880 catch (Exception e) {
563 senkov 155 result.Error(e);
564     }
565     return result.Produce();
566     }
567    
568 iliev 1135 EngineChannel* LSCPServer::GetEngineChannel(uint uiSamplerChannel) {
569     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
570     if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
571    
572     EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
573     if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
574    
575     return pEngineChannel;
576     }
577    
578 schoenebeck 35 /**
579     * Will be called by the parser to load an instrument.
580     */
581 capela 137 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
582 schoenebeck 53 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
583 senkov 120 LSCPResultSet result;
584 schoenebeck 53 try {
585     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
586 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
587 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
588 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel yet");
589 schoenebeck 223 if (!pSamplerChannel->GetAudioOutputDevice())
590 schoenebeck 880 throw Exception("No audio output device connected to sampler channel");
591 capela 137 if (bBackground) {
592 schoenebeck 947 InstrumentManager::instrument_id_t id;
593     id.FileName = Filename;
594     id.Index = uiInstrument;
595     InstrumentManager::LoadInstrumentInBackground(id, pEngineChannel);
596 capela 137 }
597 schoenebeck 392 else {
598 schoenebeck 411 // tell the engine channel which instrument to load
599     pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrument);
600 schoenebeck 392 // actually start to load the instrument (blocks until completed)
601 schoenebeck 411 pEngineChannel->LoadInstrument();
602 schoenebeck 392 }
603 schoenebeck 53 }
604 schoenebeck 880 catch (Exception e) {
605 senkov 120 result.Error(e);
606 schoenebeck 53 }
607 senkov 120 return result.Produce();
608 schoenebeck 35 }
609    
610     /**
611 schoenebeck 411 * Will be called by the parser to assign a sampler engine type to a
612     * sampler channel.
613 schoenebeck 35 */
614 schoenebeck 411 String LSCPServer::SetEngineType(String EngineName, uint uiSamplerChannel) {
615 schoenebeck 705 dmsg(2,("LSCPServer: SetEngineType(EngineName=%s,uiSamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
616 senkov 120 LSCPResultSet result;
617 schoenebeck 475 try {
618 schoenebeck 53 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
619 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
620 senkov 360 LockRTNotify();
621 schoenebeck 411 pSamplerChannel->SetEngineType(EngineName);
622 schoenebeck 705 if(HasSoloChannel()) pSamplerChannel->GetEngineChannel()->SetMute(-1);
623 senkov 360 UnlockRTNotify();
624 schoenebeck 53 }
625 schoenebeck 880 catch (Exception e) {
626 senkov 120 result.Error(e);
627 schoenebeck 53 }
628 senkov 120 return result.Produce();
629 schoenebeck 35 }
630    
631     /**
632     * Will be called by the parser to get the amount of sampler channels.
633     */
634     String LSCPServer::GetChannels() {
635     dmsg(2,("LSCPServer: GetChannels()\n"));
636 senkov 120 LSCPResultSet result;
637     result.Add(pSampler->SamplerChannels());
638     return result.Produce();
639 schoenebeck 35 }
640    
641     /**
642 schoenebeck 209 * Will be called by the parser to get the list of sampler channels.
643     */
644     String LSCPServer::ListChannels() {
645     dmsg(2,("LSCPServer: ListChannels()\n"));
646     String list;
647     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
648     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
649     for (; iter != channels.end(); iter++) {
650     if (list != "") list += ",";
651     list += ToString(iter->first);
652     }
653     LSCPResultSet result;
654     result.Add(list);
655     return result.Produce();
656     }
657    
658     /**
659 schoenebeck 35 * Will be called by the parser to add a sampler channel.
660     */
661     String LSCPServer::AddChannel() {
662     dmsg(2,("LSCPServer: AddChannel()\n"));
663 persson 841 LockRTNotify();
664 schoenebeck 53 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
665 persson 841 UnlockRTNotify();
666 senkov 120 LSCPResultSet result(pSamplerChannel->Index());
667     return result.Produce();
668 schoenebeck 35 }
669    
670     /**
671     * Will be called by the parser to remove a sampler channel.
672     */
673 schoenebeck 53 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
674     dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
675 senkov 120 LSCPResultSet result;
676 senkov 360 LockRTNotify();
677 schoenebeck 53 pSampler->RemoveSamplerChannel(uiSamplerChannel);
678 senkov 360 UnlockRTNotify();
679 senkov 120 return result.Produce();
680 schoenebeck 35 }
681    
682     /**
683 capela 527 * Will be called by the parser to get the amount of all available engines.
684 schoenebeck 35 */
685     String LSCPServer::GetAvailableEngines() {
686     dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
687 schoenebeck 905 LSCPResultSet result;
688     try {
689     int n = EngineFactory::AvailableEngineTypes().size();
690     result.Add(n);
691     }
692     catch (Exception e) {
693     result.Error(e);
694     }
695 senkov 120 return result.Produce();
696 schoenebeck 35 }
697    
698     /**
699 capela 527 * Will be called by the parser to get a list of all available engines.
700     */
701     String LSCPServer::ListAvailableEngines() {
702     dmsg(2,("LSCPServer: ListAvailableEngines()\n"));
703 schoenebeck 905 LSCPResultSet result;
704     try {
705     String s = EngineFactory::AvailableEngineTypesAsString();
706     result.Add(s);
707     }
708     catch (Exception e) {
709     result.Error(e);
710     }
711 capela 527 return result.Produce();
712     }
713    
714     /**
715 schoenebeck 411 * Will be called by the parser to get descriptions for a particular
716     * sampler engine.
717 schoenebeck 35 */
718     String LSCPServer::GetEngineInfo(String EngineName) {
719     dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
720 senkov 120 LSCPResultSet result;
721 persson 841 LockRTNotify();
722 schoenebeck 53 try {
723 schoenebeck 411 Engine* pEngine = EngineFactory::Create(EngineName);
724     result.Add("DESCRIPTION", pEngine->Description());
725     result.Add("VERSION", pEngine->Version());
726 schoenebeck 660 EngineFactory::Destroy(pEngine);
727 schoenebeck 53 }
728 schoenebeck 880 catch (Exception e) {
729 senkov 120 result.Error(e);
730 schoenebeck 53 }
731 persson 841 UnlockRTNotify();
732 senkov 120 return result.Produce();
733 schoenebeck 35 }
734    
735     /**
736     * Will be called by the parser to get informations about a particular
737     * sampler channel.
738     */
739 schoenebeck 53 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
740     dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
741 senkov 120 LSCPResultSet result;
742 senkov 113 try {
743     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
744 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
745 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
746 schoenebeck 123
747 senkov 117 //Defaults values
748     String EngineName = "NONE";
749 schoenebeck 225 float Volume = 0.0f;
750 senkov 117 String InstrumentFileName = "NONE";
751 senkov 376 String InstrumentName = "NONE";
752 capela 133 int InstrumentIndex = -1;
753     int InstrumentStatus = -1;
754 schoenebeck 225 int AudioOutputChannels = 0;
755     String AudioRouting;
756 schoenebeck 705 int Mute = 0;
757     bool Solo = false;
758 iliev 1130 String MidiInstrumentMap = "NONE";
759 schoenebeck 123
760 schoenebeck 475 if (pEngineChannel) {
761     EngineName = pEngineChannel->EngineName();
762 schoenebeck 411 AudioOutputChannels = pEngineChannel->Channels();
763     Volume = pEngineChannel->Volume();
764     InstrumentStatus = pEngineChannel->InstrumentStatus();
765     InstrumentIndex = pEngineChannel->InstrumentIndex();
766     if (InstrumentIndex != -1) {
767     InstrumentFileName = pEngineChannel->InstrumentFileName();
768     InstrumentName = pEngineChannel->InstrumentName();
769     }
770     for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
771 schoenebeck 225 if (AudioRouting != "") AudioRouting += ",";
772 schoenebeck 411 AudioRouting += ToString(pEngineChannel->OutputChannel(chan));
773 schoenebeck 225 }
774 schoenebeck 705 Mute = pEngineChannel->GetMute();
775     Solo = pEngineChannel->GetSolo();
776 schoenebeck 973 if (pEngineChannel->UsesNoMidiInstrumentMap())
777     MidiInstrumentMap = "NONE";
778     else if (pEngineChannel->UsesDefaultMidiInstrumentMap())
779     MidiInstrumentMap = "DEFAULT";
780     else
781     MidiInstrumentMap = ToString(pEngineChannel->GetMidiInstrumentMap());
782 senkov 113 }
783 senkov 117
784     result.Add("ENGINE_NAME", EngineName);
785     result.Add("VOLUME", Volume);
786    
787 capela 143 //Some not-so-hardcoded stuff to make GUI look good
788     result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
789 schoenebeck 225 result.Add("AUDIO_OUTPUT_CHANNELS", AudioOutputChannels);
790     result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
791 senkov 113
792 capela 159 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
793     result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
794 schoenebeck 675 if (pSamplerChannel->GetMidiInputChannel() == midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
795 schoenebeck 274 else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
796 capela 159
797 senkov 117 result.Add("INSTRUMENT_FILE", InstrumentFileName);
798     result.Add("INSTRUMENT_NR", InstrumentIndex);
799 senkov 376 result.Add("INSTRUMENT_NAME", InstrumentName);
800 capela 133 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
801 schoenebeck 705 result.Add("MUTE", Mute == -1 ? "MUTED_BY_SOLO" : (Mute ? "true" : "false"));
802     result.Add("SOLO", Solo);
803 schoenebeck 973 result.Add("MIDI_INSTRUMENT_MAP", MidiInstrumentMap);
804 senkov 113 }
805 schoenebeck 880 catch (Exception e) {
806 senkov 120 result.Error(e);
807 senkov 113 }
808 senkov 120 return result.Produce();
809 schoenebeck 35 }
810    
811     /**
812     * Will be called by the parser to get the amount of active voices on a
813     * particular sampler channel.
814     */
815 schoenebeck 53 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
816     dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
817 senkov 120 LSCPResultSet result;
818 schoenebeck 53 try {
819     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
820 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
821 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
822 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine loaded on sampler channel");
823     if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
824 schoenebeck 411 result.Add(pEngineChannel->GetEngine()->VoiceCount());
825 schoenebeck 53 }
826 schoenebeck 880 catch (Exception e) {
827 senkov 120 result.Error(e);
828 schoenebeck 53 }
829 senkov 120 return result.Produce();
830 schoenebeck 35 }
831    
832     /**
833     * Will be called by the parser to get the amount of active disk streams on a
834     * particular sampler channel.
835     */
836 schoenebeck 53 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
837     dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
838 senkov 120 LSCPResultSet result;
839 schoenebeck 53 try {
840     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
841 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
842 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
843 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
844     if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
845 schoenebeck 411 result.Add(pEngineChannel->GetEngine()->DiskStreamCount());
846 schoenebeck 53 }
847 schoenebeck 880 catch (Exception e) {
848 senkov 120 result.Error(e);
849 schoenebeck 53 }
850 senkov 120 return result.Produce();
851 schoenebeck 35 }
852    
853     /**
854     * Will be called by the parser to get the buffer fill states of all disk
855     * streams on a particular sampler channel.
856     */
857 schoenebeck 53 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
858     dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
859 senkov 120 LSCPResultSet result;
860 schoenebeck 53 try {
861     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
862 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
863 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
864 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
865     if (!pEngineChannel->GetEngine()) throw Exception("No audio output device connected to sampler channel");
866 schoenebeck 411 if (!pEngineChannel->GetEngine()->DiskStreamSupported()) result.Add("NA");
867 senkov 129 else {
868     switch (ResponseType) {
869     case fill_response_bytes:
870 schoenebeck 411 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillBytes());
871     break;
872 senkov 129 case fill_response_percentage:
873 schoenebeck 411 result.Add(pEngineChannel->GetEngine()->DiskStreamBufferFillPercentage());
874     break;
875 senkov 129 default:
876 schoenebeck 880 throw Exception("Unknown fill response type");
877 senkov 129 }
878     }
879 schoenebeck 53 }
880 schoenebeck 880 catch (Exception e) {
881 senkov 120 result.Error(e);
882 schoenebeck 53 }
883 senkov 120 return result.Produce();
884 schoenebeck 35 }
885    
886 schoenebeck 123 String LSCPServer::GetAvailableAudioOutputDrivers() {
887     dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
888 senkov 120 LSCPResultSet result;
889 schoenebeck 53 try {
890 capela 527 int n = AudioOutputDeviceFactory::AvailableDrivers().size();
891     result.Add(n);
892     }
893 schoenebeck 880 catch (Exception e) {
894 capela 527 result.Error(e);
895     }
896     return result.Produce();
897     }
898    
899     String LSCPServer::ListAvailableAudioOutputDrivers() {
900     dmsg(2,("LSCPServer: ListAvailableAudioOutputDrivers()\n"));
901     LSCPResultSet result;
902     try {
903 schoenebeck 123 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
904     result.Add(s);
905 schoenebeck 53 }
906 schoenebeck 880 catch (Exception e) {
907 schoenebeck 123 result.Error(e);
908 schoenebeck 53 }
909 senkov 120 return result.Produce();
910 schoenebeck 35 }
911    
912 senkov 155 String LSCPServer::GetAvailableMidiInputDrivers() {
913     dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
914     LSCPResultSet result;
915     try {
916 capela 527 int n = MidiInputDeviceFactory::AvailableDrivers().size();
917     result.Add(n);
918     }
919 schoenebeck 880 catch (Exception e) {
920 capela 527 result.Error(e);
921     }
922     return result.Produce();
923     }
924    
925     String LSCPServer::ListAvailableMidiInputDrivers() {
926     dmsg(2,("LSCPServer: ListAvailableMidiInputDrivers()\n"));
927     LSCPResultSet result;
928     try {
929 senkov 155 String s = MidiInputDeviceFactory::AvailableDriversAsString();
930     result.Add(s);
931     }
932 schoenebeck 880 catch (Exception e) {
933 senkov 155 result.Error(e);
934     }
935     return result.Produce();
936     }
937    
938     String LSCPServer::GetMidiInputDriverInfo(String Driver) {
939     dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
940     LSCPResultSet result;
941     try {
942     result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
943     result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
944    
945     std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
946     if (parameters.size()) { // if there are parameters defined for this driver
947     String s;
948     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
949     for (;iter != parameters.end(); iter++) {
950     if (s != "") s += ",";
951     s += iter->first;
952     }
953     result.Add("PARAMETERS", s);
954     }
955     }
956 schoenebeck 880 catch (Exception e) {
957 senkov 155 result.Error(e);
958     }
959     return result.Produce();
960     }
961    
962 schoenebeck 123 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
963     dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
964     LSCPResultSet result;
965     try {
966     result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
967     result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
968    
969     std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
970     if (parameters.size()) { // if there are parameters defined for this driver
971     String s;
972     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
973     for (;iter != parameters.end(); iter++) {
974     if (s != "") s += ",";
975     s += iter->first;
976     }
977     result.Add("PARAMETERS", s);
978     }
979     }
980 schoenebeck 880 catch (Exception e) {
981 schoenebeck 123 result.Error(e);
982     }
983     return result.Produce();
984     }
985    
986 senkov 155 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
987 schoenebeck 226 dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
988 senkov 155 LSCPResultSet result;
989     try {
990     DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
991     result.Add("TYPE", pParameter->Type());
992     result.Add("DESCRIPTION", pParameter->Description());
993 schoenebeck 223 result.Add("MANDATORY", pParameter->Mandatory());
994     result.Add("FIX", pParameter->Fix());
995     result.Add("MULTIPLICITY", pParameter->Multiplicity());
996 schoenebeck 226 optional<String> oDepends = pParameter->Depends();
997     optional<String> oDefault = pParameter->Default(DependencyList);
998     optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
999     optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
1000     optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
1001     if (oDepends) result.Add("DEPENDS", *oDepends);
1002     if (oDefault) result.Add("DEFAULT", *oDefault);
1003     if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
1004     if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
1005     if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1006 senkov 155 }
1007 schoenebeck 880 catch (Exception e) {
1008 senkov 155 result.Error(e);
1009     }
1010     return result.Produce();
1011     }
1012    
1013 schoenebeck 123 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1014 schoenebeck 226 dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
1015 schoenebeck 123 LSCPResultSet result;
1016     try {
1017     DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
1018     result.Add("TYPE", pParameter->Type());
1019     result.Add("DESCRIPTION", pParameter->Description());
1020 schoenebeck 223 result.Add("MANDATORY", pParameter->Mandatory());
1021     result.Add("FIX", pParameter->Fix());
1022     result.Add("MULTIPLICITY", pParameter->Multiplicity());
1023 schoenebeck 226 optional<String> oDepends = pParameter->Depends();
1024     optional<String> oDefault = pParameter->Default(DependencyList);
1025     optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
1026     optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
1027     optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
1028     if (oDepends) result.Add("DEPENDS", *oDepends);
1029     if (oDefault) result.Add("DEFAULT", *oDefault);
1030     if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
1031     if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
1032     if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
1033 schoenebeck 123 }
1034 schoenebeck 880 catch (Exception e) {
1035 schoenebeck 123 result.Error(e);
1036     }
1037     return result.Produce();
1038     }
1039    
1040     String LSCPServer::GetAudioOutputDeviceCount() {
1041     dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
1042     LSCPResultSet result;
1043     try {
1044     uint count = pSampler->AudioOutputDevices();
1045 senkov 138 result.Add(count); // success
1046 schoenebeck 123 }
1047 schoenebeck 880 catch (Exception e) {
1048 schoenebeck 123 result.Error(e);
1049     }
1050     return result.Produce();
1051     }
1052    
1053 senkov 155 String LSCPServer::GetMidiInputDeviceCount() {
1054     dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
1055     LSCPResultSet result;
1056     try {
1057     uint count = pSampler->MidiInputDevices();
1058     result.Add(count); // success
1059     }
1060 schoenebeck 880 catch (Exception e) {
1061 senkov 155 result.Error(e);
1062     }
1063     return result.Produce();
1064     }
1065    
1066 schoenebeck 123 String LSCPServer::GetAudioOutputDevices() {
1067     dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
1068     LSCPResultSet result;
1069     try {
1070     String s;
1071     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1072     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1073     for (; iter != devices.end(); iter++) {
1074     if (s != "") s += ",";
1075     s += ToString(iter->first);
1076     }
1077     result.Add(s);
1078     }
1079 schoenebeck 880 catch (Exception e) {
1080 schoenebeck 123 result.Error(e);
1081     }
1082     return result.Produce();
1083     }
1084    
1085 senkov 155 String LSCPServer::GetMidiInputDevices() {
1086     dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
1087     LSCPResultSet result;
1088     try {
1089     String s;
1090     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1091     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1092     for (; iter != devices.end(); iter++) {
1093     if (s != "") s += ",";
1094     s += ToString(iter->first);
1095     }
1096     result.Add(s);
1097     }
1098 schoenebeck 880 catch (Exception e) {
1099 senkov 155 result.Error(e);
1100     }
1101     return result.Produce();
1102     }
1103    
1104 schoenebeck 123 String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
1105     dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1106     LSCPResultSet result;
1107     try {
1108     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1109 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1110 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
1111 schoenebeck 221 result.Add("DRIVER", pDevice->Driver());
1112 schoenebeck 123 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1113     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1114     for (; iter != parameters.end(); iter++) {
1115     result.Add(iter->first, iter->second->Value());
1116     }
1117     }
1118 schoenebeck 880 catch (Exception e) {
1119 schoenebeck 123 result.Error(e);
1120     }
1121     return result.Produce();
1122     }
1123    
1124 senkov 155 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
1125     dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
1126     LSCPResultSet result;
1127     try {
1128     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1129 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1130 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1131 schoenebeck 221 result.Add("DRIVER", pDevice->Driver());
1132 senkov 155 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1133     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
1134     for (; iter != parameters.end(); iter++) {
1135     result.Add(iter->first, iter->second->Value());
1136     }
1137     }
1138 schoenebeck 880 catch (Exception e) {
1139 senkov 155 result.Error(e);
1140     }
1141     return result.Produce();
1142     }
1143     String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
1144     dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
1145     LSCPResultSet result;
1146     try {
1147 schoenebeck 223 // get MIDI input device
1148 senkov 155 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1149 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1150 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1151 schoenebeck 223
1152     // get MIDI port
1153 schoenebeck 221 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1154 schoenebeck 880 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1155 schoenebeck 223
1156     // return the values of all MIDI port parameters
1157 schoenebeck 221 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1158     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1159 senkov 155 for (; iter != parameters.end(); iter++) {
1160     result.Add(iter->first, iter->second->Value());
1161     }
1162     }
1163 schoenebeck 880 catch (Exception e) {
1164 senkov 155 result.Error(e);
1165     }
1166     return result.Produce();
1167     }
1168    
1169 schoenebeck 123 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
1170     dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
1171     LSCPResultSet result;
1172     try {
1173     // get audio output device
1174     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1175 schoenebeck 880 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1176 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
1177    
1178     // get audio channel
1179     AudioChannel* pChannel = pDevice->Channel(ChannelId);
1180 schoenebeck 880 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1181 schoenebeck 123
1182     // return the values of all audio channel parameters
1183     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1184     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
1185     for (; iter != parameters.end(); iter++) {
1186     result.Add(iter->first, iter->second->Value());
1187     }
1188     }
1189 schoenebeck 880 catch (Exception e) {
1190 schoenebeck 123 result.Error(e);
1191     }
1192     return result.Produce();
1193     }
1194    
1195 senkov 185 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
1196     dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
1197     LSCPResultSet result;
1198     try {
1199 schoenebeck 223 // get MIDI input device
1200     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1201 schoenebeck 880 if (!devices.count(DeviceId)) throw Exception("There is no midi input device with index " + ToString(DeviceId) + ".");
1202 schoenebeck 223 MidiInputDevice* pDevice = devices[DeviceId];
1203 senkov 185
1204 schoenebeck 221 // get midi port
1205     MidiInputPort* pPort = pDevice->GetPort(PortId);
1206 schoenebeck 880 if (!pPort) throw Exception("Midi input device does not have port " + ToString(PortId) + ".");
1207 senkov 185
1208 schoenebeck 223 // get desired port parameter
1209     std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
1210 schoenebeck 880 if (!parameters.count(ParameterName)) throw Exception("Midi port does not provide a parameter '" + ParameterName + "'.");
1211 schoenebeck 223 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1212 schoenebeck 203
1213 senkov 185 // return all fields of this audio channel parameter
1214     result.Add("TYPE", pParameter->Type());
1215     result.Add("DESCRIPTION", pParameter->Description());
1216     result.Add("FIX", pParameter->Fix());
1217     result.Add("MULTIPLICITY", pParameter->Multiplicity());
1218 schoenebeck 223 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1219     if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1220     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1221 senkov 185 }
1222 schoenebeck 880 catch (Exception e) {
1223 senkov 185 result.Error(e);
1224     }
1225     return result.Produce();
1226     }
1227    
1228 schoenebeck 123 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
1229     dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
1230     LSCPResultSet result;
1231     try {
1232     // get audio output device
1233     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1234 schoenebeck 880 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1235 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
1236    
1237     // get audio channel
1238     AudioChannel* pChannel = pDevice->Channel(ChannelId);
1239 schoenebeck 880 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1240 schoenebeck 123
1241     // get desired audio channel parameter
1242     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1243 schoenebeck 880 if (!parameters.count(ParameterName)) throw Exception("Audio channel does not provide a parameter '" + ParameterName + "'.");
1244 schoenebeck 123 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1245    
1246     // return all fields of this audio channel parameter
1247     result.Add("TYPE", pParameter->Type());
1248     result.Add("DESCRIPTION", pParameter->Description());
1249     result.Add("FIX", pParameter->Fix());
1250     result.Add("MULTIPLICITY", pParameter->Multiplicity());
1251 schoenebeck 223 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1252     if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1253     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1254 schoenebeck 123 }
1255 schoenebeck 880 catch (Exception e) {
1256 schoenebeck 123 result.Error(e);
1257     }
1258     return result.Produce();
1259     }
1260    
1261     String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
1262     dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
1263     LSCPResultSet result;
1264     try {
1265     // get audio output device
1266     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1267 schoenebeck 880 if (!devices.count(DeviceId)) throw Exception("There is no audio output device with index " + ToString(DeviceId) + ".");
1268 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
1269    
1270     // get audio channel
1271     AudioChannel* pChannel = pDevice->Channel(ChannelId);
1272 schoenebeck 880 if (!pChannel) throw Exception("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1273 schoenebeck 123
1274     // get desired audio channel parameter
1275     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1276 schoenebeck 880 if (!parameters.count(ParamKey)) throw Exception("Audio channel does not provide a parameter '" + ParamKey + "'.");
1277 schoenebeck 123 DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1278    
1279     // set new channel parameter value
1280     pParameter->SetValue(ParamVal);
1281 iliev 981 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceId));
1282 schoenebeck 123 }
1283 schoenebeck 880 catch (Exception e) {
1284 schoenebeck 123 result.Error(e);
1285     }
1286     return result.Produce();
1287     }
1288    
1289     String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1290     dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1291     LSCPResultSet result;
1292     try {
1293     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1294 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1295 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
1296     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1297 schoenebeck 880 if (!parameters.count(ParamKey)) throw Exception("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1298 schoenebeck 123 parameters[ParamKey]->SetValue(ParamVal);
1299 iliev 981 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_audio_device_info, DeviceIndex));
1300 schoenebeck 123 }
1301 schoenebeck 880 catch (Exception e) {
1302 schoenebeck 123 result.Error(e);
1303     }
1304     return result.Produce();
1305     }
1306    
1307 senkov 155 String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1308     dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1309     LSCPResultSet result;
1310     try {
1311     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1312 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1313 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1314     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1315 schoenebeck 880 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1316 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1317 iliev 981 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1318 senkov 155 }
1319 schoenebeck 880 catch (Exception e) {
1320 senkov 155 result.Error(e);
1321     }
1322     return result.Produce();
1323     }
1324    
1325     String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1326     dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1327     LSCPResultSet result;
1328     try {
1329 schoenebeck 223 // get MIDI input device
1330 senkov 155 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1331 schoenebeck 880 if (!devices.count(DeviceIndex)) throw Exception("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1332 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1333 schoenebeck 223
1334     // get MIDI port
1335 schoenebeck 221 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1336 schoenebeck 880 if (!pMidiInputPort) throw Exception("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1337 schoenebeck 223
1338     // set port parameter value
1339 schoenebeck 221 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1340 schoenebeck 880 if (!parameters.count(ParamKey)) throw Exception("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1341 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1342 iliev 981 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_midi_device_info, DeviceIndex));
1343 senkov 155 }
1344 schoenebeck 880 catch (Exception e) {
1345 senkov 155 result.Error(e);
1346     }
1347     return result.Produce();
1348     }
1349    
1350 schoenebeck 35 /**
1351     * Will be called by the parser to change the audio output channel for
1352     * playback on a particular sampler channel.
1353     */
1354 schoenebeck 123 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1355     dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1356 schoenebeck 225 LSCPResultSet result;
1357     try {
1358     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1359 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1360 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1361 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type yet assigned to sampler channel " + ToString(uiSamplerChannel));
1362     if (!pSamplerChannel->GetAudioOutputDevice()) throw Exception("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1363 schoenebeck 411 pEngineChannel->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1364 schoenebeck 225 }
1365 schoenebeck 880 catch (Exception e) {
1366 schoenebeck 225 result.Error(e);
1367     }
1368     return result.Produce();
1369 schoenebeck 35 }
1370    
1371 capela 159 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1372     dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1373     LSCPResultSet result;
1374 persson 841 LockRTNotify();
1375 capela 159 try {
1376     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1377 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1378 capela 159 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1379 schoenebeck 880 if (!devices.count(AudioDeviceId)) throw Exception("There is no audio output device with index " + ToString(AudioDeviceId));
1380 capela 159 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1381     pSamplerChannel->SetAudioOutputDevice(pDevice);
1382     }
1383 schoenebeck 880 catch (Exception e) {
1384 capela 159 result.Error(e);
1385     }
1386 persson 841 UnlockRTNotify();
1387 capela 159 return result.Produce();
1388     }
1389    
1390 capela 143 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1391     dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1392     LSCPResultSet result;
1393 persson 841 LockRTNotify();
1394 capela 143 try {
1395     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1396 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1397 capela 143 // Driver type name aliasing...
1398 schoenebeck 226 if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1399     if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1400 capela 143 // Check if there's one audio output device already created
1401     // for the intended audio driver type (AudioOutputDriver)...
1402     AudioOutputDevice *pDevice = NULL;
1403     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1404     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1405     for (; iter != devices.end(); iter++) {
1406     if ((iter->second)->Driver() == AudioOutputDriver) {
1407     pDevice = iter->second;
1408     break;
1409     }
1410     }
1411     // If it doesn't exist, create a new one with default parameters...
1412     if (pDevice == NULL) {
1413     std::map<String,String> params;
1414     pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1415     }
1416     // Must have a device...
1417     if (pDevice == NULL)
1418 schoenebeck 880 throw Exception("Internal error: could not create audio output device.");
1419 capela 143 // Set it as the current channel device...
1420     pSamplerChannel->SetAudioOutputDevice(pDevice);
1421     }
1422 schoenebeck 880 catch (Exception e) {
1423 capela 143 result.Error(e);
1424     }
1425 persson 841 UnlockRTNotify();
1426 capela 143 return result.Produce();
1427     }
1428    
1429 capela 159 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1430     dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1431 senkov 120 LSCPResultSet result;
1432 schoenebeck 53 try {
1433     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1434 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1435 capela 159 pSamplerChannel->SetMidiInputPort(MIDIPort);
1436 schoenebeck 53 }
1437 schoenebeck 880 catch (Exception e) {
1438 senkov 120 result.Error(e);
1439 schoenebeck 53 }
1440 senkov 120 return result.Produce();
1441 schoenebeck 53 }
1442    
1443 capela 159 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1444     dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1445 senkov 120 LSCPResultSet result;
1446 senkov 68 try {
1447     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1448 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1449 schoenebeck 675 pSamplerChannel->SetMidiInputChannel((midi_chan_t) MIDIChannel);
1450 senkov 68 }
1451 schoenebeck 880 catch (Exception e) {
1452 senkov 120 result.Error(e);
1453 senkov 68 }
1454 senkov 120 return result.Produce();
1455 schoenebeck 35 }
1456    
1457 capela 159 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1458     dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1459 schoenebeck 123 LSCPResultSet result;
1460     try {
1461 capela 159 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1462 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1463 capela 159 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1464 schoenebeck 880 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1465 capela 159 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1466     pSamplerChannel->SetMidiInputDevice(pDevice);
1467 schoenebeck 123 }
1468 schoenebeck 880 catch (Exception e) {
1469 schoenebeck 123 result.Error(e);
1470     }
1471     return result.Produce();
1472     }
1473    
1474 capela 159 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1475     dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1476     LSCPResultSet result;
1477     try {
1478     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1479 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1480 capela 159 // Driver type name aliasing...
1481 schoenebeck 226 if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1482 capela 159 // Check if there's one MIDI input device already created
1483     // for the intended MIDI driver type (MidiInputDriver)...
1484     MidiInputDevice *pDevice = NULL;
1485     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1486     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1487     for (; iter != devices.end(); iter++) {
1488     if ((iter->second)->Driver() == MidiInputDriver) {
1489     pDevice = iter->second;
1490     break;
1491     }
1492     }
1493     // If it doesn't exist, create a new one with default parameters...
1494     if (pDevice == NULL) {
1495     std::map<String,String> params;
1496     pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1497     // Make it with at least one initial port.
1498     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1499 schoenebeck 221 parameters["PORTS"]->SetValue("1");
1500 capela 159 }
1501     // Must have a device...
1502     if (pDevice == NULL)
1503 schoenebeck 880 throw Exception("Internal error: could not create MIDI input device.");
1504 capela 159 // Set it as the current channel device...
1505     pSamplerChannel->SetMidiInputDevice(pDevice);
1506     }
1507 schoenebeck 880 catch (Exception e) {
1508 capela 159 result.Error(e);
1509     }
1510     return result.Produce();
1511     }
1512    
1513 schoenebeck 35 /**
1514 capela 159 * Will be called by the parser to change the MIDI input device, port and channel on which
1515     * engine of a particular sampler channel should listen to.
1516     */
1517     String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1518     dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1519     LSCPResultSet result;
1520     try {
1521     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1522 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1523 capela 159 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1524 schoenebeck 880 if (!devices.count(MIDIDeviceId)) throw Exception("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1525 capela 159 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1526 schoenebeck 675 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (midi_chan_t) MIDIChannel);
1527 capela 159 }
1528 schoenebeck 880 catch (Exception e) {
1529 capela 159 result.Error(e);
1530     }
1531     return result.Produce();
1532     }
1533    
1534     /**
1535 schoenebeck 35 * Will be called by the parser to change the global volume factor on a
1536     * particular sampler channel.
1537     */
1538 schoenebeck 225 String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
1539     dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1540 senkov 120 LSCPResultSet result;
1541 schoenebeck 53 try {
1542     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1543 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1544 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1545 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1546 schoenebeck 411 pEngineChannel->Volume(dVolume);
1547 schoenebeck 53 }
1548 schoenebeck 880 catch (Exception e) {
1549 senkov 120 result.Error(e);
1550 schoenebeck 53 }
1551 senkov 120 return result.Produce();
1552 schoenebeck 35 }
1553    
1554     /**
1555 schoenebeck 705 * Will be called by the parser to mute/unmute particular sampler channel.
1556     */
1557     String LSCPServer::SetChannelMute(bool bMute, uint uiSamplerChannel) {
1558     dmsg(2,("LSCPServer: SetChannelMute(bMute=%d,uiSamplerChannel=%d)\n",bMute,uiSamplerChannel));
1559     LSCPResultSet result;
1560     try {
1561     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1562 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1563 schoenebeck 705
1564     EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1565 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1566 schoenebeck 705
1567     if(!bMute) pEngineChannel->SetMute((HasSoloChannel() && !pEngineChannel->GetSolo()) ? -1 : 0);
1568     else pEngineChannel->SetMute(1);
1569 schoenebeck 880 } catch (Exception e) {
1570 schoenebeck 705 result.Error(e);
1571     }
1572     return result.Produce();
1573     }
1574    
1575     /**
1576     * Will be called by the parser to solo particular sampler channel.
1577     */
1578     String LSCPServer::SetChannelSolo(bool bSolo, uint uiSamplerChannel) {
1579     dmsg(2,("LSCPServer: SetChannelSolo(bSolo=%d,uiSamplerChannel=%d)\n",bSolo,uiSamplerChannel));
1580     LSCPResultSet result;
1581     try {
1582     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1583 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1584 schoenebeck 705
1585     EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1586 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
1587 schoenebeck 705
1588     bool oldSolo = pEngineChannel->GetSolo();
1589     bool hadSoloChannel = HasSoloChannel();
1590 schoenebeck 1009
1591 schoenebeck 705 pEngineChannel->SetSolo(bSolo);
1592 schoenebeck 1009
1593 schoenebeck 705 if(!oldSolo && bSolo) {
1594     if(pEngineChannel->GetMute() == -1) pEngineChannel->SetMute(0);
1595     if(!hadSoloChannel) MuteNonSoloChannels();
1596     }
1597 schoenebeck 1009
1598 schoenebeck 705 if(oldSolo && !bSolo) {
1599     if(!HasSoloChannel()) UnmuteChannels();
1600     else if(!pEngineChannel->GetMute()) pEngineChannel->SetMute(-1);
1601     }
1602 schoenebeck 880 } catch (Exception e) {
1603 schoenebeck 705 result.Error(e);
1604     }
1605     return result.Produce();
1606     }
1607    
1608     /**
1609     * Determines whether there is at least one solo channel in the channel list.
1610     *
1611     * @returns true if there is at least one solo channel in the channel list,
1612     * false otherwise.
1613     */
1614     bool LSCPServer::HasSoloChannel() {
1615     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1616     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1617     for (; iter != channels.end(); iter++) {
1618     EngineChannel* c = iter->second->GetEngineChannel();
1619     if(c && c->GetSolo()) return true;
1620     }
1621    
1622     return false;
1623     }
1624    
1625     /**
1626     * Mutes all unmuted non-solo channels. Notice that the channels are muted
1627     * with -1 which indicates that they are muted because of the presence
1628     * of a solo channel(s). Channels muted with -1 will be automatically unmuted
1629     * when there are no solo channels left.
1630     */
1631     void LSCPServer::MuteNonSoloChannels() {
1632     dmsg(2,("LSCPServer: MuteNonSoloChannels()\n"));
1633     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1634     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1635     for (; iter != channels.end(); iter++) {
1636     EngineChannel* c = iter->second->GetEngineChannel();
1637     if(c && !c->GetSolo() && !c->GetMute()) c->SetMute(-1);
1638     }
1639     }
1640    
1641     /**
1642     * Unmutes all channels that are muted because of the presence
1643     * of a solo channel(s).
1644     */
1645     void LSCPServer::UnmuteChannels() {
1646     dmsg(2,("LSCPServer: UnmuteChannels()\n"));
1647     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
1648     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
1649     for (; iter != channels.end(); iter++) {
1650     EngineChannel* c = iter->second->GetEngineChannel();
1651     if(c && c->GetMute() == -1) c->SetMute(0);
1652     }
1653     }
1654    
1655 schoenebeck 1047 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) {
1656 schoenebeck 947 dmsg(2,("LSCPServer: AddOrReplaceMIDIInstrumentMapping()\n"));
1657    
1658     midi_prog_index_t idx;
1659 schoenebeck 973 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1660     idx.midi_bank_lsb = MidiBank & 0x7f;
1661 schoenebeck 947 idx.midi_prog = MidiProg;
1662    
1663     MidiInstrumentMapper::entry_t entry;
1664     entry.EngineName = EngineType;
1665     entry.InstrumentFile = InstrumentFile;
1666     entry.InstrumentIndex = InstrumentIndex;
1667     entry.LoadMode = LoadMode;
1668     entry.Volume = Volume;
1669     entry.Name = Name;
1670    
1671     LSCPResultSet result;
1672     try {
1673 schoenebeck 1047 // PERSISTENT mapping commands might block for a long time, so in
1674     // that case we add/replace the mapping in another thread in case
1675     // the NON_MODAL argument was supplied, non persistent mappings
1676     // should return immediately, so we don't need to do that for them
1677     bool bInBackground = (entry.LoadMode == MidiInstrumentMapper::PERSISTENT && !bModal);
1678 schoenebeck 973 MidiInstrumentMapper::AddOrReplaceEntry(MidiMapID, idx, entry, bInBackground);
1679 schoenebeck 947 } catch (Exception e) {
1680     result.Error(e);
1681     }
1682     return result.Produce();
1683     }
1684    
1685 schoenebeck 973 String LSCPServer::RemoveMIDIInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1686 schoenebeck 947 dmsg(2,("LSCPServer: RemoveMIDIInstrumentMapping()\n"));
1687    
1688     midi_prog_index_t idx;
1689 schoenebeck 973 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1690     idx.midi_bank_lsb = MidiBank & 0x7f;
1691 schoenebeck 947 idx.midi_prog = MidiProg;
1692    
1693     LSCPResultSet result;
1694     try {
1695 schoenebeck 973 MidiInstrumentMapper::RemoveEntry(MidiMapID, idx);
1696 schoenebeck 947 } catch (Exception e) {
1697     result.Error(e);
1698     }
1699     return result.Produce();
1700     }
1701    
1702 schoenebeck 973 String LSCPServer::GetMidiInstrumentMappings(uint MidiMapID) {
1703     dmsg(2,("LSCPServer: GetMidiInstrumentMappings()\n"));
1704 schoenebeck 947 LSCPResultSet result;
1705 schoenebeck 973 try {
1706     result.Add(MidiInstrumentMapper::Entries(MidiMapID).size());
1707     } catch (Exception e) {
1708     result.Error(e);
1709     }
1710 schoenebeck 947 return result.Produce();
1711     }
1712    
1713 schoenebeck 973
1714     String LSCPServer::GetAllMidiInstrumentMappings() {
1715     dmsg(2,("LSCPServer: GetAllMidiInstrumentMappings()\n"));
1716     LSCPResultSet result;
1717     std::vector<int> maps = MidiInstrumentMapper::Maps();
1718     int totalMappings = 0;
1719     for (int i = 0; i < maps.size(); i++) {
1720     try {
1721     totalMappings += MidiInstrumentMapper::Entries(maps[i]).size();
1722     } catch (Exception e) { /*NOOP*/ }
1723     }
1724     result.Add(totalMappings);
1725     return result.Produce();
1726     }
1727    
1728     String LSCPServer::GetMidiInstrumentMapping(uint MidiMapID, uint MidiBank, uint MidiProg) {
1729 schoenebeck 947 dmsg(2,("LSCPServer: GetMidiIstrumentMapping()\n"));
1730     LSCPResultSet result;
1731     try {
1732     midi_prog_index_t idx;
1733 schoenebeck 973 idx.midi_bank_msb = (MidiBank >> 7) & 0x7f;
1734     idx.midi_bank_lsb = MidiBank & 0x7f;
1735 schoenebeck 947 idx.midi_prog = MidiProg;
1736    
1737 schoenebeck 973 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1738 schoenebeck 947 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.find(idx);
1739     if (iter == mappings.end()) result.Error("there is no map entry with that index");
1740     else { // found
1741     result.Add("NAME", iter->second.Name);
1742     result.Add("ENGINE_NAME", iter->second.EngineName);
1743     result.Add("INSTRUMENT_FILE", iter->second.InstrumentFile);
1744     result.Add("INSTRUMENT_NR", (int) iter->second.InstrumentIndex);
1745     String instrumentName;
1746     Engine* pEngine = EngineFactory::Create(iter->second.EngineName);
1747     if (pEngine) {
1748     if (pEngine->GetInstrumentManager()) {
1749     InstrumentManager::instrument_id_t instrID;
1750     instrID.FileName = iter->second.InstrumentFile;
1751     instrID.Index = iter->second.InstrumentIndex;
1752     instrumentName = pEngine->GetInstrumentManager()->GetInstrumentName(instrID);
1753     }
1754     EngineFactory::Destroy(pEngine);
1755     }
1756     result.Add("INSTRUMENT_NAME", instrumentName);
1757     switch (iter->second.LoadMode) {
1758     case MidiInstrumentMapper::ON_DEMAND:
1759     result.Add("LOAD_MODE", "ON_DEMAND");
1760     break;
1761     case MidiInstrumentMapper::ON_DEMAND_HOLD:
1762     result.Add("LOAD_MODE", "ON_DEMAND_HOLD");
1763     break;
1764     case MidiInstrumentMapper::PERSISTENT:
1765     result.Add("LOAD_MODE", "PERSISTENT");
1766     break;
1767     default:
1768     throw Exception("entry reflects invalid LOAD_MODE, consider this as a bug!");
1769     }
1770     result.Add("VOLUME", iter->second.Volume);
1771     }
1772     } catch (Exception e) {
1773     result.Error(e);
1774     }
1775     return result.Produce();
1776     }
1777    
1778 schoenebeck 973 String LSCPServer::ListMidiInstrumentMappings(uint MidiMapID) {
1779     dmsg(2,("LSCPServer: ListMidiInstrumentMappings()\n"));
1780 schoenebeck 947 LSCPResultSet result;
1781     try {
1782     String s;
1783 schoenebeck 973 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(MidiMapID);
1784 schoenebeck 947 std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1785     for (; iter != mappings.end(); iter++) {
1786     if (s.size()) s += ",";
1787 schoenebeck 973 s += "{" + ToString(MidiMapID) + ","
1788 schoenebeck 1007 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1789 schoenebeck 973 + ToString(int(iter->first.midi_prog)) + "}";
1790 schoenebeck 947 }
1791     result.Add(s);
1792     } catch (Exception e) {
1793     result.Error(e);
1794     }
1795     return result.Produce();
1796     }
1797    
1798 schoenebeck 973 String LSCPServer::ListAllMidiInstrumentMappings() {
1799     dmsg(2,("LSCPServer: ListAllMidiInstrumentMappings()\n"));
1800     LSCPResultSet result;
1801     try {
1802     std::vector<int> maps = MidiInstrumentMapper::Maps();
1803     String s;
1804     for (int i = 0; i < maps.size(); i++) {
1805     std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
1806     std::map<midi_prog_index_t,MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin();
1807     for (; iter != mappings.end(); iter++) {
1808     if (s.size()) s += ",";
1809     s += "{" + ToString(maps[i]) + ","
1810 schoenebeck 1009 + ToString((int(iter->first.midi_bank_msb) << 7) | int(iter->first.midi_bank_lsb)) + ","
1811 schoenebeck 973 + ToString(int(iter->first.midi_prog)) + "}";
1812     }
1813     }
1814     result.Add(s);
1815     } catch (Exception e) {
1816     result.Error(e);
1817     }
1818     return result.Produce();
1819     }
1820    
1821     String LSCPServer::ClearMidiInstrumentMappings(uint MidiMapID) {
1822 schoenebeck 947 dmsg(2,("LSCPServer: ClearMidiInstrumentMappings()\n"));
1823     LSCPResultSet result;
1824     try {
1825 schoenebeck 973 MidiInstrumentMapper::RemoveAllEntries(MidiMapID);
1826 schoenebeck 947 } catch (Exception e) {
1827     result.Error(e);
1828     }
1829     return result.Produce();
1830     }
1831    
1832 schoenebeck 973 String LSCPServer::ClearAllMidiInstrumentMappings() {
1833     dmsg(2,("LSCPServer: ClearAllMidiInstrumentMappings()\n"));
1834     LSCPResultSet result;
1835     try {
1836     std::vector<int> maps = MidiInstrumentMapper::Maps();
1837     for (int i = 0; i < maps.size(); i++)
1838     MidiInstrumentMapper::RemoveAllEntries(maps[i]);
1839     } catch (Exception e) {
1840     result.Error(e);
1841     }
1842     return result.Produce();
1843     }
1844    
1845     String LSCPServer::AddMidiInstrumentMap(String MapName) {
1846     dmsg(2,("LSCPServer: AddMidiInstrumentMap()\n"));
1847     LSCPResultSet result;
1848     try {
1849     int MapID = MidiInstrumentMapper::AddMap(MapName);
1850     result = LSCPResultSet(MapID);
1851     } catch (Exception e) {
1852     result.Error(e);
1853     }
1854     return result.Produce();
1855     }
1856    
1857     String LSCPServer::RemoveMidiInstrumentMap(uint MidiMapID) {
1858     dmsg(2,("LSCPServer: RemoveMidiInstrumentMap()\n"));
1859     LSCPResultSet result;
1860     try {
1861     MidiInstrumentMapper::RemoveMap(MidiMapID);
1862     } catch (Exception e) {
1863     result.Error(e);
1864     }
1865     return result.Produce();
1866     }
1867    
1868     String LSCPServer::RemoveAllMidiInstrumentMaps() {
1869     dmsg(2,("LSCPServer: RemoveAllMidiInstrumentMaps()\n"));
1870     LSCPResultSet result;
1871     try {
1872     MidiInstrumentMapper::RemoveAllMaps();
1873     } catch (Exception e) {
1874     result.Error(e);
1875     }
1876     return result.Produce();
1877     }
1878    
1879     String LSCPServer::GetMidiInstrumentMaps() {
1880     dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
1881     LSCPResultSet result;
1882     try {
1883     result.Add(MidiInstrumentMapper::Maps().size());
1884     } catch (Exception e) {
1885     result.Error(e);
1886     }
1887     return result.Produce();
1888     }
1889    
1890     String LSCPServer::ListMidiInstrumentMaps() {
1891     dmsg(2,("LSCPServer: ListMidiInstrumentMaps()\n"));
1892     LSCPResultSet result;
1893     try {
1894     std::vector<int> maps = MidiInstrumentMapper::Maps();
1895     String sList;
1896     for (int i = 0; i < maps.size(); i++) {
1897     if (sList != "") sList += ",";
1898     sList += ToString(maps[i]);
1899     }
1900     result.Add(sList);
1901     } catch (Exception e) {
1902     result.Error(e);
1903     }
1904     return result.Produce();
1905     }
1906    
1907     String LSCPServer::GetMidiInstrumentMap(uint MidiMapID) {
1908     dmsg(2,("LSCPServer: GetMidiInstrumentMap()\n"));
1909     LSCPResultSet result;
1910     try {
1911     result.Add("NAME", MidiInstrumentMapper::MapName(MidiMapID));
1912 iliev 1135 result.Add("DEFAULT", MidiInstrumentMapper::GetDefaultMap() == MidiMapID);
1913 schoenebeck 973 } catch (Exception e) {
1914     result.Error(e);
1915     }
1916     return result.Produce();
1917     }
1918    
1919     String LSCPServer::SetMidiInstrumentMapName(uint MidiMapID, String NewName) {
1920     dmsg(2,("LSCPServer: SetMidiInstrumentMapName()\n"));
1921     LSCPResultSet result;
1922     try {
1923     MidiInstrumentMapper::RenameMap(MidiMapID, NewName);
1924     } catch (Exception e) {
1925     result.Error(e);
1926     }
1927     return result.Produce();
1928     }
1929    
1930 schoenebeck 705 /**
1931 schoenebeck 973 * Set the MIDI instrument map the given sampler channel shall use for
1932     * handling MIDI program change messages. There are the following two
1933     * special (negative) values:
1934     *
1935     * - (-1) : set to NONE (ignore program changes)
1936     * - (-2) : set to DEFAULT map
1937     */
1938     String LSCPServer::SetChannelMap(uint uiSamplerChannel, int MidiMapID) {
1939     dmsg(2,("LSCPServer: SetChannelMap()\n"));
1940     LSCPResultSet result;
1941     try {
1942     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1943     if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
1944    
1945     EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
1946     if (!pEngineChannel) throw Exception("There is no engine deployed on this sampler channel yet");
1947    
1948     if (MidiMapID == -1) pEngineChannel->SetMidiInstrumentMapToNone();
1949     else if (MidiMapID == -2) pEngineChannel->SetMidiInstrumentMapToDefault();
1950     else pEngineChannel->SetMidiInstrumentMap(MidiMapID);
1951     } catch (Exception e) {
1952     result.Error(e);
1953     }
1954     return result.Produce();
1955     }
1956    
1957 schoenebeck 1001 String LSCPServer::CreateFxSend(uint uiSamplerChannel, uint MidiCtrl, String Name) {
1958     dmsg(2,("LSCPServer: CreateFxSend()\n"));
1959     LSCPResultSet result;
1960     try {
1961 iliev 1135 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1962    
1963 schoenebeck 1001 FxSend* pFxSend = pEngineChannel->AddFxSend(MidiCtrl, Name);
1964     if (!pFxSend) throw Exception("Could not add FxSend, don't ask, I don't know why (probably a bug)");
1965    
1966     result = LSCPResultSet(pFxSend->Id()); // success
1967     } catch (Exception e) {
1968     result.Error(e);
1969     }
1970     return result.Produce();
1971     }
1972    
1973     String LSCPServer::DestroyFxSend(uint uiSamplerChannel, uint FxSendID) {
1974     dmsg(2,("LSCPServer: DestroyFxSend()\n"));
1975     LSCPResultSet result;
1976     try {
1977 iliev 1135 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1978 schoenebeck 1001
1979     FxSend* pFxSend = NULL;
1980     for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
1981     if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
1982     pFxSend = pEngineChannel->GetFxSend(i);
1983     break;
1984     }
1985     }
1986     if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
1987     pEngineChannel->RemoveFxSend(pFxSend);
1988     } catch (Exception e) {
1989     result.Error(e);
1990     }
1991     return result.Produce();
1992     }
1993    
1994     String LSCPServer::GetFxSends(uint uiSamplerChannel) {
1995     dmsg(2,("LSCPServer: GetFxSends()\n"));
1996     LSCPResultSet result;
1997     try {
1998 iliev 1135 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
1999 schoenebeck 1001
2000     result.Add(pEngineChannel->GetFxSendCount());
2001     } catch (Exception e) {
2002     result.Error(e);
2003     }
2004     return result.Produce();
2005     }
2006    
2007     String LSCPServer::ListFxSends(uint uiSamplerChannel) {
2008     dmsg(2,("LSCPServer: ListFxSends()\n"));
2009     LSCPResultSet result;
2010     String list;
2011     try {
2012 iliev 1135 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2013 schoenebeck 1001
2014     for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2015     FxSend* pFxSend = pEngineChannel->GetFxSend(i);
2016     if (list != "") list += ",";
2017     list += ToString(pFxSend->Id());
2018     }
2019     result.Add(list);
2020     } catch (Exception e) {
2021     result.Error(e);
2022     }
2023     return result.Produce();
2024     }
2025    
2026 iliev 1135 FxSend* LSCPServer::GetFxSend(uint uiSamplerChannel, uint FxSendID) {
2027     EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2028    
2029     FxSend* pFxSend = NULL;
2030     for (int i = 0; i < pEngineChannel->GetFxSendCount(); i++) {
2031     if (pEngineChannel->GetFxSend(i)->Id() == FxSendID) {
2032     pFxSend = pEngineChannel->GetFxSend(i);
2033     break;
2034     }
2035     }
2036     if (!pFxSend) throw Exception("There is no FxSend with that ID on the given sampler channel");
2037     return pFxSend;
2038     }
2039    
2040 schoenebeck 1001 String LSCPServer::GetFxSendInfo(uint uiSamplerChannel, uint FxSendID) {
2041     dmsg(2,("LSCPServer: GetFxSendInfo()\n"));
2042     LSCPResultSet result;
2043     try {
2044 iliev 1135 EngineChannel* pEngineChannel = GetEngineChannel(uiSamplerChannel);
2045     FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2046    
2047 schoenebeck 1001 // gather audio routing informations
2048     String AudioRouting;
2049     for (int chan = 0; chan < pEngineChannel->Channels(); chan++) {
2050     if (AudioRouting != "") AudioRouting += ",";
2051     AudioRouting += ToString(pFxSend->DestinationChannel(chan));
2052     }
2053    
2054     // success
2055     result.Add("NAME", pFxSend->Name());
2056 schoenebeck 1026 result.Add("MIDI_CONTROLLER", pFxSend->MidiController());
2057     result.Add("LEVEL", ToString(pFxSend->Level()));
2058 schoenebeck 1001 result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
2059     } catch (Exception e) {
2060     result.Error(e);
2061     }
2062     return result.Produce();
2063     }
2064    
2065 iliev 1135 String LSCPServer::SetFxSendName(uint uiSamplerChannel, uint FxSendID, String Name) {
2066     dmsg(2,("LSCPServer: SetFxSendName()\n"));
2067     LSCPResultSet result;
2068     try {
2069     FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2070    
2071     pFxSend->SetName(Name);
2072     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2073     } catch (Exception e) {
2074     result.Error(e);
2075     }
2076     return result.Produce();
2077     }
2078    
2079 schoenebeck 1001 String LSCPServer::SetFxSendAudioOutputChannel(uint uiSamplerChannel, uint FxSendID, uint FxSendChannel, uint DeviceChannel) {
2080     dmsg(2,("LSCPServer: SetFxSendAudioOutputChannel()\n"));
2081     LSCPResultSet result;
2082     try {
2083 iliev 1135 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2084 schoenebeck 1001
2085     pFxSend->SetDestinationChannel(FxSendChannel, DeviceChannel);
2086 iliev 1108 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2087 schoenebeck 1001 } catch (Exception e) {
2088     result.Error(e);
2089     }
2090     return result.Produce();
2091     }
2092    
2093 schoenebeck 1026 String LSCPServer::SetFxSendMidiController(uint uiSamplerChannel, uint FxSendID, uint MidiController) {
2094     dmsg(2,("LSCPServer: SetFxSendMidiController()\n"));
2095     LSCPResultSet result;
2096     try {
2097 iliev 1135 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2098 schoenebeck 1026
2099     pFxSend->SetMidiController(MidiController);
2100 iliev 1108 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2101 schoenebeck 1026 } catch (Exception e) {
2102     result.Error(e);
2103     }
2104     return result.Produce();
2105     }
2106    
2107     String LSCPServer::SetFxSendLevel(uint uiSamplerChannel, uint FxSendID, double dLevel) {
2108     dmsg(2,("LSCPServer: SetFxSendLevel()\n"));
2109     LSCPResultSet result;
2110     try {
2111 iliev 1135 FxSend* pFxSend = GetFxSend(uiSamplerChannel, FxSendID);
2112 schoenebeck 1026
2113     pFxSend->SetLevel((float)dLevel);
2114 iliev 1108 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_fx_send_info, uiSamplerChannel, FxSendID));
2115 schoenebeck 1026 } catch (Exception e) {
2116     result.Error(e);
2117     }
2118     return result.Produce();
2119     }
2120    
2121 schoenebeck 973 /**
2122 schoenebeck 35 * Will be called by the parser to reset a particular sampler channel.
2123     */
2124 schoenebeck 53 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
2125     dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
2126 senkov 120 LSCPResultSet result;
2127 schoenebeck 53 try {
2128     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
2129 schoenebeck 880 if (!pSamplerChannel) throw Exception("Invalid sampler channel number " + ToString(uiSamplerChannel));
2130 schoenebeck 411 EngineChannel* pEngineChannel = pSamplerChannel->GetEngineChannel();
2131 schoenebeck 880 if (!pEngineChannel) throw Exception("No engine type assigned to sampler channel");
2132 schoenebeck 670 pEngineChannel->Reset();
2133 schoenebeck 53 }
2134 schoenebeck 880 catch (Exception e) {
2135 senkov 120 result.Error(e);
2136 schoenebeck 53 }
2137 senkov 120 return result.Produce();
2138 schoenebeck 35 }
2139    
2140     /**
2141 schoenebeck 212 * Will be called by the parser to reset the whole sampler.
2142     */
2143     String LSCPServer::ResetSampler() {
2144     dmsg(2,("LSCPServer: ResetSampler()\n"));
2145     pSampler->Reset();
2146     LSCPResultSet result;
2147     return result.Produce();
2148     }
2149    
2150     /**
2151 schoenebeck 563 * Will be called by the parser to return general informations about this
2152     * sampler.
2153     */
2154     String LSCPServer::GetServerInfo() {
2155     dmsg(2,("LSCPServer: GetServerInfo()\n"));
2156     LSCPResultSet result;
2157     result.Add("DESCRIPTION", "LinuxSampler - modular, streaming capable sampler");
2158 schoenebeck 570 result.Add("VERSION", VERSION);
2159 schoenebeck 947 result.Add("PROTOCOL_VERSION", ToString(LSCP_RELEASE_MAJOR) + "." + ToString(LSCP_RELEASE_MINOR));
2160 schoenebeck 563 return result.Produce();
2161     }
2162    
2163     /**
2164 iliev 778 * Will be called by the parser to return the current number of all active voices.
2165     */
2166     String LSCPServer::GetTotalVoiceCount() {
2167     dmsg(2,("LSCPServer: GetTotalVoiceCount()\n"));
2168     LSCPResultSet result;
2169     result.Add(pSampler->GetVoiceCount());
2170     return result.Produce();
2171     }
2172    
2173     /**
2174     * Will be called by the parser to return the maximum number of voices.
2175     */
2176     String LSCPServer::GetTotalVoiceCountMax() {
2177     dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
2178     LSCPResultSet result;
2179     result.Add(EngineFactory::EngineInstances().size() * CONFIG_MAX_VOICES);
2180     return result.Produce();
2181     }
2182    
2183 schoenebeck 1005 String LSCPServer::GetGlobalVolume() {
2184     LSCPResultSet result;
2185     result.Add(ToString(GLOBAL_VOLUME)); // see common/global.cpp
2186     return result.Produce();
2187     }
2188    
2189     String LSCPServer::SetGlobalVolume(double dVolume) {
2190     LSCPResultSet result;
2191     try {
2192     if (dVolume < 0) throw Exception("Volume may not be negative");
2193     GLOBAL_VOLUME = dVolume; // see common/global.cpp
2194 iliev 1108 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_global_info, "VOLUME", GLOBAL_VOLUME));
2195 schoenebeck 1005 } catch (Exception e) {
2196     result.Error(e);
2197     }
2198     return result.Produce();
2199     }
2200    
2201 iliev 778 /**
2202 schoenebeck 35 * Will be called by the parser to subscribe a client (frontend) on the
2203     * server for receiving event messages.
2204     */
2205 senkov 170 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
2206     dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2207     LSCPResultSet result;
2208     SubscriptionMutex.Lock();
2209     eventSubscriptions[type].push_back(currentSocket);
2210     SubscriptionMutex.Unlock();
2211     return result.Produce();
2212 schoenebeck 35 }
2213    
2214     /**
2215     * Will be called by the parser to unsubscribe a client on the server
2216     * for not receiving further event messages.
2217     */
2218 senkov 170 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
2219     dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
2220     LSCPResultSet result;
2221     SubscriptionMutex.Lock();
2222     eventSubscriptions[type].remove(currentSocket);
2223     SubscriptionMutex.Unlock();
2224     return result.Produce();
2225 schoenebeck 35 }
2226 capela 133
2227 senkov 397 static int select_callback(void * lscpResultSet, int argc,
2228     char **argv, char **azColName)
2229     {
2230     LSCPResultSet* resultSet = (LSCPResultSet*) lscpResultSet;
2231     resultSet->Add(argc, argv);
2232     return 0;
2233     }
2234    
2235     String LSCPServer::QueryDatabase(String query) {
2236     LSCPResultSet result;
2237 schoenebeck 401 #if HAVE_SQLITE3
2238 senkov 397 char* zErrMsg = NULL;
2239     sqlite3 *db;
2240     String selectStr = "SELECT " + query;
2241    
2242     int rc = sqlite3_open("linuxsampler.db", &db);
2243     if (rc == SQLITE_OK)
2244     {
2245     rc = sqlite3_exec(db, selectStr.c_str(), select_callback, &result, &zErrMsg);
2246     }
2247     if ( rc != SQLITE_OK )
2248     {
2249 senkov 398 result.Error(String(zErrMsg), rc);
2250 senkov 397 }
2251     sqlite3_close(db);
2252     #else
2253     result.Error(String("SQLITE3 was not installed when linuxsampler was built. SELECT statement is not available."), 0);
2254     #endif
2255     return result.Produce();
2256     }
2257    
2258 schoenebeck 210 /**
2259     * Will be called by the parser to enable or disable echo mode; if echo
2260     * mode is enabled, all commands from the client will (immediately) be
2261     * echoed back to the client.
2262     */
2263     String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
2264     dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
2265     LSCPResultSet result;
2266     try {
2267     if (boolean_value == 0) pSession->bVerbose = false;
2268     else if (boolean_value == 1) pSession->bVerbose = true;
2269 schoenebeck 880 else throw Exception("Not a boolean value, must either be 0 or 1");
2270 schoenebeck 210 }
2271 schoenebeck 880 catch (Exception e) {
2272 schoenebeck 210 result.Error(e);
2273     }
2274     return result.Produce();
2275     }

  ViewVC Help
Powered by ViewVC