/[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 209 - (hide annotations) (download)
Sun Jul 18 00:29:39 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 55329 byte(s)
* src/Sampler.cpp: changed sampler channel index allocation from consistent
channel index allocation to incrementing channel index allocation, that is
it doesn't fill channel index gaps anymore (to avoid race conditions)
* implemented "LIST CHANNELS" LSCP command

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

  ViewVC Help
Powered by ViewVC