/[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 219 - (hide annotations) (download)
Tue Aug 17 20:35:04 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 57474 byte(s)
* completely removed the lex scanner and replaced it by pure yacc rules
  for all terminal symbols (that is command keywords and variables) to
  avoid misunderstandings while parsing (e.g. recognition of command
  keywords in string arguments)
* src/drivers/audio/AudioChannel.cpp: changed channel parameter 'Name' to
 'NAME' as defined in the LSCP documentation

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

  ViewVC Help
Powered by ViewVC