/[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 142 - (show 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 /***************************************************************************
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, bool bBackground) {
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 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 }
149 catch (LinuxSamplerException e) {
150 result.Error(e);
151 }
152 return result.Produce();
153 }
154
155 /**
156 * Will be called by the parser to load and deploy an engine.
157 */
158 String LSCPServer::LoadEngine(String EngineName, uint uiSamplerChannel) {
159 dmsg(2,("LSCPServer: LoadEngine(EngineName=%s,SamplerChannel=%d)\n", EngineName.c_str(), uiSamplerChannel));
160 LSCPResultSet result;
161 try {
162 Engine::type_t type;
163 if ((EngineName == "GigEngine") || (EngineName == "gig")) type = Engine::type_gig;
164 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 result.Error(e);
171 }
172 return result.Produce();
173 }
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 LSCPResultSet result;
181 result.Add(pSampler->SamplerChannels());
182 return result.Produce();
183 }
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 SamplerChannel* pSamplerChannel = pSampler->AddSamplerChannel();
191 LSCPResultSet result(pSamplerChannel->Index());
192 return result.Produce();
193 }
194
195 /**
196 * Will be called by the parser to remove a sampler channel.
197 */
198 String LSCPServer::RemoveChannel(uint uiSamplerChannel) {
199 dmsg(2,("LSCPServer: RemoveChannel(SamplerChannel=%d)\n", uiSamplerChannel));
200 LSCPResultSet result;
201 pSampler->RemoveSamplerChannel(uiSamplerChannel);
202 return result.Produce();
203 }
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 LSCPResultSet result("GigEngine");
211 return result.Produce();
212 }
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 LSCPResultSet result;
220 try {
221 if ((EngineName == "GigEngine") || (EngineName == "gig")) {
222 Engine* pEngine = new LinuxSampler::gig::Engine;
223 result.Add(pEngine->Description());
224 result.Add(pEngine->Version());
225 delete pEngine;
226 }
227 else throw LinuxSamplerException("Unknown engine type");
228 }
229 catch (LinuxSamplerException e) {
230 result.Error(e);
231 }
232 return result.Produce();
233 }
234
235 /**
236 * Will be called by the parser to get informations about a particular
237 * sampler channel.
238 */
239 String LSCPServer::GetChannelInfo(uint uiSamplerChannel) {
240 dmsg(2,("LSCPServer: GetChannelInfo(SamplerChannel=%d)\n", uiSamplerChannel));
241 LSCPResultSet result;
242 try {
243 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
244 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
245 Engine* pEngine = pSamplerChannel->GetEngine();
246
247 //Defaults values
248 String EngineName = "NONE";
249 float Volume = 0;
250 String InstrumentFileName = "NONE";
251 int InstrumentIndex = -1;
252 int InstrumentStatus = -1;
253
254 if (pEngine) {
255 EngineName = pEngine->EngineName();
256 Volume = pEngine->Volume();
257 InstrumentStatus = pEngine->InstrumentStatus();
258 InstrumentIndex = pEngine->InstrumentIndex();
259 if (InstrumentIndex != -1)
260 InstrumentFileName = pEngine->InstrumentFileName();
261 }
262
263 result.Add("ENGINE_NAME", EngineName);
264 result.Add("VOLUME", Volume);
265
266 //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 result.Add("INSTRUMENT_FILE", InstrumentFileName);
272 result.Add("INSTRUMENT_NR", InstrumentIndex);
273 result.Add("INSTRUMENT_STATUS", InstrumentStatus);
274
275 //Some more hardcoded stuff for now to make GUI look good
276 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 result.Error(e);
282 }
283 return result.Produce();
284 }
285
286 /**
287 * Will be called by the parser to get the amount of active voices on a
288 * particular sampler channel.
289 */
290 String LSCPServer::GetVoiceCount(uint uiSamplerChannel) {
291 dmsg(2,("LSCPServer: GetVoiceCount(SamplerChannel=%d)\n", uiSamplerChannel));
292 LSCPResultSet result;
293 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 result.Add(pEngine->VoiceCount());
299 }
300 catch (LinuxSamplerException e) {
301 result.Error(e);
302 }
303 return result.Produce();
304 }
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 String LSCPServer::GetStreamCount(uint uiSamplerChannel) {
311 dmsg(2,("LSCPServer: GetStreamCount(SamplerChannel=%d)\n", uiSamplerChannel));
312 LSCPResultSet result;
313 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 result.Add(pEngine->DiskStreamCount());
319 }
320 catch (LinuxSamplerException e) {
321 result.Error(e);
322 }
323 return result.Produce();
324 }
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 String LSCPServer::GetBufferFill(fill_response_t ResponseType, uint uiSamplerChannel) {
331 dmsg(2,("LSCPServer: GetBufferFill(ResponseType=%d, SamplerChannel=%d)\n", ResponseType, uiSamplerChannel));
332 LSCPResultSet result;
333 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 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 }
353 catch (LinuxSamplerException e) {
354 result.Error(e);
355 }
356 return result.Produce();
357 }
358
359 String LSCPServer::GetAvailableAudioOutputDrivers() {
360 dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
361 LSCPResultSet result;
362 try {
363 String s = AudioOutputDeviceFactory::AvailableDriversAsString();
364 result.Add(s);
365 }
366 catch (LinuxSamplerException e) {
367 result.Error(e);
368 }
369 return result.Produce();
370 }
371
372 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 result.Add(count); // success
424 }
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 /**
573 * Will be called by the parser to change the audio output channel for
574 * playback on a particular sampler channel.
575 */
576 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 return "ERR:0:Not implemented yet.\r\n"; //FIXME: Add support for this in resultset class?
579 }
580
581 String LSCPServer::SetMIDIInputType(String MidiInputDriver, uint uiSamplerChannel) {
582 dmsg(2,("LSCPServer: SetMIDIInputType(String MidiInputDriver=%s, SamplerChannel=%d)\n",MidiInputDriver.c_str(),uiSamplerChannel));
583 LSCPResultSet result;
584 try {
585 SamplerChannel* pSamplerChannel = pSampler->GetSamplerChannel(uiSamplerChannel);
586 if (!pSamplerChannel) throw LinuxSamplerException("Index out of bounds");
587 // 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 if (MidiInputDriver != "Alsa") throw LinuxSamplerException("Unknown MIDI input driver '" + MidiInputDriver + "'.");
589 MidiInputDevice::type_t MidiInputType = MidiInputDevice::type_alsa;
590 pSamplerChannel->SetMidiInputDevice(MidiInputType);
591 }
592 catch (LinuxSamplerException e) {
593 result.Error(e);
594 }
595 return result.Produce();
596 }
597
598 /**
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 String LSCPServer::SetMIDIInputPort(String MIDIInputPort, uint uiSamplerChannel) {
603 dmsg(2,("LSCPServer: SetMIDIInputPort(MIDIInputPort=%s, Samplerchannel=%d)\n", MIDIInputPort.c_str(), uiSamplerChannel));
604 LSCPResultSet result;
605 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 result.Error(e);
613 }
614 return result.Produce();
615 }
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 String LSCPServer::SetMIDIInputChannel(uint MIDIChannel, uint uiSamplerChannel) {
622 dmsg(2,("LSCPServer: SetMIDIInputChannel(MIDIChannel=%d, SamplerChannel=%d)\n", MIDIChannel, uiSamplerChannel));
623 LSCPResultSet result;
624 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 pSamplerChannel->SetMidiInputDevice(oldtype, (MidiInputDevice::midi_chan_t) MIDIChannel);
630 }
631 catch (LinuxSamplerException e) {
632 result.Error(e);
633 }
634 return result.Produce();
635 }
636
637 String LSCPServer::SetAudioOutputDevice(uint AudioDeviceId, uint uiSamplerChannel) {
638 LSCPResultSet result;
639 try {
640 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 }
649 catch (LinuxSamplerException e) {
650 result.Error(e);
651 }
652 return result.Produce();
653 }
654
655 /**
656 * Will be called by the parser to change the global volume factor on a
657 * particular sampler channel.
658 */
659 String LSCPServer::SetVolume(double Volume, uint uiSamplerChannel) {
660 dmsg(2,("LSCPServer: SetVolume(Volume=%f, SamplerChannel=%d)\n", Volume, uiSamplerChannel));
661 LSCPResultSet result;
662 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 result.Error(e);
671 }
672 return result.Produce();
673 }
674
675 /**
676 * Will be called by the parser to reset a particular sampler channel.
677 */
678 String LSCPServer::ResetChannel(uint uiSamplerChannel) {
679 dmsg(2,("LSCPServer: ResetChannel(SamplerChannel=%d)\n", uiSamplerChannel));
680 LSCPResultSet result;
681 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 result.Error(e);
690 }
691 return result.Produce();
692 }
693
694 /**
695 * Will be called by the parser to subscribe a client (frontend) on the
696 * server for receiving event messages.
697 */
698 String LSCPServer::SubscribeNotification(event_t Event) {
699 dmsg(2,("LSCPServer: SubscribeNotification(Event=%d)\n", Event));
700 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 String LSCPServer::UnsubscribeNotification(event_t Event) {
708 dmsg(2,("LSCPServer: UnsubscribeNotification(Event=%d)\n", Event));
709 return "ERR:0:Not implemented yet.\r\n";
710 }
711
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