/[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 411 - (hide annotations) (download)
Sat Feb 26 02:01:14 2005 UTC (19 years, 1 month ago) by schoenebeck
File size: 62087 byte(s)
* design change: using now one sampler engine instance and one disk thread
  instance for all sampler channels that are connected to the same audio
  output device (and are using the same engine type of course)
* added EngineFactory / EngineChannelFactory to remove the annoying build
  dependencies e.g. of the lscpserver to the actual sampler engine
  implementations
* bumped version to 0.3.0 (current CVS state is still quite broken,
  previous, stable CVS version was tagged as "v0_2_0" and is also available
  as source tarball)

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

  ViewVC Help
Powered by ViewVC