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

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

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

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

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

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

  ViewVC Help
Powered by ViewVC