/[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 374 - (hide annotations) (download)
Sat Feb 12 00:36:08 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 60997 byte(s)
* JACK audio driver: added device creation parameter 'NAME' which can be
  used to assign an arbitrary name to the JACK client, it's now possible to
  create multiple JACK audio output devices simultaniously for LS
* src/network/lscpserver.cpp: fixed little bug in
  'SET CHANNEL AUDIO_OUTPUT_CHANNEL' (altering of audio routing)
  implementation, cleanup of error messages

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 35 * *
7     * This program is free software; you can redistribute it and/or modify *
8     * it under the terms of the GNU General Public License as published by *
9     * the Free Software Foundation; either version 2 of the License, or *
10     * (at your option) any later version. *
11     * *
12     * This program is distributed in the hope that it will be useful, *
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15     * GNU General Public License for more details. *
16     * *
17     * You should have received a copy of the GNU General Public License *
18     * along with this program; if not, write to the Free Software *
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20     * MA 02111-1307 USA *
21     ***************************************************************************/
22    
23     #include "lscpserver.h"
24 senkov 113 #include "lscpresultset.h"
25 senkov 170 #include "lscpevent.h"
26 schoenebeck 35
27 schoenebeck 53 #include "../engines/gig/Engine.h"
28 schoenebeck 203 #include "../drivers/audio/AudioOutputDeviceFactory.h"
29     #include "../drivers/midi/MidiInputDeviceFactory.h"
30 schoenebeck 53
31 senkov 170 /**
32     * Below are a few static members of the LSCPServer class.
33     * The big assumption here is that LSCPServer is going to remain a singleton.
34     * These members are used to support client connections.
35     * Class handles multiple connections at the same time using select() and non-blocking recv()
36     * Commands are processed by a single LSCPServer thread.
37     * Notifications are delivered either by the thread that originated them
38     * or (if the resultset is currently in progress) by the LSCPServer thread
39     * after the resultset was sent out.
40     * This makes sure that resultsets can not be interrupted by notifications.
41     * This also makes sure that the thread sending notification is not blocked
42     * by the LSCPServer thread.
43     */
44     fd_set LSCPServer::fdSet;
45     int LSCPServer::currentSocket = -1;
46 schoenebeck 210 std::vector<yyparse_param_t> LSCPServer::Sessions = std::vector<yyparse_param_t>();
47 senkov 170 std::map<int,String> LSCPServer::bufferedNotifies = std::map<int,String>();
48     std::map<int,String> LSCPServer::bufferedCommands = std::map<int,String>();
49     std::map< LSCPEvent::event_t, std::list<int> > LSCPServer::eventSubscriptions = std::map< LSCPEvent::event_t, std::list<int> >();
50     Mutex LSCPServer::NotifyMutex = Mutex();
51     Mutex LSCPServer::NotifyBufferMutex = Mutex();
52     Mutex LSCPServer::SubscriptionMutex = Mutex();
53 senkov 360 Mutex LSCPServer::RTNotifyMutex = Mutex();
54 senkov 170
55 schoenebeck 53 LSCPServer::LSCPServer(Sampler* pSampler) : Thread(false, 0, -4) {
56     this->pSampler = pSampler;
57 senkov 170 LSCPEvent::RegisterEvent(LSCPEvent::event_channels, "CHANNELS");
58     LSCPEvent::RegisterEvent(LSCPEvent::event_voice_count, "VOICE_COUNT");
59     LSCPEvent::RegisterEvent(LSCPEvent::event_stream_count, "STREAM_COUNT");
60     LSCPEvent::RegisterEvent(LSCPEvent::event_buffer_fill, "BUFFER_FILL");
61     LSCPEvent::RegisterEvent(LSCPEvent::event_info, "INFO");
62     LSCPEvent::RegisterEvent(LSCPEvent::event_misc, "MISCELLANEOUS");
63 schoenebeck 35 }
64    
65 schoenebeck 211 /**
66     * Blocks the calling thread until the LSCP Server is initialized and
67     * accepting socket connections, if the server is already initialized then
68     * this method will return immediately.
69     * @param TimeoutSeconds - optional: max. wait time in seconds
70     * (default: 0s)
71     * @param TimeoutNanoSeconds - optional: max wait time in nano seconds
72     * (default: 0ns)
73     * @returns 0 on success, a value less than 0 if timeout exceeded
74     */
75     int LSCPServer::WaitUntilInitialized(long TimeoutSeconds, long TimeoutNanoSeconds) {
76     return Initialized.WaitAndUnlockIf(false, TimeoutSeconds, TimeoutNanoSeconds);
77     }
78    
79 schoenebeck 35 int LSCPServer::Main() {
80 senkov 170 int hSocket = socket(AF_INET, SOCK_STREAM, 0);
81 schoenebeck 35 if (hSocket < 0) {
82     std::cerr << "LSCPServer: Could not create server socket." << std::endl;
83 schoenebeck 53 //return -1;
84     exit(EXIT_FAILURE);
85 schoenebeck 35 }
86    
87     SocketAddress.sin_family = AF_INET;
88     SocketAddress.sin_port = htons(LSCP_PORT);
89     SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
90    
91     if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
92 schoenebeck 227 std::cerr << "LSCPServer: Could not bind server socket, retrying for " << ToString(LSCP_SERVER_BIND_TIMEOUT) << " seconds...";
93     for (int trial = 0; true; trial++) { // retry for LSCP_SERVER_BIND_TIMEOUT seconds
94     if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
95     if (trial > LSCP_SERVER_BIND_TIMEOUT) {
96     std::cerr << "gave up!" << std::endl;
97     close(hSocket);
98     //return -1;
99     exit(EXIT_FAILURE);
100     }
101     else sleep(1); // sleep 1s
102     }
103     else break; // success
104     }
105 schoenebeck 35 }
106    
107     listen(hSocket, 1);
108 schoenebeck 211 Initialized.Set(true);
109 schoenebeck 35
110     // now wait for client connections and handle their requests
111     sockaddr_in client;
112     int length = sizeof(client);
113 senkov 170 FD_ZERO(&fdSet);
114     FD_SET(hSocket, &fdSet);
115     int maxSessions = hSocket;
116 schoenebeck 203
117 schoenebeck 35 while (true) {
118 senkov 170 fd_set selectSet = fdSet;
119 senkov 198 int retval = select(maxSessions+1, &selectSet, NULL, NULL, NULL);
120 senkov 170 if (retval == 0)
121 senkov 198 continue; //Nothing try again
122 senkov 170 if (retval == -1) {
123     std::cerr << "LSCPServer: Socket select error." << std::endl;
124     close(hSocket);
125     exit(EXIT_FAILURE);
126     }
127 schoenebeck 203
128 senkov 170 //Accept new connections now (if any)
129     if (FD_ISSET(hSocket, &selectSet)) {
130     int socket = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
131     if (socket < 0) {
132     std::cerr << "LSCPServer: Client connection failed." << std::endl;
133     exit(EXIT_FAILURE);
134     }
135 schoenebeck 35
136 senkov 170 if (fcntl(socket, F_SETFL, O_NONBLOCK)) {
137     std::cerr << "LSCPServer: F_SETFL O_NONBLOCK failed." << std::endl;
138     exit(EXIT_FAILURE);
139     }
140 schoenebeck 35
141 schoenebeck 210 // Parser initialization
142     yyparse_param_t yyparse_param;
143     yyparse_param.pServer = this;
144     yyparse_param.hSession = socket;
145    
146     Sessions.push_back(yyparse_param);
147 senkov 170 FD_SET(socket, &fdSet);
148     if (socket > maxSessions)
149     maxSessions = socket;
150     dmsg(1,("LSCPServer: Client connection established on socket:%d.\n", socket));
151     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection established on socket", socket));
152     continue; //Maybe this was the only selected socket, better select again
153     }
154 schoenebeck 35
155 senkov 170 //Something was selected and it was not the hSocket, so it must be some command(s) coming.
156 schoenebeck 210 for (std::vector<yyparse_param_t>::iterator iter = Sessions.begin(); iter != Sessions.end(); iter++) {
157     if (FD_ISSET((*iter).hSession, &selectSet)) { //Was it this socket?
158 senkov 170 if (GetLSCPCommand(iter)) { //Have we read the entire command?
159     dmsg(3,("LSCPServer: Got command on socket %d, calling parser.\n", currentSocket));
160 schoenebeck 219 int dummy; // just a temporary hack to fulfill the restart() function prototype
161     restart(NULL, dummy); // restart the 'scanner'
162 schoenebeck 210 currentSocket = (*iter).hSession; //a hack
163     if ((*iter).bVerbose) { // if echo mode enabled
164     AnswerClient(bufferedCommands[currentSocket]);
165     }
166     int result = yyparse(&(*iter));
167 senkov 170 currentSocket = -1; //continuation of a hack
168     dmsg(3,("LSCPServer: Done parsing on socket %d.\n", currentSocket));
169     if (result == LSCP_QUIT) { //Was it a quit command by any chance?
170     CloseConnection(iter);
171     }
172     }
173     //socket may have been closed, iter may be invalid, get out of the loop for now.
174     //we'll be back if there is data.
175 schoenebeck 203 break;
176 senkov 170 }
177     }
178    
179     //Now let's deliver late notifies (if any)
180     NotifyBufferMutex.Lock();
181     for (std::map<int,String>::iterator iterNotify = bufferedNotifies.begin(); iterNotify != bufferedNotifies.end(); iterNotify++) {
182     send(iterNotify->first, iterNotify->second.c_str(), iterNotify->second.size(), 0);
183     bufferedNotifies.erase(iterNotify);
184     }
185     NotifyBufferMutex.Unlock();
186 schoenebeck 35 }
187     }
188    
189 schoenebeck 210 void LSCPServer::CloseConnection( std::vector<yyparse_param_t>::iterator iter ) {
190     int socket = (*iter).hSession;
191 senkov 170 dmsg(1,("LSCPServer: Client connection terminated on socket:%d.\n",socket));
192     LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Client connection terminated on socket", socket));
193 schoenebeck 210 Sessions.erase(iter);
194 senkov 170 FD_CLR(socket, &fdSet);
195     SubscriptionMutex.Lock(); //Must unsubscribe this socket from all events (if any)
196     for (std::map< LSCPEvent::event_t, std::list<int> >::iterator iter = eventSubscriptions.begin(); iter != eventSubscriptions.end(); iter++) {
197     iter->second.remove(socket);
198     }
199     SubscriptionMutex.Unlock();
200     NotifyMutex.Lock();
201     bufferedCommands.erase(socket);
202     bufferedNotifies.erase(socket);
203     close(socket);
204     NotifyMutex.Unlock();
205     }
206    
207 senkov 360 int LSCPServer::EventSubscribers( std::list<LSCPEvent::event_t> events ) {
208     int subs = 0;
209     SubscriptionMutex.Lock();
210     for( std::list<LSCPEvent::event_t>::iterator iter = events.begin();
211     iter != events.end(); iter++)
212     {
213     subs += eventSubscriptions.count(*iter);
214     }
215     SubscriptionMutex.Unlock();
216     return subs;
217     }
218    
219 senkov 170 void LSCPServer::SendLSCPNotify( LSCPEvent event ) {
220     SubscriptionMutex.Lock();
221     if (eventSubscriptions.count(event.GetType()) == 0) {
222     SubscriptionMutex.Unlock(); //Nobody is subscribed to this event
223     return;
224     }
225     std::list<int>::iterator iter = eventSubscriptions[event.GetType()].begin();
226     std::list<int>::iterator end = eventSubscriptions[event.GetType()].end();
227     String notify = event.Produce();
228    
229     while (true) {
230     if (NotifyMutex.Trylock()) {
231     for(;iter != end; iter++)
232     send(*iter, notify.c_str(), notify.size(), 0);
233     NotifyMutex.Unlock();
234     break;
235     } else {
236     if (NotifyBufferMutex.Trylock()) {
237     for(;iter != end; iter++)
238     bufferedNotifies[*iter] += notify;
239     NotifyBufferMutex.Unlock();
240     break;
241     }
242     }
243     }
244     SubscriptionMutex.Unlock();
245     }
246    
247     extern int GetLSCPCommand( void *buf, int max_size ) {
248     String command = LSCPServer::bufferedCommands[LSCPServer::currentSocket];
249     if (command.size() == 0) { //Parser wants input but we have nothing.
250     strcpy((char*) buf, "\n"); //So give it an empty command
251     return 1; //to keep it happy.
252     }
253    
254     if (max_size < command.size()) {
255     std::cerr << "getLSCPCommand: Flex buffer too small, ignoring the command." << std::endl;
256     return 0; //This will never happen
257     }
258    
259     strcpy((char*) buf, command.c_str());
260     LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);
261     return command.size();
262     }
263    
264 schoenebeck 35 /**
265 senkov 170 * Will be called to try to read the command from the socket
266     * If command is read, it will return true. Otherwise false is returned.
267     * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.
268     */
269 schoenebeck 210 bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
270     int socket = (*iter).hSession;
271 senkov 170 char c;
272     int i = 0;
273     while (true) {
274     int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now
275     if (result == 0) { //socket was selected, so 0 here means client has closed the connection
276     CloseConnection(iter);
277     break;
278     }
279     if (result == 1) {
280 schoenebeck 203 if (c == '\r')
281 senkov 170 continue; //Ignore CR
282     if (c == '\n') {
283 senkov 184 LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
284 senkov 170 bufferedCommands[socket] += "\n";
285     return true; //Complete command was read
286     }
287     bufferedCommands[socket] += c;
288     }
289     if (result == -1) {
290     if (errno == EAGAIN) //Would block, try again later.
291     return false;
292     switch(errno) {
293     case EBADF:
294     dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
295     break;
296     case ECONNREFUSED:
297     dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
298     break;
299     case ENOTCONN:
300     dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
301     break;
302     case ENOTSOCK:
303     dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
304     break;
305     case EAGAIN:
306     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"));
307 schoenebeck 203 break;
308     case EINTR:
309 senkov 170 dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
310 schoenebeck 203 break;
311     case EFAULT:
312     dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
313     break;
314     case EINVAL:
315     dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
316     break;
317     case ENOMEM:
318     dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
319     break;
320     default:
321     dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
322     break;
323     }
324 senkov 170 CloseConnection(iter);
325     break;
326     }
327     }
328     return false;
329     }
330    
331     /**
332 schoenebeck 35 * Will be called by the parser whenever it wants to send an answer to the
333     * client / frontend.
334     *
335     * @param ReturnMessage - message that will be send to the client
336     */
337     void LSCPServer::AnswerClient(String ReturnMessage) {
338     dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
339 senkov 170 if (currentSocket != -1) {
340     NotifyMutex.Lock();
341     send(currentSocket, ReturnMessage.c_str(), ReturnMessage.size(), 0);
342     NotifyMutex.Unlock();
343     }
344 schoenebeck 35 }
345    
346 capela 143 /**
347     * Find a created audio output device index.
348     */
349     int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
350     {
351     // Search for the created device to get its index
352     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
353     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
354     for (; iter != devices.end(); iter++) {
355     if (iter->second == pDevice)
356     return iter->first;
357     }
358     // Not found.
359     return -1;
360     }
361    
362 senkov 155 /**
363     * Find a created midi input device index.
364     */
365     int LSCPServer::GetMidiInputDeviceIndex ( MidiInputDevice *pDevice )
366     {
367     // Search for the created device to get its index
368     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
369     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
370     for (; iter != devices.end(); iter++) {
371     if (iter->second == pDevice)
372     return iter->first;
373     }
374     // Not found.
375     return -1;
376     }
377    
378 schoenebeck 123 String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
379     dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
380     LSCPResultSet result;
381     try {
382     AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
383     // search for the created device to get its index
384 capela 143 int index = GetAudioOutputDeviceIndex(pDevice);
385 schoenebeck 123 if (index == -1) throw LinuxSamplerException("Internal error: could not find created audio output device.");
386     result = index; // success
387     }
388     catch (LinuxSamplerException e) {
389     result.Error(e);
390     }
391     return result.Produce();
392     }
393    
394 senkov 155 String LSCPServer::CreateMidiInputDevice(String Driver, std::map<String,String> Parameters) {
395     dmsg(2,("LSCPServer: CreateMidiInputDevice(Driver=%s)\n", Driver.c_str()));
396     LSCPResultSet result;
397     try {
398     MidiInputDevice* pDevice = pSampler->CreateMidiInputDevice(Driver, Parameters);
399     // search for the created device to get its index
400     int index = GetMidiInputDeviceIndex(pDevice);
401     if (index == -1) throw LinuxSamplerException("Internal error: could not find created midi input device.");
402     result = index; // success
403     }
404     catch (LinuxSamplerException e) {
405     result.Error(e);
406     }
407     return result.Produce();
408     }
409    
410 schoenebeck 123 String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
411     dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
412     LSCPResultSet result;
413     try {
414     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
415 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
416 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
417     pSampler->DestroyAudioOutputDevice(pDevice);
418     }
419     catch (LinuxSamplerException e) {
420     result.Error(e);
421     }
422     return result.Produce();
423     }
424    
425 senkov 155 String LSCPServer::DestroyMidiInputDevice(uint DeviceIndex) {
426     dmsg(2,("LSCPServer: DestroyMidiInputDevice(DeviceIndex=%d)\n", DeviceIndex));
427     LSCPResultSet result;
428     try {
429     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
430 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
431 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
432     pSampler->DestroyMidiInputDevice(pDevice);
433     }
434     catch (LinuxSamplerException e) {
435     result.Error(e);
436     }
437     return result.Produce();
438     }
439    
440 schoenebeck 35 /**
441     * Will be called by the parser to load an instrument.
442     */
443 capela 137 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
444 schoenebeck 53 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
445 senkov 120 LSCPResultSet result;
446 schoenebeck 53 try {
447     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
448 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
449 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
450 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
451 schoenebeck 223 if (!pSamplerChannel->GetAudioOutputDevice())
452 schoenebeck 374 throw LinuxSamplerException("No audio output device connected to sampler channel");
453 capela 137 if (bBackground) {
454     LSCPLoadInstrument *pLoadInstrument = new LSCPLoadInstrument(pEngine, Filename.c_str(), uiInstrument);
455     pLoadInstrument->StartThread();
456     }
457     else pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
458 schoenebeck 53 }
459     catch (LinuxSamplerException e) {
460 senkov 120 result.Error(e);
461 schoenebeck 53 }
462 senkov 120 return result.Produce();
463 schoenebeck 35 }
464    
465     /**
466     * Will be called by the parser to load and deploy an engine.
467     */
468 schoenebeck 53 String LSCPServer::LoadEngine(String EngineName, uint uiSamplerChannel) {
469     dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
470 senkov 120 LSCPResultSet result;
471 schoenebeck 53 try {
472 schoenebeck 64 Engine::type_t type;
473 senkov 120 if ((EngineName == "GigEngine") || (EngineName == "gig")) type = Engine::type_gig;
474 schoenebeck 53 else throw LinuxSamplerException("Unknown engine type");
475     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
476 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
477 senkov 360 LockRTNotify();
478 schoenebeck 53 pSamplerChannel->LoadEngine(type);
479 senkov 360 UnlockRTNotify();
480 schoenebeck 53 }
481     catch (LinuxSamplerException e) {
482 senkov 120 result.Error(e);
483 schoenebeck 53 }
484 senkov 120 return result.Produce();
485 schoenebeck 35 }
486    
487     /**
488     * Will be called by the parser to get the amount of sampler channels.
489     */
490     String LSCPServer::GetChannels() {
491     dmsg(2,("LSCPServer: GetChannels()\n"));
492 senkov 120 LSCPResultSet result;
493     result.Add(pSampler->SamplerChannels());
494     return result.Produce();
495 schoenebeck 35 }
496    
497     /**
498 schoenebeck 209 * Will be called by the parser to get the list of sampler channels.
499     */
500     String LSCPServer::ListChannels() {
501     dmsg(2,("LSCPServer: ListChannels()\n"));
502     String list;
503     std::map<uint,SamplerChannel*> channels = pSampler->GetSamplerChannels();
504     std::map<uint,SamplerChannel*>::iterator iter = channels.begin();
505     for (; iter != channels.end(); iter++) {
506     if (list != "") list += ",";
507     list += ToString(iter->first);
508     }
509     LSCPResultSet result;
510     result.Add(list);
511     return result.Produce();
512     }
513    
514     /**
515 schoenebeck 35 * Will be called by the parser to add a sampler channel.
516     */
517     String LSCPServer::AddChannel() {
518     dmsg(2,("LSCPServer: AddChannel()\n"));
519 schoenebeck 53 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
520 senkov 120 LSCPResultSet result(pSamplerChannel->Index());
521     return result.Produce();
522 schoenebeck 35 }
523    
524     /**
525     * Will be called by the parser to remove a sampler channel.
526     */
527 schoenebeck 53 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
528     dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
529 senkov 120 LSCPResultSet result;
530 senkov 360 LockRTNotify();
531 schoenebeck 53 pSampler->RemoveSamplerChannel(uiSamplerChannel);
532 senkov 360 UnlockRTNotify();
533 senkov 120 return result.Produce();
534 schoenebeck 35 }
535    
536     /**
537     * Will be called by the parser to get all available engines.
538     */
539     String LSCPServer::GetAvailableEngines() {
540     dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
541 senkov 120 LSCPResultSet result("GigEngine");
542     return result.Produce();
543 schoenebeck 35 }
544    
545     /**
546     * Will be called by the parser to get descriptions for a particular engine.
547     */
548     String LSCPServer::GetEngineInfo(String EngineName) {
549     dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
550 senkov 120 LSCPResultSet result;
551 schoenebeck 53 try {
552 senkov 120 if ((EngineName == "GigEngine") || (EngineName == "gig")) {
553 schoenebeck 53 Engine* pEngine = new LinuxSampler::gig::Engine;
554 schoenebeck 225 result.Add("DESCRIPTION", pEngine->Description());
555     result.Add("VERSION", pEngine->Version());
556 schoenebeck 53 delete pEngine;
557     }
558     else throw LinuxSamplerException("Unknown engine type");
559     }
560     catch (LinuxSamplerException e) {
561 senkov 120 result.Error(e);
562 schoenebeck 53 }
563 senkov 120 return result.Produce();
564 schoenebeck 35 }
565    
566     /**
567     * Will be called by the parser to get informations about a particular
568     * sampler channel.
569     */
570 schoenebeck 53 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
571     dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
572 senkov 120 LSCPResultSet result;
573 senkov 113 try {
574     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
575 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
576 senkov 113 Engine* pEngine = pSamplerChannel->GetEngine();
577 schoenebeck 123
578 senkov 117 //Defaults values
579     String EngineName = "NONE";
580 schoenebeck 225 float Volume = 0.0f;
581 senkov 117 String InstrumentFileName = "NONE";
582 capela 133 int InstrumentIndex = -1;
583     int InstrumentStatus = -1;
584 schoenebeck 225 int AudioOutputChannels = 0;
585     String AudioRouting;
586 schoenebeck 123
587 senkov 113 if (pEngine) {
588 senkov 117 EngineName = pEngine->EngineName();
589 schoenebeck 225 AudioOutputChannels = pEngine->Channels();
590 senkov 117 Volume = pEngine->Volume();
591 capela 133 InstrumentStatus = pEngine->InstrumentStatus();
592     InstrumentIndex = pEngine->InstrumentIndex();
593     if (InstrumentIndex != -1)
594 senkov 117 InstrumentFileName = pEngine->InstrumentFileName();
595 schoenebeck 225 for (int chan = 0; chan < pEngine->Channels(); chan++) {
596     if (AudioRouting != "") AudioRouting += ",";
597     AudioRouting += ToString(pEngine->OutputChannel(chan));
598     }
599 senkov 113 }
600 senkov 117
601     result.Add("ENGINE_NAME", EngineName);
602     result.Add("VOLUME", Volume);
603    
604 capela 143 //Some not-so-hardcoded stuff to make GUI look good
605     result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
606 schoenebeck 225 result.Add("AUDIO_OUTPUT_CHANNELS", AudioOutputChannels);
607     result.Add("AUDIO_OUTPUT_ROUTING", AudioRouting);
608 senkov 113
609 capela 159 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
610     result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
611 schoenebeck 274 if (pSamplerChannel->GetMidiInputChannel() == MidiInputPort::midi_chan_all) result.Add("MIDI_INPUT_CHANNEL", "ALL");
612     else result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
613 capela 159
614 senkov 117 result.Add("INSTRUMENT_FILE", InstrumentFileName);
615     result.Add("INSTRUMENT_NR", InstrumentIndex);
616 capela 133 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
617 senkov 113 }
618     catch (LinuxSamplerException e) {
619 senkov 120 result.Error(e);
620 senkov 113 }
621 senkov 120 return result.Produce();
622 schoenebeck 35 }
623    
624     /**
625     * Will be called by the parser to get the amount of active voices on a
626     * particular sampler channel.
627     */
628 schoenebeck 53 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
629     dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
630 senkov 120 LSCPResultSet result;
631 schoenebeck 53 try {
632     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
633 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
634 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
635 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
636 senkov 120 result.Add(pEngine->VoiceCount());
637 schoenebeck 53 }
638     catch (LinuxSamplerException e) {
639 senkov 120 result.Error(e);
640 schoenebeck 53 }
641 senkov 120 return result.Produce();
642 schoenebeck 35 }
643    
644     /**
645     * Will be called by the parser to get the amount of active disk streams on a
646     * particular sampler channel.
647     */
648 schoenebeck 53 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
649     dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
650 senkov 120 LSCPResultSet result;
651 schoenebeck 53 try {
652     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
653 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
654 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
655 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
656 senkov 120 result.Add(pEngine->DiskStreamCount());
657 schoenebeck 53 }
658     catch (LinuxSamplerException e) {
659 senkov 120 result.Error(e);
660 schoenebeck 53 }
661 senkov 120 return result.Produce();
662 schoenebeck 35 }
663    
664     /**
665     * Will be called by the parser to get the buffer fill states of all disk
666     * streams on a particular sampler channel.
667     */
668 schoenebeck 53 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
669     dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
670 senkov 120 LSCPResultSet result;
671 schoenebeck 53 try {
672     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
673 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
674 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
675 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
676 senkov 129 if (!pEngine->DiskStreamSupported())
677     result.Add("NA");
678     else {
679     switch (ResponseType) {
680     case fill_response_bytes:
681     result.Add(pEngine->DiskStreamBufferFillBytes());
682     break;
683     case fill_response_percentage:
684     result.Add(pEngine->DiskStreamBufferFillPercentage());
685     break;
686     default:
687     throw LinuxSamplerException("Unknown fill response type");
688     }
689     }
690 schoenebeck 53 }
691     catch (LinuxSamplerException e) {
692 senkov 120 result.Error(e);
693 schoenebeck 53 }
694 senkov 120 return result.Produce();
695 schoenebeck 35 }
696    
697 schoenebeck 123 String LSCPServer::GetAvailableAudioOutputDrivers() {
698     dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
699 senkov 120 LSCPResultSet result;
700 schoenebeck 53 try {
701 schoenebeck 123 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
702     result.Add(s);
703 schoenebeck 53 }
704     catch (LinuxSamplerException e) {
705 schoenebeck 123 result.Error(e);
706 schoenebeck 53 }
707 senkov 120 return result.Produce();
708 schoenebeck 35 }
709    
710 senkov 155 String LSCPServer::GetAvailableMidiInputDrivers() {
711     dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
712     LSCPResultSet result;
713     try {
714     String s = MidiInputDeviceFactory::AvailableDriversAsString();
715     result.Add(s);
716     }
717     catch (LinuxSamplerException e) {
718     result.Error(e);
719     }
720     return result.Produce();
721     }
722    
723     String LSCPServer::GetMidiInputDriverInfo(String Driver) {
724     dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
725     LSCPResultSet result;
726     try {
727     result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
728     result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
729    
730     std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
731     if (parameters.size()) { // if there are parameters defined for this driver
732     String s;
733     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
734     for (;iter != parameters.end(); iter++) {
735     if (s != "") s += ",";
736     s += iter->first;
737     }
738     result.Add("PARAMETERS", s);
739     }
740     }
741     catch (LinuxSamplerException e) {
742     result.Error(e);
743     }
744     return result.Produce();
745     }
746    
747 schoenebeck 123 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
748     dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
749     LSCPResultSet result;
750     try {
751     result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
752     result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
753    
754     std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
755     if (parameters.size()) { // if there are parameters defined for this driver
756     String s;
757     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
758     for (;iter != parameters.end(); iter++) {
759     if (s != "") s += ",";
760     s += iter->first;
761     }
762     result.Add("PARAMETERS", s);
763     }
764     }
765     catch (LinuxSamplerException e) {
766     result.Error(e);
767     }
768     return result.Produce();
769     }
770    
771 senkov 155 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
772 schoenebeck 226 dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
773 senkov 155 LSCPResultSet result;
774     try {
775     DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
776     result.Add("TYPE", pParameter->Type());
777     result.Add("DESCRIPTION", pParameter->Description());
778 schoenebeck 223 result.Add("MANDATORY", pParameter->Mandatory());
779     result.Add("FIX", pParameter->Fix());
780     result.Add("MULTIPLICITY", pParameter->Multiplicity());
781 schoenebeck 226 optional<String> oDepends = pParameter->Depends();
782     optional<String> oDefault = pParameter->Default(DependencyList);
783     optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
784     optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
785     optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
786     if (oDepends) result.Add("DEPENDS", *oDepends);
787     if (oDefault) result.Add("DEFAULT", *oDefault);
788     if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
789     if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
790     if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
791 senkov 155 }
792     catch (LinuxSamplerException e) {
793     result.Error(e);
794     }
795     return result.Produce();
796     }
797    
798 schoenebeck 123 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
799 schoenebeck 226 dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));
800 schoenebeck 123 LSCPResultSet result;
801     try {
802     DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
803     result.Add("TYPE", pParameter->Type());
804     result.Add("DESCRIPTION", pParameter->Description());
805 schoenebeck 223 result.Add("MANDATORY", pParameter->Mandatory());
806     result.Add("FIX", pParameter->Fix());
807     result.Add("MULTIPLICITY", pParameter->Multiplicity());
808 schoenebeck 226 optional<String> oDepends = pParameter->Depends();
809     optional<String> oDefault = pParameter->Default(DependencyList);
810     optional<String> oRangeMin = pParameter->RangeMin(DependencyList);
811     optional<String> oRangeMax = pParameter->RangeMax(DependencyList);
812     optional<String> oPossibilities = pParameter->Possibilities(DependencyList);
813     if (oDepends) result.Add("DEPENDS", *oDepends);
814     if (oDefault) result.Add("DEFAULT", *oDefault);
815     if (oRangeMin) result.Add("RANGE_MIN", *oRangeMin);
816     if (oRangeMax) result.Add("RANGE_MAX", *oRangeMax);
817     if (oPossibilities) result.Add("POSSIBILITIES", *oPossibilities);
818 schoenebeck 123 }
819     catch (LinuxSamplerException e) {
820     result.Error(e);
821     }
822     return result.Produce();
823     }
824    
825     String LSCPServer::GetAudioOutputDeviceCount() {
826     dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
827     LSCPResultSet result;
828     try {
829     uint count = pSampler->AudioOutputDevices();
830 senkov 138 result.Add(count); // success
831 schoenebeck 123 }
832     catch (LinuxSamplerException e) {
833     result.Error(e);
834     }
835     return result.Produce();
836     }
837    
838 senkov 155 String LSCPServer::GetMidiInputDeviceCount() {
839     dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
840     LSCPResultSet result;
841     try {
842     uint count = pSampler->MidiInputDevices();
843     result.Add(count); // success
844     }
845     catch (LinuxSamplerException e) {
846     result.Error(e);
847     }
848     return result.Produce();
849     }
850    
851 schoenebeck 123 String LSCPServer::GetAudioOutputDevices() {
852     dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
853     LSCPResultSet result;
854     try {
855     String s;
856     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
857     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
858     for (; iter != devices.end(); iter++) {
859     if (s != "") s += ",";
860     s += ToString(iter->first);
861     }
862     result.Add(s);
863     }
864     catch (LinuxSamplerException e) {
865     result.Error(e);
866     }
867     return result.Produce();
868     }
869    
870 senkov 155 String LSCPServer::GetMidiInputDevices() {
871     dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
872     LSCPResultSet result;
873     try {
874     String s;
875     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
876     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
877     for (; iter != devices.end(); iter++) {
878     if (s != "") s += ",";
879     s += ToString(iter->first);
880     }
881     result.Add(s);
882     }
883     catch (LinuxSamplerException e) {
884     result.Error(e);
885     }
886     return result.Produce();
887     }
888    
889 schoenebeck 123 String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
890     dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
891     LSCPResultSet result;
892     try {
893     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
894 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
895 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
896 schoenebeck 221 result.Add("DRIVER", pDevice->Driver());
897 schoenebeck 123 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
898     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
899     for (; iter != parameters.end(); iter++) {
900     result.Add(iter->first, iter->second->Value());
901     }
902     }
903     catch (LinuxSamplerException e) {
904     result.Error(e);
905     }
906     return result.Produce();
907     }
908    
909 senkov 155 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
910     dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
911     LSCPResultSet result;
912     try {
913     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
914 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
915 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
916 schoenebeck 221 result.Add("DRIVER", pDevice->Driver());
917 senkov 155 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
918     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
919     for (; iter != parameters.end(); iter++) {
920     result.Add(iter->first, iter->second->Value());
921     }
922     }
923     catch (LinuxSamplerException e) {
924     result.Error(e);
925     }
926     return result.Produce();
927     }
928     String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
929     dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
930     LSCPResultSet result;
931     try {
932 schoenebeck 223 // get MIDI input device
933 senkov 155 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
934 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
935 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
936 schoenebeck 223
937     // get MIDI port
938 schoenebeck 221 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
939     if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
940 schoenebeck 223
941     // return the values of all MIDI port parameters
942 schoenebeck 221 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
943     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
944 senkov 155 for (; iter != parameters.end(); iter++) {
945     result.Add(iter->first, iter->second->Value());
946     }
947     }
948     catch (LinuxSamplerException e) {
949     result.Error(e);
950     }
951     return result.Produce();
952     }
953    
954 schoenebeck 123 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
955     dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
956     LSCPResultSet result;
957     try {
958     // get audio output device
959     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
960 schoenebeck 223 if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
961 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
962    
963     // get audio channel
964     AudioChannel* pChannel = pDevice->Channel(ChannelId);
965 schoenebeck 374 if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
966 schoenebeck 123
967     // return the values of all audio channel parameters
968     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
969     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
970     for (; iter != parameters.end(); iter++) {
971     result.Add(iter->first, iter->second->Value());
972     }
973     }
974     catch (LinuxSamplerException e) {
975     result.Error(e);
976     }
977     return result.Produce();
978     }
979    
980 senkov 185 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
981     dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
982     LSCPResultSet result;
983     try {
984 schoenebeck 223 // get MIDI input device
985     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
986     if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no midi input device with index " + ToString(DeviceId) + ".");
987     MidiInputDevice* pDevice = devices[DeviceId];
988 senkov 185
989 schoenebeck 221 // get midi port
990     MidiInputPort* pPort = pDevice->GetPort(PortId);
991     if (!pPort) throw LinuxSamplerException("Midi input device does not have port " + ToString(PortId) + ".");
992 senkov 185
993 schoenebeck 223 // get desired port parameter
994     std::map<String,DeviceRuntimeParameter*> parameters = pPort->PortParameters();
995     if (!parameters.count(ParameterName)) throw LinuxSamplerException("Midi port does not provide a parameter '" + ParameterName + "'.");
996     DeviceRuntimeParameter* pParameter = parameters[ParameterName];
997 schoenebeck 203
998 senkov 185 // return all fields of this audio channel parameter
999     result.Add("TYPE", pParameter->Type());
1000     result.Add("DESCRIPTION", pParameter->Description());
1001     result.Add("FIX", pParameter->Fix());
1002     result.Add("MULTIPLICITY", pParameter->Multiplicity());
1003 schoenebeck 223 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1004     if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1005     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1006 senkov 185 }
1007     catch (LinuxSamplerException e) {
1008     result.Error(e);
1009     }
1010     return result.Produce();
1011     }
1012    
1013 schoenebeck 123 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
1014     dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
1015     LSCPResultSet result;
1016     try {
1017     // get audio output device
1018     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1019 schoenebeck 223 if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
1020 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
1021    
1022     // get audio channel
1023     AudioChannel* pChannel = pDevice->Channel(ChannelId);
1024 schoenebeck 374 if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1025 schoenebeck 123
1026     // get desired audio channel parameter
1027     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1028 schoenebeck 223 if (!parameters.count(ParameterName)) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParameterName + "'.");
1029 schoenebeck 123 DeviceRuntimeParameter* pParameter = parameters[ParameterName];
1030    
1031     // return all fields of this audio channel parameter
1032     result.Add("TYPE", pParameter->Type());
1033     result.Add("DESCRIPTION", pParameter->Description());
1034     result.Add("FIX", pParameter->Fix());
1035     result.Add("MULTIPLICITY", pParameter->Multiplicity());
1036 schoenebeck 223 if (pParameter->RangeMin()) result.Add("RANGE_MIN", *pParameter->RangeMin());
1037     if (pParameter->RangeMax()) result.Add("RANGE_MAX", *pParameter->RangeMax());
1038     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", *pParameter->Possibilities());
1039 schoenebeck 123 }
1040     catch (LinuxSamplerException e) {
1041     result.Error(e);
1042     }
1043     return result.Produce();
1044     }
1045    
1046     String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
1047     dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
1048     LSCPResultSet result;
1049     try {
1050     // get audio output device
1051     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1052 schoenebeck 223 if (!devices.count(DeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
1053 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceId];
1054    
1055     // get audio channel
1056     AudioChannel* pChannel = pDevice->Channel(ChannelId);
1057 schoenebeck 374 if (!pChannel) throw LinuxSamplerException("Audio output device does not have audio channel " + ToString(ChannelId) + ".");
1058 schoenebeck 123
1059     // get desired audio channel parameter
1060     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
1061 schoenebeck 223 if (!parameters.count(ParamKey)) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParamKey + "'.");
1062 schoenebeck 123 DeviceRuntimeParameter* pParameter = parameters[ParamKey];
1063    
1064     // set new channel parameter value
1065     pParameter->SetValue(ParamVal);
1066     }
1067     catch (LinuxSamplerException e) {
1068     result.Error(e);
1069     }
1070     return result.Produce();
1071     }
1072    
1073     String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1074     dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1075     LSCPResultSet result;
1076     try {
1077     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1078 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
1079 schoenebeck 123 AudioOutputDevice* pDevice = devices[DeviceIndex];
1080     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1081 schoenebeck 223 if (!parameters.count(ParamKey)) throw LinuxSamplerException("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1082 schoenebeck 123 parameters[ParamKey]->SetValue(ParamVal);
1083     }
1084     catch (LinuxSamplerException e) {
1085     result.Error(e);
1086     }
1087     return result.Produce();
1088     }
1089    
1090 senkov 155 String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1091     dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1092     LSCPResultSet result;
1093     try {
1094     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1095 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1096 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1097     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1098 schoenebeck 223 if (!parameters.count(ParamKey)) throw LinuxSamplerException("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1099 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1100     }
1101     catch (LinuxSamplerException e) {
1102     result.Error(e);
1103     }
1104     return result.Produce();
1105     }
1106    
1107     String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, String ParamKey, String ParamVal) {
1108     dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1109     LSCPResultSet result;
1110     try {
1111 schoenebeck 223 // get MIDI input device
1112 senkov 155 std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1113 schoenebeck 223 if (!devices.count(DeviceIndex)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1114 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1115 schoenebeck 223
1116     // get MIDI port
1117 schoenebeck 221 MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1118     if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1119 schoenebeck 223
1120     // set port parameter value
1121 schoenebeck 221 std::map<String,DeviceRuntimeParameter*> parameters = pMidiInputPort->PortParameters();
1122 schoenebeck 223 if (!parameters.count(ParamKey)) throw LinuxSamplerException("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1123 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1124     }
1125     catch (LinuxSamplerException e) {
1126     result.Error(e);
1127     }
1128     return result.Produce();
1129     }
1130    
1131 schoenebeck 35 /**
1132     * Will be called by the parser to change the audio output channel for
1133     * playback on a particular sampler channel.
1134     */
1135 schoenebeck 123 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1136     dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1137 schoenebeck 225 LSCPResultSet result;
1138     try {
1139     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1140 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1141 schoenebeck 225 Engine* pEngine = pSamplerChannel->GetEngine();
1142     if (!pEngine) throw LinuxSamplerException("No engine deployed on sampler channel " + ToString(uiSamplerChannel));
1143 schoenebeck 374 if (!pSamplerChannel->GetAudioOutputDevice()) throw LinuxSamplerException("No audio output device connected to sampler channel " + ToString(uiSamplerChannel));
1144 schoenebeck 225 pEngine->SetOutputChannel(ChannelAudioOutputChannel, AudioOutputDeviceInputChannel);
1145     }
1146     catch (LinuxSamplerException e) {
1147     result.Error(e);
1148     }
1149     return result.Produce();
1150 schoenebeck 35 }
1151    
1152 capela 159 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1153     dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1154     LSCPResultSet result;
1155     try {
1156     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1157 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1158 capela 159 std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1159 schoenebeck 223 if (!devices.count(AudioDeviceId)) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));
1160 capela 159 AudioOutputDevice* pDevice = devices[AudioDeviceId];
1161     pSamplerChannel->SetAudioOutputDevice(pDevice);
1162     }
1163     catch (LinuxSamplerException e) {
1164     result.Error(e);
1165     }
1166     return result.Produce();
1167     }
1168    
1169 capela 143 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1170     dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1171     LSCPResultSet result;
1172     try {
1173     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1174 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1175 capela 143 // Driver type name aliasing...
1176 schoenebeck 226 if (AudioOutputDriver == "Alsa") AudioOutputDriver = "ALSA";
1177     if (AudioOutputDriver == "Jack") AudioOutputDriver = "JACK";
1178 capela 143 // Check if there's one audio output device already created
1179     // for the intended audio driver type (AudioOutputDriver)...
1180     AudioOutputDevice *pDevice = NULL;
1181     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1182     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1183     for (; iter != devices.end(); iter++) {
1184     if ((iter->second)->Driver() == AudioOutputDriver) {
1185     pDevice = iter->second;
1186     break;
1187     }
1188     }
1189     // If it doesn't exist, create a new one with default parameters...
1190     if (pDevice == NULL) {
1191     std::map<String,String> params;
1192     pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1193     }
1194     // Must have a device...
1195     if (pDevice == NULL)
1196     throw LinuxSamplerException("Internal error: could not create audio output device.");
1197     // Set it as the current channel device...
1198     pSamplerChannel->SetAudioOutputDevice(pDevice);
1199     }
1200     catch (LinuxSamplerException e) {
1201     result.Error(e);
1202     }
1203     return result.Produce();
1204     }
1205    
1206 capela 159 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1207     dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1208 senkov 120 LSCPResultSet result;
1209 schoenebeck 53 try {
1210     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1211 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1212 capela 159 pSamplerChannel->SetMidiInputPort(MIDIPort);
1213 schoenebeck 53 }
1214     catch (LinuxSamplerException e) {
1215 senkov 120 result.Error(e);
1216 schoenebeck 53 }
1217 senkov 120 return result.Produce();
1218 schoenebeck 53 }
1219    
1220 capela 159 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1221     dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1222 senkov 120 LSCPResultSet result;
1223 senkov 68 try {
1224     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1225 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1226 schoenebeck 221 pSamplerChannel->SetMidiInputChannel((MidiInputPort::midi_chan_t) MIDIChannel);
1227 senkov 68 }
1228     catch (LinuxSamplerException e) {
1229 senkov 120 result.Error(e);
1230 senkov 68 }
1231 senkov 120 return result.Produce();
1232 schoenebeck 35 }
1233    
1234 capela 159 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1235     dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1236 schoenebeck 123 LSCPResultSet result;
1237     try {
1238 capela 159 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1239 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1240 capela 159 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1241 schoenebeck 223 if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1242 capela 159 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1243     pSamplerChannel->SetMidiInputDevice(pDevice);
1244 schoenebeck 123 }
1245     catch (LinuxSamplerException e) {
1246     result.Error(e);
1247     }
1248     return result.Produce();
1249     }
1250    
1251 capela 159 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1252     dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1253     LSCPResultSet result;
1254     try {
1255     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1256 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1257 capela 159 // Driver type name aliasing...
1258 schoenebeck 226 if (MidiInputDriver == "Alsa") MidiInputDriver = "ALSA";
1259 capela 159 // Check if there's one MIDI input device already created
1260     // for the intended MIDI driver type (MidiInputDriver)...
1261     MidiInputDevice *pDevice = NULL;
1262     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1263     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1264     for (; iter != devices.end(); iter++) {
1265     if ((iter->second)->Driver() == MidiInputDriver) {
1266     pDevice = iter->second;
1267     break;
1268     }
1269     }
1270     // If it doesn't exist, create a new one with default parameters...
1271     if (pDevice == NULL) {
1272     std::map<String,String> params;
1273     pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1274     // Make it with at least one initial port.
1275     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1276 schoenebeck 221 parameters["PORTS"]->SetValue("1");
1277 capela 159 }
1278     // Must have a device...
1279     if (pDevice == NULL)
1280     throw LinuxSamplerException("Internal error: could not create MIDI input device.");
1281     // Set it as the current channel device...
1282     pSamplerChannel->SetMidiInputDevice(pDevice);
1283     }
1284     catch (LinuxSamplerException e) {
1285     result.Error(e);
1286     }
1287     return result.Produce();
1288     }
1289    
1290 schoenebeck 35 /**
1291 capela 159 * Will be called by the parser to change the MIDI input device, port and channel on which
1292     * engine of a particular sampler channel should listen to.
1293     */
1294     String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1295     dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1296     LSCPResultSet result;
1297     try {
1298     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1299 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1300 capela 159 std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1301 schoenebeck 223 if (!devices.count(MIDIDeviceId)) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1302 capela 159 MidiInputDevice* pDevice = devices[MIDIDeviceId];
1303 schoenebeck 221 pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (MidiInputPort::midi_chan_t) MIDIChannel);
1304 capela 159 }
1305     catch (LinuxSamplerException e) {
1306     result.Error(e);
1307     }
1308     return result.Produce();
1309     }
1310    
1311     /**
1312 schoenebeck 35 * Will be called by the parser to change the global volume factor on a
1313     * particular sampler channel.
1314     */
1315 schoenebeck 225 String LSCPServer::SetVolume(double dVolume, uint uiSamplerChannel) {
1316     dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", dVolume, uiSamplerChannel));
1317 senkov 120 LSCPResultSet result;
1318 schoenebeck 53 try {
1319     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1320 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1321 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
1322 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
1323 schoenebeck 225 pEngine->Volume(dVolume);
1324 schoenebeck 53 }
1325     catch (LinuxSamplerException e) {
1326 senkov 120 result.Error(e);
1327 schoenebeck 53 }
1328 senkov 120 return result.Produce();
1329 schoenebeck 35 }
1330    
1331     /**
1332     * Will be called by the parser to reset a particular sampler channel.
1333     */
1334 schoenebeck 53 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
1335     dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
1336 senkov 120 LSCPResultSet result;
1337 schoenebeck 53 try {
1338     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1339 schoenebeck 374 if (!pSamplerChannel) throw LinuxSamplerException("Invalid sampler channel number " + ToString(uiSamplerChannel));
1340 schoenebeck 53 Engine* pEngine = pSamplerChannel->GetEngine();
1341 schoenebeck 374 if (!pEngine) throw LinuxSamplerException("No engine loaded on sampler channel");
1342 schoenebeck 53 pEngine->Reset();
1343     }
1344     catch (LinuxSamplerException e) {
1345 senkov 120 result.Error(e);
1346 schoenebeck 53 }
1347 senkov 120 return result.Produce();
1348 schoenebeck 35 }
1349    
1350     /**
1351 schoenebeck 212 * Will be called by the parser to reset the whole sampler.
1352     */
1353     String LSCPServer::ResetSampler() {
1354     dmsg(2,("LSCPServer: ResetSampler()\n"));
1355     pSampler->Reset();
1356     LSCPResultSet result;
1357     return result.Produce();
1358     }
1359    
1360     /**
1361 schoenebeck 35 * Will be called by the parser to subscribe a client (frontend) on the
1362     * server for receiving event messages.
1363     */
1364 senkov 170 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
1365     dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1366     LSCPResultSet result;
1367     SubscriptionMutex.Lock();
1368     eventSubscriptions[type].push_back(currentSocket);
1369     SubscriptionMutex.Unlock();
1370     return result.Produce();
1371 schoenebeck 35 }
1372    
1373     /**
1374     * Will be called by the parser to unsubscribe a client on the server
1375     * for not receiving further event messages.
1376     */
1377 senkov 170 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
1378     dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1379     LSCPResultSet result;
1380     SubscriptionMutex.Lock();
1381     eventSubscriptions[type].remove(currentSocket);
1382     SubscriptionMutex.Unlock();
1383     return result.Produce();
1384 schoenebeck 35 }
1385 capela 133
1386 schoenebeck 210 /**
1387     * Will be called by the parser to enable or disable echo mode; if echo
1388     * mode is enabled, all commands from the client will (immediately) be
1389     * echoed back to the client.
1390     */
1391     String LSCPServer::SetEcho(yyparse_param_t* pSession, double boolean_value) {
1392     dmsg(2,("LSCPServer: SetEcho(val=%f)\n", boolean_value));
1393     LSCPResultSet result;
1394     try {
1395     if (boolean_value == 0) pSession->bVerbose = false;
1396     else if (boolean_value == 1) pSession->bVerbose = true;
1397     else throw LinuxSamplerException("Not a boolean value, must either be 0 or 1");
1398     }
1399     catch (LinuxSamplerException e) {
1400     result.Error(e);
1401     }
1402     return result.Produce();
1403     }
1404 capela 133
1405     // Instrument loader constructor.
1406     LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)
1407     : Thread(false, 0, -4)
1408     {
1409     this->pEngine = pEngine;
1410     this->Filename = Filename;
1411     this->uiInstrument = uiInstrument;
1412     }
1413    
1414     // Instrument loader process.
1415     int LSCPLoadInstrument::Main()
1416     {
1417     try {
1418     pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
1419     }
1420    
1421     catch (LinuxSamplerException e) {
1422     e.PrintMessage();
1423     }
1424    
1425     // Always re-enable the engine.
1426     pEngine->Enable();
1427    
1428     // FIXME: Shoot ourselves on the foot?
1429     delete this;
1430     }

  ViewVC Help
Powered by ViewVC