/[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 143 - (hide annotations) (download)
Wed Jun 23 18:54:08 2004 UTC (19 years, 9 months ago) by capela
File size: 32622 byte(s)
* SET CHANNEL AUDIO_OUTPUT_TYPE <chan> <driver> command is back!
  creates an audio output device instance of the given driver type
  ('Jack' or 'Alsa') with default parameters if none exists,
  otherwise it just picks the first available device and assign
  it to the intended sampler channel.

* The AudioOutputDevice class get's a new pure virtual method,
  Driver(), which is implemented on both of the existing inherited
  classes, AudioOutputDeviceAlsa and AudioOutputDeviceJack, with
  the sole purpose to return the driver type name as a String
  ('Alsa' and 'Jack', respectively).

* The quoting on the filename argument for the LOAD INSTRUMENT
  command has been made optional; you can have both ways, with
  single quotes or none, keeping compability with older LSCP
  specification.

* An additional sanity check is made on LOAD INSTRUMENT, whether
  the sampler channel has an audio output device assigned, thus
  preventing the server from crashing on instrument file load.

* The GET AUDIO_OUTPUT_DEVICE INFO now includes the missing
  'driver' item, as predicted by the draft protocol document.

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 schoenebeck 35
26 schoenebeck 53 #include "../engines/gig/Engine.h"
27 schoenebeck 123 #include "../audiodriver/AudioOutputDeviceFactory.h"
28 schoenebeck 53
29     LSCPServer::LSCPServer(Sampler* pSampler) : Thread(false, 0, -4) {
30     this->pSampler = pSampler;
31 schoenebeck 35 }
32    
33     int LSCPServer::Main() {
34     hSocket = socket(AF_INET, SOCK_STREAM, 0);
35     if (hSocket < 0) {
36     std::cerr << "LSCPServer: Could not create server socket." << std::endl;
37 schoenebeck 53 //return -1;
38     exit(EXIT_FAILURE);
39 schoenebeck 35 }
40    
41     SocketAddress.sin_family = AF_INET;
42     SocketAddress.sin_port = htons(LSCP_PORT);
43     SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
44    
45     if (bind(hSocket, (sockaddr*) &SocketAddress, sizeof(sockaddr_in)) < 0) {
46     std::cerr << "LSCPServer: Could not bind server socket." << std::endl;
47     close(hSocket);
48 schoenebeck 53 //return -1;
49     exit(EXIT_FAILURE);
50 schoenebeck 35 }
51    
52     listen(hSocket, 1);
53     dmsg(1,("LSCPServer: Server running.\n")); // server running
54    
55     // now wait for client connections and handle their requests
56     sockaddr_in client;
57     int length = sizeof(client);
58     while (true) {
59     hSession = accept(hSocket, (sockaddr*) &client, (socklen_t*) &length);
60     if (hSession < 0) {
61     std::cerr << "LSCPServer: Client connection failed." << std::endl;
62     close(hSocket);
63 schoenebeck 53 //return -1;
64     exit(EXIT_FAILURE);
65 schoenebeck 35 }
66    
67     dmsg(1,("LSCPServer: Client connection established.\n"));
68     //send(hSession, "Welcome!\r\n", 10, 0);
69    
70     // Parser invocation
71     yyparse_param_t yyparse_param;
72     yyparse_param.pServer = this;
73     yylex_init(&yyparse_param.pScanner);
74     while (yyparse(&yyparse_param) == LSCP_SYNTAX_ERROR); // recall parser in case of syntax error
75     yylex_destroy(yyparse_param.pScanner);
76    
77     close(hSession);
78     dmsg(1,("LSCPServer: Client connection terminated.\n"));
79     }
80     }
81    
82     /**
83     * Will be called by the parser whenever it wants to send an answer to the
84     * client / frontend.
85     *
86     * @param ReturnMessage - message that will be send to the client
87     */
88     void LSCPServer::AnswerClient(String ReturnMessage) {
89     dmsg(2,("LSCPServer::AnswerClient(ReturnMessage=%s)", ReturnMessage.c_str()));
90     send(hSession, ReturnMessage.c_str(), ReturnMessage.size(), 0);
91     }
92    
93 capela 143 /**
94     * Find a created audio output device index.
95     */
96     int LSCPServer::GetAudioOutputDeviceIndex ( AudioOutputDevice *pDevice )
97     {
98     // Search for the created device to get its index
99     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
100     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
101     for (; iter != devices.end(); iter++) {
102     if (iter->second == pDevice)
103     return iter->first;
104     }
105     // Not found.
106     return -1;
107     }
108    
109 schoenebeck 123 String LSCPServer::CreateAudioOutputDevice(String Driver, std::map<String,String> Parameters) {
110     dmsg(2,("LSCPServer: CreateAudioOutputDevice(Driver=%s)\n", Driver.c_str()));
111     LSCPResultSet result;
112     try {
113     AudioOutputDevice* pDevice = pSampler->CreateAudioOutputDevice(Driver, Parameters);
114     // search for the created device to get its index
115 capela 143 int index = GetAudioOutputDeviceIndex(pDevice);
116 schoenebeck 123 if (index == -1) throw LinuxSamplerException("Internal error: could not find created audio output device.");
117     result = index; // success
118     }
119     catch (LinuxSamplerException e) {
120     result.Error(e);
121     }
122     return result.Produce();
123     }
124    
125     String LSCPServer::DestroyAudioOutputDevice(uint DeviceIndex) {
126     dmsg(2,("LSCPServer: DestroyAudioOutputDevice(DeviceIndex=%d)\n", DeviceIndex));
127     LSCPResultSet result;
128     try {
129     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
130     if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
131     AudioOutputDevice* pDevice = devices[DeviceIndex];
132     pSampler->DestroyAudioOutputDevice(pDevice);
133     }
134     catch (LinuxSamplerException e) {
135     result.Error(e);
136     }
137     return result.Produce();
138     }
139    
140 schoenebeck 35 /**
141     * Will be called by the parser to load an instrument.
142     */
143 capela 137 String LSCPServer::LoadInstrument(String Filename, uint uiInstrument, uint uiSamplerChannel, bool bBackground) {
144 schoenebeck 53 dmsg(2,("LSCPServer: LoadInstrument(Filename=%s,Instrument=%d,SamplerChannel=%d)\n", Filename.c_str(), uiInstrument, uiSamplerChannel));
145 senkov 120 LSCPResultSet result;
146 schoenebeck 53 try {
147     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
148     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
149     Engine* pEngine = pSamplerChannel->GetEngine();
150     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
151 capela 143 if (pSamplerChannel->GetAudioOutputDevice() == NULL)
152     throw LinuxSamplerException("No audio output device on channel");
153 capela 137 if (bBackground) {
154     LSCPLoadInstrument *pLoadInstrument = new LSCPLoadInstrument(pEngine, Filename.c_str(), uiInstrument);
155     pLoadInstrument->StartThread();
156     }
157     else pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
158 schoenebeck 53 }
159     catch (LinuxSamplerException e) {
160 senkov 120 result.Error(e);
161 schoenebeck 53 }
162 senkov 120 return result.Produce();
163 schoenebeck 35 }
164    
165     /**
166     * Will be called by the parser to load and deploy an engine.
167     */
168 schoenebeck 53 String LSCPServer::LoadEngine(String EngineName, uint uiSamplerChannel) {
169     dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
170 senkov 120 LSCPResultSet result;
171 schoenebeck 53 try {
172 schoenebeck 64 Engine::type_t type;
173 senkov 120 if ((EngineName == "GigEngine") || (EngineName == "gig")) type = Engine::type_gig;
174 schoenebeck 53 else throw LinuxSamplerException("Unknown engine type");
175     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
176     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
177     pSamplerChannel->LoadEngine(type);
178     }
179     catch (LinuxSamplerException e) {
180 senkov 120 result.Error(e);
181 schoenebeck 53 }
182 senkov 120 return result.Produce();
183 schoenebeck 35 }
184    
185     /**
186     * Will be called by the parser to get the amount of sampler channels.
187     */
188     String LSCPServer::GetChannels() {
189     dmsg(2,("LSCPServer: GetChannels()\n"));
190 senkov 120 LSCPResultSet result;
191     result.Add(pSampler->SamplerChannels());
192     return result.Produce();
193 schoenebeck 35 }
194    
195     /**
196     * Will be called by the parser to add a sampler channel.
197     */
198     String LSCPServer::AddChannel() {
199     dmsg(2,("LSCPServer: AddChannel()\n"));
200 schoenebeck 53 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
201 senkov 120 LSCPResultSet result(pSamplerChannel->Index());
202     return result.Produce();
203 schoenebeck 35 }
204    
205     /**
206     * Will be called by the parser to remove a sampler channel.
207     */
208 schoenebeck 53 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
209     dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
210 senkov 120 LSCPResultSet result;
211 schoenebeck 53 pSampler->RemoveSamplerChannel(uiSamplerChannel);
212 senkov 120 return result.Produce();
213 schoenebeck 35 }
214    
215     /**
216     * Will be called by the parser to get all available engines.
217     */
218     String LSCPServer::GetAvailableEngines() {
219     dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
220 senkov 120 LSCPResultSet result("GigEngine");
221     return result.Produce();
222 schoenebeck 35 }
223    
224     /**
225     * Will be called by the parser to get descriptions for a particular engine.
226     */
227     String LSCPServer::GetEngineInfo(String EngineName) {
228     dmsg(2,("LSCPServer: GetEngineInfo(EngineName=%s)\n", EngineName.c_str()));
229 senkov 120 LSCPResultSet result;
230 schoenebeck 53 try {
231 senkov 120 if ((EngineName == "GigEngine") || (EngineName == "gig")) {
232 schoenebeck 53 Engine* pEngine = new LinuxSampler::gig::Engine;
233 senkov 120 result.Add(pEngine->Description());
234 schoenebeck 123 result.Add(pEngine->Version());
235 schoenebeck 53 delete pEngine;
236     }
237     else throw LinuxSamplerException("Unknown engine type");
238     }
239     catch (LinuxSamplerException e) {
240 senkov 120 result.Error(e);
241 schoenebeck 53 }
242 senkov 120 return result.Produce();
243 schoenebeck 35 }
244    
245     /**
246     * Will be called by the parser to get informations about a particular
247     * sampler channel.
248     */
249 schoenebeck 53 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
250     dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
251 senkov 120 LSCPResultSet result;
252 senkov 113 try {
253     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
254     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
255     Engine* pEngine = pSamplerChannel->GetEngine();
256 schoenebeck 123
257 senkov 117 //Defaults values
258     String EngineName = "NONE";
259     float Volume = 0;
260     String InstrumentFileName = "NONE";
261 capela 133 int InstrumentIndex = -1;
262     int InstrumentStatus = -1;
263 schoenebeck 123
264 senkov 113 if (pEngine) {
265 senkov 117 EngineName = pEngine->EngineName();
266     Volume = pEngine->Volume();
267 capela 133 InstrumentStatus = pEngine->InstrumentStatus();
268     InstrumentIndex = pEngine->InstrumentIndex();
269     if (InstrumentIndex != -1)
270 senkov 117 InstrumentFileName = pEngine->InstrumentFileName();
271 senkov 113 }
272 senkov 117
273     result.Add("ENGINE_NAME", EngineName);
274     result.Add("VOLUME", Volume);
275    
276 capela 143 //Some not-so-hardcoded stuff to make GUI look good
277     result.Add("AUDIO_OUTPUT_DEVICE", GetAudioOutputDeviceIndex(pSamplerChannel->GetAudioOutputDevice()));
278 senkov 113 result.Add("AUDIO_OUTPUT_CHANNELS", "2");
279     result.Add("AUDIO_OUTPUT_ROUTING", "0,1");
280    
281 senkov 117 result.Add("INSTRUMENT_FILE", InstrumentFileName);
282     result.Add("INSTRUMENT_NR", InstrumentIndex);
283 capela 133 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
284 schoenebeck 123
285 senkov 117 //Some more hardcoded stuff for now to make GUI look good
286 senkov 113 result.Add("MIDI_INPUT_DEVICE", "0");
287     result.Add("MIDI_INPUT_PORT", "0");
288     result.Add("MIDI_INPUT_CHANNEL", "1");
289     }
290     catch (LinuxSamplerException e) {
291 senkov 120 result.Error(e);
292 senkov 113 }
293 senkov 120 return result.Produce();
294 schoenebeck 35 }
295    
296     /**
297     * Will be called by the parser to get the amount of active voices on a
298     * particular sampler channel.
299     */
300 schoenebeck 53 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
301     dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
302 senkov 120 LSCPResultSet result;
303 schoenebeck 53 try {
304     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
305     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
306     Engine* pEngine = pSamplerChannel->GetEngine();
307     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
308 senkov 120 result.Add(pEngine->VoiceCount());
309 schoenebeck 53 }
310     catch (LinuxSamplerException e) {
311 senkov 120 result.Error(e);
312 schoenebeck 53 }
313 senkov 120 return result.Produce();
314 schoenebeck 35 }
315    
316     /**
317     * Will be called by the parser to get the amount of active disk streams on a
318     * particular sampler channel.
319     */
320 schoenebeck 53 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
321     dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
322 senkov 120 LSCPResultSet result;
323 schoenebeck 53 try {
324     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
325     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
326     Engine* pEngine = pSamplerChannel->GetEngine();
327     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
328 senkov 120 result.Add(pEngine->DiskStreamCount());
329 schoenebeck 53 }
330     catch (LinuxSamplerException e) {
331 senkov 120 result.Error(e);
332 schoenebeck 53 }
333 senkov 120 return result.Produce();
334 schoenebeck 35 }
335    
336     /**
337     * Will be called by the parser to get the buffer fill states of all disk
338     * streams on a particular sampler channel.
339     */
340 schoenebeck 53 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
341     dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
342 senkov 120 LSCPResultSet result;
343 schoenebeck 53 try {
344     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
345     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
346     Engine* pEngine = pSamplerChannel->GetEngine();
347     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
348 senkov 129 if (!pEngine->DiskStreamSupported())
349     result.Add("NA");
350     else {
351     switch (ResponseType) {
352     case fill_response_bytes:
353     result.Add(pEngine->DiskStreamBufferFillBytes());
354     break;
355     case fill_response_percentage:
356     result.Add(pEngine->DiskStreamBufferFillPercentage());
357     break;
358     default:
359     throw LinuxSamplerException("Unknown fill response type");
360     }
361     }
362 schoenebeck 53 }
363     catch (LinuxSamplerException e) {
364 senkov 120 result.Error(e);
365 schoenebeck 53 }
366 senkov 120 return result.Produce();
367 schoenebeck 35 }
368    
369 schoenebeck 123 String LSCPServer::GetAvailableAudioOutputDrivers() {
370     dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
371 senkov 120 LSCPResultSet result;
372 schoenebeck 53 try {
373 schoenebeck 123 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
374     result.Add(s);
375 schoenebeck 53 }
376     catch (LinuxSamplerException e) {
377 schoenebeck 123 result.Error(e);
378 schoenebeck 53 }
379 senkov 120 return result.Produce();
380 schoenebeck 35 }
381    
382 schoenebeck 123 String LSCPServer::GetAudioOutputDriverInfo(String Driver) {
383     dmsg(2,("LSCPServer: GetAudioOutputDriverInfo(Driver=%s)\n",Driver.c_str()));
384     LSCPResultSet result;
385     try {
386     result.Add("DESCRIPTION", AudioOutputDeviceFactory::GetDriverDescription(Driver));
387     result.Add("VERSION", AudioOutputDeviceFactory::GetDriverVersion(Driver));
388    
389     std::map<String,DeviceCreationParameter*> parameters = AudioOutputDeviceFactory::GetAvailableDriverParameters(Driver);
390     if (parameters.size()) { // if there are parameters defined for this driver
391     String s;
392     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
393     for (;iter != parameters.end(); iter++) {
394     if (s != "") s += ",";
395     s += iter->first;
396     }
397     result.Add("PARAMETERS", s);
398     }
399     }
400     catch (LinuxSamplerException e) {
401     result.Error(e);
402     }
403     return result.Produce();
404     }
405    
406     String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
407     dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s)\n",Driver.c_str(),Parameter.c_str()));
408     LSCPResultSet result;
409     try {
410     DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
411     result.Add("TYPE", pParameter->Type());
412     result.Add("DESCRIPTION", pParameter->Description());
413     result.Add("MANDATORY", pParameter->Mandatory());
414     result.Add("FIX", pParameter->Fix());
415     result.Add("MULTIPLICITY", pParameter->Multiplicity());
416     if (pParameter->Depends()) result.Add("DEPENDS", pParameter->Depends());
417     if (pParameter->Default()) result.Add("DEFAULT", pParameter->Default());
418     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
419     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
420     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
421     }
422     catch (LinuxSamplerException e) {
423     result.Error(e);
424     }
425     return result.Produce();
426     }
427    
428     String LSCPServer::GetAudioOutputDeviceCount() {
429     dmsg(2,("LSCPServer: GetAudioOutputDeviceCount()\n"));
430     LSCPResultSet result;
431     try {
432     uint count = pSampler->AudioOutputDevices();
433 senkov 138 result.Add(count); // success
434 schoenebeck 123 }
435     catch (LinuxSamplerException e) {
436     result.Error(e);
437     }
438     return result.Produce();
439     }
440    
441     String LSCPServer::GetAudioOutputDevices() {
442     dmsg(2,("LSCPServer: GetAudioOutputDevices()\n"));
443     LSCPResultSet result;
444     try {
445     String s;
446     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
447     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
448     for (; iter != devices.end(); iter++) {
449     if (s != "") s += ",";
450     s += ToString(iter->first);
451     }
452     result.Add(s);
453     }
454     catch (LinuxSamplerException e) {
455     result.Error(e);
456     }
457     return result.Produce();
458     }
459    
460     String LSCPServer::GetAudioOutputDeviceInfo(uint DeviceIndex) {
461     dmsg(2,("LSCPServer: GetAudioOutputDeviceInfo(DeviceIndex=%d)\n",DeviceIndex));
462     LSCPResultSet result;
463     try {
464     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
465     if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
466     AudioOutputDevice* pDevice = devices[DeviceIndex];
467 capela 143 result.Add("driver", pDevice->Driver());
468 schoenebeck 123 std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
469     std::map<String,DeviceCreationParameter*>::iterator iter = parameters.begin();
470     for (; iter != parameters.end(); iter++) {
471     result.Add(iter->first, iter->second->Value());
472     }
473     }
474     catch (LinuxSamplerException e) {
475     result.Error(e);
476     }
477     return result.Produce();
478     }
479    
480     String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
481     dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));
482     LSCPResultSet result;
483     try {
484     // get audio output device
485     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
486     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
487     AudioOutputDevice* pDevice = devices[DeviceId];
488    
489     // get audio channel
490     AudioChannel* pChannel = pDevice->Channel(ChannelId);
491     if (!pChannel) throw LinuxSamplerException("Audio ouotput device does not have channel " + ToString(ChannelId) + ".");
492    
493     // return the values of all audio channel parameters
494     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
495     std::map<String,DeviceRuntimeParameter*>::iterator iter = parameters.begin();
496     for (; iter != parameters.end(); iter++) {
497     result.Add(iter->first, iter->second->Value());
498     }
499     }
500     catch (LinuxSamplerException e) {
501     result.Error(e);
502     }
503     return result.Produce();
504     }
505    
506     String LSCPServer::GetAudioOutputChannelParameterInfo(uint DeviceId, uint ChannelId, String ParameterName) {
507     dmsg(2,("LSCPServer: GetAudioOutputChannelParameterInfo(DeviceId=%d,ChannelId=%d,ParameterName=%s)\n",DeviceId,ChannelId,ParameterName.c_str()));
508     LSCPResultSet result;
509     try {
510     // get audio output device
511     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
512     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
513     AudioOutputDevice* pDevice = devices[DeviceId];
514    
515     // get audio channel
516     AudioChannel* pChannel = pDevice->Channel(ChannelId);
517     if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
518    
519     // get desired audio channel parameter
520     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
521     if (!parameters[ParameterName]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParameterName + "'.");
522     DeviceRuntimeParameter* pParameter = parameters[ParameterName];
523    
524     // return all fields of this audio channel parameter
525     result.Add("TYPE", pParameter->Type());
526     result.Add("DESCRIPTION", pParameter->Description());
527     result.Add("FIX", pParameter->Fix());
528     result.Add("MULTIPLICITY", pParameter->Multiplicity());
529     if (pParameter->RangeMin()) result.Add("RANGE_MIN", pParameter->RangeMin());
530     if (pParameter->RangeMax()) result.Add("RANGE_MAX", pParameter->RangeMax());
531     if (pParameter->Possibilities()) result.Add("POSSIBILITIES", pParameter->Possibilities());
532     }
533     catch (LinuxSamplerException e) {
534     result.Error(e);
535     }
536     return result.Produce();
537     }
538    
539     String LSCPServer::SetAudioOutputChannelParameter(uint DeviceId, uint ChannelId, String ParamKey, String ParamVal) {
540     dmsg(2,("LSCPServer: SetAudioOutputChannelParameter(DeviceId=%d,ChannelId=%d,ParamKey=%s,ParamVal=%s)\n",DeviceId,ChannelId,ParamKey.c_str(),ParamVal.c_str()));
541     LSCPResultSet result;
542     try {
543     // get audio output device
544     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
545     if (!devices[DeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceId) + ".");
546     AudioOutputDevice* pDevice = devices[DeviceId];
547    
548     // get audio channel
549     AudioChannel* pChannel = pDevice->Channel(ChannelId);
550     if (!pChannel) throw LinuxSamplerException("Audio output device does not have channel " + ToString(ChannelId) + ".");
551    
552     // get desired audio channel parameter
553     std::map<String,DeviceRuntimeParameter*> parameters = pChannel->ChannelParameters();
554     if (!parameters[ParamKey]) throw LinuxSamplerException("Audio channel does not provide a parameter '" + ParamKey + "'.");
555     DeviceRuntimeParameter* pParameter = parameters[ParamKey];
556    
557     // set new channel parameter value
558     pParameter->SetValue(ParamVal);
559     }
560     catch (LinuxSamplerException e) {
561     result.Error(e);
562     }
563     return result.Produce();
564     }
565    
566     String LSCPServer::SetAudioOutputDeviceParameter(uint DeviceIndex, String ParamKey, String ParamVal) {
567     dmsg(2,("LSCPServer: SetAudioOutputDeviceParameter(DeviceIndex=%d,ParamKey=%s,ParamVal=%s)\n",DeviceIndex,ParamKey.c_str(),ParamVal.c_str()));
568     LSCPResultSet result;
569     try {
570     std::map<uint,AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
571     if (!devices[DeviceIndex]) throw LinuxSamplerException("There is no audio output device with index " + ToString(DeviceIndex) + ".");
572     AudioOutputDevice* pDevice = devices[DeviceIndex];
573     std::map<String,DeviceCreationParameter*> parameters = pDevice->DeviceParameters();
574     if (!parameters[ParamKey]) throw LinuxSamplerException("Audio output device " + ToString(DeviceIndex) + " does not have a device parameter '" + ParamKey + "'");
575     parameters[ParamKey]->SetValue(ParamVal);
576     }
577     catch (LinuxSamplerException e) {
578     result.Error(e);
579     }
580     return result.Produce();
581     }
582    
583 schoenebeck 35 /**
584     * Will be called by the parser to change the audio output channel for
585     * playback on a particular sampler channel.
586     */
587 schoenebeck 123 String LSCPServer::SetAudioOutputChannel(uint ChannelAudioOutputChannel, uint AudioOutputDeviceInputChannel, uint uiSamplerChannel) {
588     dmsg(2,("LSCPServer: SetAudioOutputChannel(ChannelAudioOutputChannel=%d, AudioOutputDeviceInputChannel=%d, SamplerChannel=%d)\n",ChannelAudioOutputChannel,AudioOutputDeviceInputChannel,uiSamplerChannel));
589 senkov 120 return "ERR:0:Not implemented yet.\r\n"; //FIXME: Add support for this in resultset class?
590 schoenebeck 35 }
591    
592 capela 143 String LSCPServer::SetAudioOutputType(String AudioOutputDriver, uint uiSamplerChannel) {
593     dmsg(2,("LSCPServer: SetAudioOutputType(String AudioOutputDriver=%s, SamplerChannel=%d)\n",AudioOutputDriver.c_str(),uiSamplerChannel));
594     LSCPResultSet result;
595     try {
596     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
597     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
598     // Driver type name aliasing...
599     if (AudioOutputDriver == "ALSA") AudioOutputDriver = "Alsa";
600     if (AudioOutputDriver == "JACK") AudioOutputDriver = "Jack";
601     // Check if there's one audio output device already created
602     // for the intended audio driver type (AudioOutputDriver)...
603     AudioOutputDevice *pDevice = NULL;
604     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
605     std::map<uint, AudioOutputDevice*>::iterator iter = devices.begin();
606     for (; iter != devices.end(); iter++) {
607     if ((iter->second)->Driver() == AudioOutputDriver) {
608     pDevice = iter->second;
609     break;
610     }
611     }
612     // If it doesn't exist, create a new one with default parameters...
613     if (pDevice == NULL) {
614     std::map<String,String> params;
615     pDevice = pSampler->CreateAudioOutputDevice(AudioOutputDriver, params);
616     }
617     // Must have a device...
618     if (pDevice == NULL)
619     throw LinuxSamplerException("Internal error: could not create audio output device.");
620     // Set it as the current channel device...
621     pSamplerChannel->SetAudioOutputDevice(pDevice);
622     }
623     catch (LinuxSamplerException e) {
624     result.Error(e);
625     }
626     return result.Produce();
627     }
628    
629    
630 schoenebeck 123 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
631     dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
632 senkov 120 LSCPResultSet result;
633 schoenebeck 53 try {
634     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
635     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
636 schoenebeck 123 // FIXME: workaround until MIDI driver configuration is implemented (using a Factory class for the MIDI input drivers then, like its already done for audio output drivers)
637 capela 143 if (MidiInputDriver == "ALSA") MidiInputDriver = "Alsa";
638 senkov 135 if (MidiInputDriver != "Alsa") throw LinuxSamplerException("Unknown MIDI input driver '" + MidiInputDriver + "'.");
639 schoenebeck 123 MidiInputDevice::type_t MidiInputType = MidiInputDevice::type_alsa;
640 schoenebeck 53 pSamplerChannel->SetMidiInputDevice(MidiInputType);
641     }
642     catch (LinuxSamplerException e) {
643 senkov 120 result.Error(e);
644 schoenebeck 53 }
645 senkov 120 return result.Produce();
646 schoenebeck 53 }
647    
648 schoenebeck 35 /**
649     * Will be called by the parser to change the MIDI input port on which the
650     * engine of a particular sampler channel should listen to.
651     */
652 senkov 68 String LSCPServer::SetMIDIInputPort(String MIDIInputPort, uint uiSamplerChannel) {
653     dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIInputPort=%s, Samplerchannel=%d)\n", MIDIInputPort.c_str(), uiSamplerChannel));
654 senkov 120 LSCPResultSet result;
655 senkov 68 try {
656     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
657     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
658     if (!pSamplerChannel->GetMidiInputDevice()) throw LinuxSamplerException("No MIDI input device connected yet");
659     pSamplerChannel->GetMidiInputDevice()->SetInputPort(MIDIInputPort.c_str());
660     }
661     catch (LinuxSamplerException e) {
662 senkov 120 result.Error(e);
663 senkov 68 }
664 senkov 120 return result.Produce();
665 schoenebeck 35 }
666    
667     /**
668     * Will be called by the parser to change the MIDI input channel on which the
669     * engine of a particular sampler channel should listen to.
670     */
671 schoenebeck 53 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
672     dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n", MIDIChannel, uiSamplerChannel));
673 senkov 120 LSCPResultSet result;
674 schoenebeck 64 try {
675     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
676     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
677     if (!pSamplerChannel->GetMidiInputDevice()) throw LinuxSamplerException("No MIDI input device connected yet");
678     MidiInputDevice::type_t oldtype = pSamplerChannel->GetMidiInputDevice()->Type();
679 senkov 79 pSamplerChannel->SetMidiInputDevice(oldtype, (MidiInputDevice::midi_chan_t) MIDIChannel);
680 schoenebeck 64 }
681     catch (LinuxSamplerException e) {
682 senkov 120 result.Error(e);
683 schoenebeck 64 }
684 senkov 120 return result.Produce();
685 schoenebeck 35 }
686    
687 senkov 142 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
688 schoenebeck 123 LSCPResultSet result;
689     try {
690 senkov 142 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
691     if (!pSamplerChannel) throw LinuxSamplerException("Invalid channel number " + ToString(uiSamplerChannel));
692     std::map<uint, AudioOutputDevice*> devices = pSampler->GetAudioOutputDevices();
693     if (!devices[AudioDeviceId]) throw LinuxSamplerException("There is no audio output device with index " + ToString(AudioDeviceId));
694     AudioOutputDevice* pDevice = devices[AudioDeviceId];
695     pSamplerChannel->SetAudioOutputDevice(pDevice);
696 schoenebeck 123 }
697     catch (LinuxSamplerException e) {
698     result.Error(e);
699     }
700     return result.Produce();
701     }
702    
703 schoenebeck 35 /**
704     * Will be called by the parser to change the global volume factor on a
705     * particular sampler channel.
706     */
707 schoenebeck 53 String LSCPServer::SetVolume(double Volume, uint uiSamplerChannel) {
708     dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, uiSamplerChannel));
709 senkov 120 LSCPResultSet result;
710 schoenebeck 53 try {
711     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
712     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
713     Engine* pEngine = pSamplerChannel->GetEngine();
714     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
715     pEngine->Volume(Volume);
716     }
717     catch (LinuxSamplerException e) {
718 senkov 120 result.Error(e);
719 schoenebeck 53 }
720 senkov 120 return result.Produce();
721 schoenebeck 35 }
722    
723     /**
724     * Will be called by the parser to reset a particular sampler channel.
725     */
726 schoenebeck 53 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
727     dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
728 senkov 120 LSCPResultSet result;
729 schoenebeck 53 try {
730     SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
731     if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
732     Engine* pEngine = pSamplerChannel->GetEngine();
733     if (!pEngine) throw LinuxSamplerException("No engine loaded on channel");
734     pEngine->Reset();
735     }
736     catch (LinuxSamplerException e) {
737 senkov 120 result.Error(e);
738 schoenebeck 53 }
739 senkov 120 return result.Produce();
740 schoenebeck 35 }
741    
742     /**
743     * Will be called by the parser to subscribe a client (frontend) on the
744     * server for receiving event messages.
745     */
746 senkov 135 String LSCPServer::SubscribeNotification(event_t Event) {
747     dmsg(2,("LSCPServer: SubscribeNotification(Event=%d)\n", Event));
748 schoenebeck 35 return "ERR:0:Not implemented yet.\r\n";
749     }
750    
751     /**
752     * Will be called by the parser to unsubscribe a client on the server
753     * for not receiving further event messages.
754     */
755 senkov 135 String LSCPServer::UnsubscribeNotification(event_t Event) {
756     dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%d)\n", Event));
757 schoenebeck 35 return "ERR:0:Not implemented yet.\r\n";
758     }
759 capela 133
760    
761     // Instrument loader constructor.
762     LSCPLoadInstrument::LSCPLoadInstrument(Engine* pEngine, String Filename, uint uiInstrument)
763     : Thread(false, 0, -4)
764     {
765     this->pEngine = pEngine;
766     this->Filename = Filename;
767     this->uiInstrument = uiInstrument;
768     }
769    
770     // Instrument loader process.
771     int LSCPLoadInstrument::Main()
772     {
773     try {
774     pEngine->LoadInstrument(Filename.c_str(), uiInstrument);
775     }
776    
777     catch (LinuxSamplerException e) {
778     e.PrintMessage();
779     }
780    
781     // Always re-enable the engine.
782     pEngine->Enable();
783    
784     // FIXME: Shoot ourselves on the foot?
785     delete this;
786     }

  ViewVC Help
Powered by ViewVC