/[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 133 - (hide annotations) (download)
Fri Jun 18 14:29:02 2004 UTC (19 years, 9 months ago) by capela
File size: 29717 byte(s)
* Load Instrument patch applied; this patch makes the
  LOAD INSTRUMENT command to return immediately,
  almost/always with an OK response, while spawning
  the proper instrument file loading in the background.

* New INSTRUMENT_STATUS field on GET CHANNEL INFO result
  set; the instrument status value holds the load progress
  percentage if positive, otherwise a negative value is
  evidence of a load exception error.

* VERSION is now set to 0.2.

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

  ViewVC Help
Powered by ViewVC