/[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 142 - (hide annotations) (download)
Tue Jun 22 00:02:17 2004 UTC (19 years, 9 months ago) by senkov
File size: 30437 byte(s)
* Added implementation for SET CHANNEL AUDIO_OUTPUT_DEVICE

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

  ViewVC Help
Powered by ViewVC