/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/network/lscpserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 123 - (show annotations) (download)
Mon Jun 14 19:33:16 2004 UTC (19 years, 9 months ago) by schoenebeck
File size: 28907 byte(s)
* src/common: added template class 'optional<>' which can be used e.g. as
  return type whenever a value might be returned, but don't has to; this
  template class pretty much acts like a pointer of the given type, but is
  much more safer than a simple pointer
* src/audiodriver: added static class AudioDeviceFactory to create audio
  devices at runtime by using a string and to obtain driver informations
  of drivers at runtime, driver classes should simply use the macro
  REGISTER_AUDIO_OUTPUT_DRIVER(DriverName,DriverClass) in their cpp file
  to register the driver to LinuxSampler (no changes needed anymore in the
  LS code to add a new audio output driver)
* src/drivers: added classes to dynamically manage driver parameters; there
  are two different kinds of parameters: parameters which are need to
  create a new device (DeviceCreationParameterX) used to e.g. create an
  audio output device or a MIDI input device and parameters which are only
  available at runtime, means when a device is already created
  (DeviceRuntimeParameterX) which will be e.g. used as audio channel
  parameters and MIDI port parameters
* src/linuxsampler.cpp: all registered audio output drivers will be shown
  on the console on startup
* src/network: implemented configuration of audio output devices via LSCP

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

  ViewVC Help
Powered by ViewVC