/[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 274 - (hide annotations) (download)
Sat Oct 9 00:46:18 2004 UTC (19 years, 5 months ago) by schoenebeck
File size: 59919 byte(s)
* MidiInputPort: fixed dispatching of MIDI events to engines which are
  listening to all MIDI channels
* switched MIDI channel indexing to low level indexing (means 0..15 now)

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

  ViewVC Help
Powered by ViewVC