/[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 203 - (hide annotations) (download)
Tue Jul 13 22:44:13 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 54798 byte(s)
forgot to change some things which was mandatory due to the recent
directory movements ('/src/audiodriver' -> '/src/drivers/audio',
'/src/mididriver' -> '/src/drivers/midi')

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     * Will be called by the parser to add a sampler channel.
458     */
459     String LSCPServer::AddChannel() {
460     dmsg(2,("LSCPServer: AddChannel()\n"));
461 schoenebeck 53 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
462 senkov 120 LSCPResultSet result(pSamplerChannel->Index());
463     return result.Produce();
464 schoenebeck 35 }
465    
466     /**
467     * Will be called by the parser to remove a sampler channel.
468     */
469 schoenebeck 53 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
470     dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
471 senkov 120 LSCPResultSet result;
472 schoenebeck 53 pSampler->RemoveSamplerChannel(uiSamplerChannel);
473 senkov 120 return result.Produce();
474 schoenebeck 35 }
475    
476     /**
477     * Will be called by the parser to get all available engines.
478     */
479     String LSCPServer::GetAvailableEngines() {
480     dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
481 senkov 120 LSCPResultSet result("GigEngine");
482     return result.Produce();
483 schoenebeck 35 }
484    
485     /**
486     * Will be called by the parser to get descriptions for a particular engine.
487     */
488     String LSCPServer::GetEngineInfo(String EngineName) {
489     dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
490 senkov 120 LSCPResultSet result;
491 schoenebeck 53 try {
492 senkov 120 if ((EngineName == "GigEngine") || (EngineName == "gig")) {
493 schoenebeck 53 Engine* pEngine = new LinuxSampler::gig::Engine;
494 senkov 120 result.Add(pEngine->Description());
495 schoenebeck 123 result.Add(pEngine->Version());
496 schoenebeck 53 delete pEngine;
497     }
498     else throw LinuxSamplerException("Unknown engine type");
499     }
500     catch (LinuxSamplerException e) {
501 senkov 120 result.Error(e);
502 schoenebeck 53 }
503 senkov 120 return result.Produce();
504 schoenebeck 35 }
505    
506     /**
507     * Will be called by the parser to get informations about a particular
508     * sampler channel.
509     */
510 schoenebeck 53 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
511     dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
512 senkov 120 LSCPResultSet result;
513 senkov 113 try {
514     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
515     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
516     Engine* pEngine = pSamplerChannel->GetEngine();
517 schoenebeck 123
518 senkov 117 //Defaults values
519     String EngineName = "NONE";
520     float Volume = 0;
521     String InstrumentFileName = "NONE";
522 capela 133 int InstrumentIndex = -1;
523     int InstrumentStatus = -1;
524 schoenebeck 123
525 senkov 113 if (pEngine) {
526 senkov 117 EngineName = pEngine->EngineName();
527     Volume = pEngine->Volume();
528 capela 133 InstrumentStatus = pEngine->InstrumentStatus();
529     InstrumentIndex = pEngine->InstrumentIndex();
530     if (InstrumentIndex != -1)
531 senkov 117 InstrumentFileName = pEngine->InstrumentFileName();
532 senkov 113 }
533 senkov 117
534     result.Add("ENGINE_NAME", EngineName);
535     result.Add("VOLUME", Volume);
536    
537 capela 143 //Some not-so-hardcoded stuff to make GUI look good
538     result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
539 senkov 113 result.Add("AUDIO_OUTPUT_CHANNELS", "2");
540     result.Add("AUDIO_OUTPUT_ROUTING", "0,1");
541    
542 capela 159 result.Add("MIDI_INPUT_DEVICE", GetMidiInputDeviceIndex(pSamplerChannel->GetMidiInputDevice()));
543     result.Add("MIDI_INPUT_PORT", pSamplerChannel->GetMidiInputPort());
544     result.Add("MIDI_INPUT_CHANNEL", pSamplerChannel->GetMidiInputChannel());
545    
546 senkov 117 result.Add("INSTRUMENT_FILE", InstrumentFileName);
547     result.Add("INSTRUMENT_NR", InstrumentIndex);
548 capela 133 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
549 senkov 113 }
550     catch (LinuxSamplerException e) {
551 senkov 120 result.Error(e);
552 senkov 113 }
553 senkov 120 return result.Produce();
554 schoenebeck 35 }
555    
556     /**
557     * Will be called by the parser to get the amount of active voices on a
558     * particular sampler channel.
559     */
560 schoenebeck 53 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
561     dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
562 senkov 120 LSCPResultSet result;
563 schoenebeck 53 try {
564     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
565     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
566     Engine* pEngine = pSamplerChannel->GetEngine();
567     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
568 senkov 120 result.Add(pEngine->VoiceCount());
569 schoenebeck 53 }
570     catch (LinuxSamplerException e) {
571 senkov 120 result.Error(e);
572 schoenebeck 53 }
573 senkov 120 return result.Produce();
574 schoenebeck 35 }
575    
576     /**
577     * Will be called by the parser to get the amount of active disk streams on a
578     * particular sampler channel.
579     */
580 schoenebeck 53 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
581     dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
582 senkov 120 LSCPResultSet result;
583 schoenebeck 53 try {
584     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
585     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
586     Engine* pEngine = pSamplerChannel->GetEngine();
587     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
588 senkov 120 result.Add(pEngine->DiskStreamCount());
589 schoenebeck 53 }
590     catch (LinuxSamplerException e) {
591 senkov 120 result.Error(e);
592 schoenebeck 53 }
593 senkov 120 return result.Produce();
594 schoenebeck 35 }
595    
596     /**
597     * Will be called by the parser to get the buffer fill states of all disk
598     * streams on a particular sampler channel.
599     */
600 schoenebeck 53 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
601     dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
602 senkov 120 LSCPResultSet result;
603 schoenebeck 53 try {
604     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
605     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
606     Engine* pEngine = pSamplerChannel->GetEngine();
607     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
608 senkov 129 if (!pEngine->DiskStreamSupported())
609     result.Add("NA");
610     else {
611     switch (ResponseType) {
612     case fill_response_bytes:
613     result.Add(pEngine->DiskStreamBufferFillBytes());
614     break;
615     case fill_response_percentage:
616     result.Add(pEngine->DiskStreamBufferFillPercentage());
617     break;
618     default:
619     throw LinuxSamplerException("Unknown fill response type");
620     }
621     }
622 schoenebeck 53 }
623     catch (LinuxSamplerException e) {
624 senkov 120 result.Error(e);
625 schoenebeck 53 }
626 senkov 120 return result.Produce();
627 schoenebeck 35 }
628    
629 schoenebeck 123 String LSCPServer::GetAvailableAudioOutputDrivers() {
630     dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
631 senkov 120 LSCPResultSet result;
632 schoenebeck 53 try {
633 schoenebeck 123 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
634     result.Add(s);
635 schoenebeck 53 }
636     catch (LinuxSamplerException e) {
637 schoenebeck 123 result.Error(e);
638 schoenebeck 53 }
639 senkov 120 return result.Produce();
640 schoenebeck 35 }
641    
642 senkov 155 String LSCPServer::GetAvailableMidiInputDrivers() {
643     dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
644     LSCPResultSet result;
645     try {
646     String s = MidiInputDeviceFactory::AvailableDriversAsString();
647     result.Add(s);
648     }
649     catch (LinuxSamplerException e) {
650     result.Error(e);
651     }
652     return result.Produce();
653     }
654    
655     String LSCPServer::GetMidiInputDriverInfo(String Driver) {
656     dmsg(2,("LSCPServer: GetMidiInputDriverInfo(Driver=%s)\n",Driver.c_str()));
657     LSCPResultSet result;
658     try {
659     result.Add("DESCRIPTION", MidiInputDeviceFactory::GetDriverDescription(Driver));
660     result.Add("VERSION", MidiInputDeviceFactory::GetDriverVersion(Driver));
661    
662     std::map<String,DeviceCreationParameter*> parameters = MidiInputDeviceFactory::GetAvailableDriverParameters(Driver);
663     if (parameters.size()) { // if there are parameters defined for this driver
664     String s;
665     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
666     for (;iter != parameters.end(); iter++) {
667     if (s != "") s += ",";
668     s += iter->first;
669     }
670     result.Add("PARAMETERS", s);
671     }
672     }
673     catch (LinuxSamplerException e) {
674     result.Error(e);
675     }
676     return result.Produce();
677     }
678    
679 schoenebeck 123 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
680     dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
681     LSCPResultSet result;
682     try {
683     result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
684     result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
685    
686     std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
687     if (parameters.size()) { // if there are parameters defined for this driver
688     String s;
689     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
690     for (;iter != parameters.end(); iter++) {
691     if (s != "") s += ",";
692     s += iter->first;
693     }
694     result.Add("PARAMETERS", s);
695     }
696     }
697     catch (LinuxSamplerException e) {
698     result.Error(e);
699     }
700     return result.Produce();
701     }
702    
703 senkov 155 String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
704     dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s)\n",Driver.c_str(),Parameter.c_str()));
705     LSCPResultSet result;
706     try {
707     DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
708     result.Add("TYPE", pParameter->Type());
709     result.Add("DESCRIPTION", pParameter->Description());
710     result.Add("MANDATORY", pParameter->Mandatory());
711     result.Add("FIX", pParameter->Fix());
712     result.Add("MULTIPLICITY", pParameter->Multiplicity());
713     if (pParameter->Depends()) result.Add("DEPENDS", pParameter->Depends());
714     if (pParameter->Default()) result.Add("DEFAULT", pParameter->Default());
715     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
716     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
717     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
718     }
719     catch (LinuxSamplerException e) {
720     result.Error(e);
721     }
722     return result.Produce();
723     }
724    
725 schoenebeck 123 String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
726     dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s)\n",Driver.c_str(),Parameter.c_str()));
727     LSCPResultSet result;
728     try {
729     DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
730     result.Add("TYPE", pParameter->Type());
731     result.Add("DESCRIPTION", pParameter->Description());
732     result.Add("MANDATORY", pParameter->Mandatory());
733     result.Add("FIX", pParameter->Fix());
734     result.Add("MULTIPLICITY", pParameter->Multiplicity());
735     if (pParameter->Depends()) result.Add("DEPENDS", pParameter->Depends());
736     if (pParameter->Default()) result.Add("DEFAULT", pParameter->Default());
737     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
738     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
739     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
740     }
741     catch (LinuxSamplerException e) {
742     result.Error(e);
743     }
744     return result.Produce();
745     }
746    
747     String LSCPServer::GetAudioOutputDeviceCount() {
748     dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
749     LSCPResultSet result;
750     try {
751     uint count = pSampler->AudioOutputDevices();
752 senkov 138 result.Add(count); // success
753 schoenebeck 123 }
754     catch (LinuxSamplerException e) {
755     result.Error(e);
756     }
757     return result.Produce();
758     }
759    
760 senkov 155 String LSCPServer::GetMidiInputDeviceCount() {
761     dmsg(2,("LSCPServer: GetMidiInputDeviceCount()\n"));
762     LSCPResultSet result;
763     try {
764     uint count = pSampler->MidiInputDevices();
765     result.Add(count); // success
766     }
767     catch (LinuxSamplerException e) {
768     result.Error(e);
769     }
770     return result.Produce();
771     }
772    
773 schoenebeck 123 String LSCPServer::GetAudioOutputDevices() {
774     dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
775     LSCPResultSet result;
776     try {
777     String s;
778     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
779     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
780     for (; iter != devices.end(); iter++) {
781     if (s != "") s += ",";
782     s += ToString(iter->first);
783     }
784     result.Add(s);
785     }
786     catch (LinuxSamplerException e) {
787     result.Error(e);
788     }
789     return result.Produce();
790     }
791    
792 senkov 155 String LSCPServer::GetMidiInputDevices() {
793     dmsg(2,("LSCPServer: GetMidiInputDevices()\n"));
794     LSCPResultSet result;
795     try {
796     String s;
797     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
798     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
799     for (; iter != devices.end(); iter++) {
800     if (s != "") s += ",";
801     s += ToString(iter->first);
802     }
803     result.Add(s);
804     }
805     catch (LinuxSamplerException e) {
806     result.Error(e);
807     }
808     return result.Produce();
809     }
810    
811 schoenebeck 123 String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
812     dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
813     LSCPResultSet result;
814     try {
815     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
816     if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
817     AudioOutputDevice* pDevice = devices[DeviceIndex];
818 capela 143 result.Add("driver", pDevice->Driver());
819 schoenebeck 123 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
820     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
821     for (; iter != parameters.end(); iter++) {
822     result.Add(iter->first, iter->second->Value());
823     }
824     }
825     catch (LinuxSamplerException e) {
826     result.Error(e);
827     }
828     return result.Produce();
829     }
830    
831 senkov 155 String LSCPServer::GetMidiInputDeviceInfo(uint DeviceIndex) {
832     dmsg(2,("LSCPServer: GetMidiInputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
833     LSCPResultSet result;
834     try {
835     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
836     MidiInputDevice* pDevice = devices[DeviceIndex];
837 capela 159 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
838 senkov 155 result.Add("driver", pDevice->Driver());
839     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
840     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
841     for (; iter != parameters.end(); iter++) {
842     result.Add(iter->first, iter->second->Value());
843     }
844     }
845     catch (LinuxSamplerException e) {
846     result.Error(e);
847     }
848     return result.Produce();
849     }
850     String LSCPServer::GetMidiInputPortInfo(uint DeviceIndex, uint PortIndex) {
851     dmsg(2,("LSCPServer: GetMidiInputPortInfo(DeviceIndex=%d, PortIndex=%d)\n",DeviceIndex, PortIndex));
852     LSCPResultSet result;
853     try {
854     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
855     MidiInputDevice* pDevice = devices[DeviceIndex];
856 capela 159 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
857 senkov 155 MidiInputDevice::MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
858 capela 159 if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
859 senkov 155 std::map<String,DeviceCreationParameter*> parameters = pMidiInputPort->DeviceParameters();
860     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
861     for (; iter != parameters.end(); iter++) {
862     result.Add(iter->first, iter->second->Value());
863     }
864     }
865     catch (LinuxSamplerException e) {
866     result.Error(e);
867     }
868     return result.Produce();
869     }
870    
871 schoenebeck 123 String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
872     dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
873     LSCPResultSet result;
874     try {
875     // get audio output device
876     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
877     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
878     AudioOutputDevice* pDevice = devices[DeviceId];
879    
880     // get audio channel
881     AudioChannel* pChannel = pDevice->Channel(ChannelId);
882     if (!pChannel) throw LinuxSamplerException("Audio ouotput device does not have channel " + ToString(ChannelId) + ".");
883    
884     // return the values of all audio channel parameters
885     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
886     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
887     for (; iter != parameters.end(); iter++) {
888     result.Add(iter->first, iter->second->Value());
889     }
890     }
891     catch (LinuxSamplerException e) {
892     result.Error(e);
893     }
894     return result.Produce();
895     }
896    
897 senkov 185 String LSCPServer::GetMidiInputPortParameterInfo(uint DeviceId, uint PortId, String ParameterName) {
898     dmsg(2,("LSCPServer: GetMidiInputPortParameterInfo(DeviceId=%d,PortId=%d,ParameterName=%s)\n",DeviceId,PortId,ParameterName.c_str()));
899     LSCPResultSet result;
900     try {
901     // get audio output device
902     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
903     if (!devices[DeviceId]) throw LinuxSamplerException("There is no midi input device with index " + ToString(DeviceId) + ".");
904     MidiInputDevice* pDevice = devices[DeviceId];
905    
906     // get midi port
907     MidiInputDevice::MidiInputPort* pPort = pDevice->GetPort(PortId);
908     if (!pPort) throw LinuxSamplerException("Midi input device does not have port " + ToString(PortId) + ".");
909    
910     // get desired port parameter
911     std::map<String,DeviceCreationParameter*> parameters = pPort->DeviceParameters();
912     if (!parameters[ParameterName]) throw LinuxSamplerException("Midi port does not provice a parameters '" + ParameterName + "'.");
913     DeviceCreationParameter* pParameter = parameters[ParameterName];
914 schoenebeck 203
915 senkov 185 // return all fields of this audio channel parameter
916     result.Add("TYPE", pParameter->Type());
917     result.Add("DESCRIPTION", pParameter->Description());
918     result.Add("FIX", pParameter->Fix());
919     result.Add("MULTIPLICITY", pParameter->Multiplicity());
920     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
921     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
922     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
923     }
924     catch (LinuxSamplerException e) {
925     result.Error(e);
926     }
927     return result.Produce();
928     }
929    
930 schoenebeck 123 String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
931     dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
932     LSCPResultSet result;
933     try {
934     // get audio output device
935     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
936     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
937     AudioOutputDevice* pDevice = devices[DeviceId];
938    
939     // get audio channel
940     AudioChannel* pChannel = pDevice->Channel(ChannelId);
941     if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
942    
943     // get desired audio channel parameter
944     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
945     if (!parameters[ParameterName]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParameterName + "'.");
946     DeviceRuntimeParameter* pParameter = parameters[ParameterName];
947    
948     // return all fields of this audio channel parameter
949     result.Add("TYPE", pParameter->Type());
950     result.Add("DESCRIPTION", pParameter->Description());
951     result.Add("FIX", pParameter->Fix());
952     result.Add("MULTIPLICITY", pParameter->Multiplicity());
953     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
954     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
955     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
956     }
957     catch (LinuxSamplerException e) {
958     result.Error(e);
959     }
960     return result.Produce();
961     }
962    
963     String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
964     dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
965     LSCPResultSet result;
966     try {
967     // get audio output device
968     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
969     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
970     AudioOutputDevice* pDevice = devices[DeviceId];
971    
972     // get audio channel
973     AudioChannel* pChannel = pDevice->Channel(ChannelId);
974     if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
975    
976     // get desired audio channel parameter
977     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
978     if (!parameters[ParamKey]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParamKey + "'.");
979     DeviceRuntimeParameter* pParameter = parameters[ParamKey];
980    
981     // set new channel parameter value
982     pParameter->SetValue(ParamVal);
983     }
984     catch (LinuxSamplerException e) {
985     result.Error(e);
986     }
987     return result.Produce();
988     }
989    
990     String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
991     dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
992     LSCPResultSet result;
993     try {
994     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
995     if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
996     AudioOutputDevice* pDevice = devices[DeviceIndex];
997     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
998     if (!parameters[ParamKey]) throw LinuxSamplerException("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
999     parameters[ParamKey]->SetValue(ParamVal);
1000     }
1001     catch (LinuxSamplerException e) {
1002     result.Error(e);
1003     }
1004     return result.Produce();
1005     }
1006    
1007 senkov 155 String LSCPServer::SetMidiInputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
1008     dmsg(2,("LSCPServer: SetMidiOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
1009     LSCPResultSet result;
1010     try {
1011     std::map<uint,MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1012 capela 159 if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1013 senkov 155 MidiInputDevice* pDevice = devices[DeviceIndex];
1014     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1015 capela 159 if (!parameters[ParamKey]) throw LinuxSamplerException("MIDI input device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
1016 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1017     }
1018     catch (LinuxSamplerException e) {
1019     result.Error(e);
1020     }
1021     return result.Produce();
1022     }
1023    
1024     String LSCPServer::SetMidiInputPortParameter(uint DeviceIndex, uint PortIndex, 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     MidiInputDevice* pDevice = devices[DeviceIndex];
1030 capela 159 if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(DeviceIndex) + ".");
1031 senkov 155 MidiInputDevice::MidiInputPort* pMidiInputPort = pDevice->GetPort(PortIndex);
1032 capela 159 if (!pMidiInputPort) throw LinuxSamplerException("There is no MIDI input port with index " + ToString(PortIndex) + ".");
1033 senkov 155 std::map<String,DeviceCreationParameter*> parameters = pMidiInputPort->DeviceParameters();
1034 capela 159 if (!parameters[ParamKey]) throw LinuxSamplerException("MIDI input device " + ToString(PortIndex) + " does not have a parameter '" + ParamKey + "'");
1035 senkov 155 parameters[ParamKey]->SetValue(ParamVal);
1036     }
1037     catch (LinuxSamplerException e) {
1038     result.Error(e);
1039     }
1040     return result.Produce();
1041     }
1042    
1043 schoenebeck 35 /**
1044     * Will be called by the parser to change the audio output channel for
1045     * playback on a particular sampler channel.
1046     */
1047 schoenebeck 123 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
1048     dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
1049 senkov 120 return "ERR:0:Not implemented yet.\r\n"; //FIXME: Add support for this in resultset class?
1050 schoenebeck 35 }
1051    
1052 capela 159 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
1053     dmsg(2,("LSCPServer: SetAudiotOutputDevice(AudioDeviceId=%d, SamplerChannel=%d)\n",AudioDeviceId,uiSamplerChannel));
1054     LSCPResultSet result;
1055     try {
1056     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1057     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1058     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1059     AudioOutputDevice* pDevice = devices[AudioDeviceId];
1060     if (!pDevice) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));
1061     pSamplerChannel->SetAudioOutputDevice(pDevice);
1062     }
1063     catch (LinuxSamplerException e) {
1064     result.Error(e);
1065     }
1066     return result.Produce();
1067     }
1068    
1069 capela 143 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
1070     dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
1071     LSCPResultSet result;
1072     try {
1073     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1074     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1075     // Driver type name aliasing...
1076     if (AudioOutputDriver == "ALSA") AudioOutputDriver = "Alsa";
1077 schoenebeck 203 if (AudioOutputDriver == "JACK") AudioOutputDriver = "Jack";
1078 capela 143 // Check if there's one audio output device already created
1079     // for the intended audio driver type (AudioOutputDriver)...
1080     AudioOutputDevice *pDevice = NULL;
1081     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
1082     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
1083     for (; iter != devices.end(); iter++) {
1084     if ((iter->second)->Driver() == AudioOutputDriver) {
1085     pDevice = iter->second;
1086     break;
1087     }
1088     }
1089     // If it doesn't exist, create a new one with default parameters...
1090     if (pDevice == NULL) {
1091     std::map<String,String> params;
1092     pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
1093     }
1094     // Must have a device...
1095     if (pDevice == NULL)
1096     throw LinuxSamplerException("Internal error: could not create audio output device.");
1097     // Set it as the current channel device...
1098     pSamplerChannel->SetAudioOutputDevice(pDevice);
1099     }
1100     catch (LinuxSamplerException e) {
1101     result.Error(e);
1102     }
1103     return result.Produce();
1104     }
1105    
1106 capela 159 String LSCPServer::SetMIDIInputPort(uint MIDIPort, uint uiSamplerChannel) {
1107     dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIPort=%d, SamplerChannel=%d)\n",MIDIPort,uiSamplerChannel));
1108 senkov 120 LSCPResultSet result;
1109 schoenebeck 53 try {
1110     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1111 capela 159 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1112     pSamplerChannel->SetMidiInputPort(MIDIPort);
1113 schoenebeck 53 }
1114     catch (LinuxSamplerException e) {
1115 senkov 120 result.Error(e);
1116 schoenebeck 53 }
1117 senkov 120 return result.Produce();
1118 schoenebeck 53 }
1119    
1120 capela 159 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
1121     dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n",MIDIChannel,uiSamplerChannel));
1122 senkov 120 LSCPResultSet result;
1123 senkov 68 try {
1124     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1125 senkov 155 if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1126 capela 159 pSamplerChannel->SetMidiInputChannel((MidiInputDevice::MidiInputPort::midi_chan_t) MIDIChannel);
1127 senkov 68 }
1128     catch (LinuxSamplerException e) {
1129 senkov 120 result.Error(e);
1130 senkov 68 }
1131 senkov 120 return result.Produce();
1132 schoenebeck 35 }
1133    
1134 capela 159 String LSCPServer::SetMIDIInputDevice(uint MIDIDeviceId, uint uiSamplerChannel) {
1135     dmsg(2,("LSCPServer: SetMIDIInputDevice(MIDIDeviceId=%d, SamplerChannel=%d)\n",MIDIDeviceId,uiSamplerChannel));
1136 schoenebeck 123 LSCPResultSet result;
1137     try {
1138 capela 159 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1139     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1140     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1141     MidiInputDevice* pDevice = devices[MIDIDeviceId];
1142     if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1143     pSamplerChannel->SetMidiInputDevice(pDevice);
1144 schoenebeck 123 }
1145     catch (LinuxSamplerException e) {
1146     result.Error(e);
1147     }
1148     return result.Produce();
1149     }
1150    
1151 capela 159 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
1152     dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
1153     LSCPResultSet result;
1154     try {
1155     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1156     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1157     // Driver type name aliasing...
1158     if (MidiInputDriver == "ALSA") MidiInputDriver = "Alsa";
1159     // Check if there's one MIDI input device already created
1160     // for the intended MIDI driver type (MidiInputDriver)...
1161     MidiInputDevice *pDevice = NULL;
1162     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1163     std::map<uint, MidiInputDevice*>::iterator iter = devices.begin();
1164     for (; iter != devices.end(); iter++) {
1165     if ((iter->second)->Driver() == MidiInputDriver) {
1166     pDevice = iter->second;
1167     break;
1168     }
1169     }
1170     // If it doesn't exist, create a new one with default parameters...
1171     if (pDevice == NULL) {
1172     std::map<String,String> params;
1173     pDevice = pSampler->CreateMidiInputDevice(MidiInputDriver, params);
1174     // Make it with at least one initial port.
1175     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
1176     parameters["ports"]->SetValue("1");
1177     }
1178     // Must have a device...
1179     if (pDevice == NULL)
1180     throw LinuxSamplerException("Internal error: could not create MIDI input device.");
1181     // Set it as the current channel device...
1182     pSamplerChannel->SetMidiInputDevice(pDevice);
1183     }
1184     catch (LinuxSamplerException e) {
1185     result.Error(e);
1186     }
1187     return result.Produce();
1188     }
1189    
1190 schoenebeck 35 /**
1191 capela 159 * Will be called by the parser to change the MIDI input device, port and channel on which
1192     * engine of a particular sampler channel should listen to.
1193     */
1194     String LSCPServer::SetMIDIInput(uint MIDIDeviceId, uint MIDIPort, uint MIDIChannel, uint uiSamplerChannel) {
1195     dmsg(2,("LSCPServer: SetMIDIInput(MIDIDeviceId=%d, MIDIPort=%d, MIDIChannel=%d, SamplerChannel=%d)\n", MIDIDeviceId, MIDIPort, MIDIChannel, uiSamplerChannel));
1196     LSCPResultSet result;
1197     try {
1198     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1199     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
1200     std::map<uint, MidiInputDevice*> devices = pSampler->GetMidiInputDevices();
1201     MidiInputDevice* pDevice = devices[MIDIDeviceId];
1202     if (!pDevice) throw LinuxSamplerException("There is no MIDI input device with index " + ToString(MIDIDeviceId));
1203     pSamplerChannel->SetMidiInput(pDevice, MIDIPort, (MidiInputDevice::MidiInputPort::midi_chan_t) MIDIChannel);
1204     }
1205     catch (LinuxSamplerException e) {
1206     result.Error(e);
1207     }
1208     return result.Produce();
1209     }
1210    
1211     /**
1212 schoenebeck 35 * Will be called by the parser to change the global volume factor on a
1213     * particular sampler channel.
1214     */
1215 schoenebeck 53 String LSCPServer::SetVolume(double Volume, uint uiSamplerChannel) {
1216     dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, uiSamplerChannel));
1217 senkov 120 LSCPResultSet result;
1218 schoenebeck 53 try {
1219     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1220     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
1221     Engine* pEngine = pSamplerChannel->GetEngine();
1222     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
1223     pEngine->Volume(Volume);
1224     }
1225     catch (LinuxSamplerException e) {
1226 senkov 120 result.Error(e);
1227 schoenebeck 53 }
1228 senkov 120 return result.Produce();
1229 schoenebeck 35 }
1230    
1231     /**
1232     * Will be called by the parser to reset a particular sampler channel.
1233     */
1234 schoenebeck 53 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
1235     dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
1236 senkov 120 LSCPResultSet result;
1237 schoenebeck 53 try {
1238     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
1239     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
1240     Engine* pEngine = pSamplerChannel->GetEngine();
1241     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
1242     pEngine->Reset();
1243     }
1244     catch (LinuxSamplerException e) {
1245 senkov 120 result.Error(e);
1246 schoenebeck 53 }
1247 senkov 120 return result.Produce();
1248 schoenebeck 35 }
1249    
1250     /**
1251     * Will be called by the parser to subscribe a client (frontend) on the
1252     * server for receiving event messages.
1253     */
1254 senkov 170 String LSCPServer::SubscribeNotification(LSCPEvent::event_t type) {
1255     dmsg(2,("LSCPServer: SubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1256     LSCPResultSet result;
1257     SubscriptionMutex.Lock();
1258     eventSubscriptions[type].push_back(currentSocket);
1259     SubscriptionMutex.Unlock();
1260     return result.Produce();
1261 schoenebeck 35 }
1262    
1263     /**
1264     * Will be called by the parser to unsubscribe a client on the server
1265     * for not receiving further event messages.
1266     */
1267 senkov 170 String LSCPServer::UnsubscribeNotification(LSCPEvent::event_t type) {
1268     dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%s)\n", LSCPEvent::Name(type).c_str()));
1269     LSCPResultSet result;
1270     SubscriptionMutex.Lock();
1271     eventSubscriptions[type].remove(currentSocket);
1272     SubscriptionMutex.Unlock();
1273     return result.Produce();
1274 schoenebeck 35 }
1275 capela 133
1276    
1277     // Instrument loader constructor.
1278     LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)
1279     : Thread(false, 0, -4)
1280     {
1281     this->pEngine = pEngine;
1282     this->Filename = Filename;
1283     this->uiInstrument = uiInstrument;
1284     }
1285    
1286     // Instrument loader process.
1287     int LSCPLoadInstrument::Main()
1288     {
1289     try {
1290     pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
1291     }
1292    
1293     catch (LinuxSamplerException e) {
1294     e.PrintMessage();
1295     }
1296    
1297     // Always re-enable the engine.
1298     pEngine->Enable();
1299    
1300     // FIXME: Shoot ourselves on the foot?
1301     delete this;
1302     }

  ViewVC Help
Powered by ViewVC