1 // device.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2021, rncbc aka Rui Nuno Capela. All rights reserved.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library 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 GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 *****************************************************************************/
22
23 #include "common.h"
24
25
26 // Local prototypes.
27
28 static lscp_driver_info_t *_lscp_driver_info_query (lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, char *pszQuery);
29 static lscp_device_info_t *_lscp_device_info_query (lscp_client_t *pClient, lscp_device_info_t *pDeviceInfo, char *pszQuery);
30 static lscp_param_info_t *_lscp_param_info_query (lscp_client_t *pClient, lscp_param_info_t *pParamInfo, char *pszQuery, int cchMaxQuery, lscp_param_t *pDepList);
31
32 static lscp_device_port_info_t *_lscp_device_port_info_query (lscp_client_t *pClient, lscp_device_port_info_t *pDevicePortInfo, char *pszQuery);
33
34
35 //-------------------------------------------------------------------------
36 // Local funtions.
37
38 // Common driver type query command.
_lscp_driver_info_query(lscp_client_t * pClient,lscp_driver_info_t * pDriverInfo,char * pszQuery)39 static lscp_driver_info_t *_lscp_driver_info_query ( lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, char *pszQuery )
40 {
41 const char *pszResult;
42 const char *pszSeps = ":";
43 const char *pszCrlf = "\r\n";
44 char *pszToken;
45 char *pch;
46
47 // Lock this section up.
48 lscp_mutex_lock(pClient->mutex);
49
50 lscp_driver_info_reset(pDriverInfo);
51 if (lscp_client_call(pClient, pszQuery, 1) == LSCP_OK) {
52 pszResult = lscp_client_get_result(pClient);
53 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
54 while (pszToken) {
55 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
56 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
57 if (pszToken)
58 lscp_unquote_dup(&(pDriverInfo->description), &pszToken);
59 }
60 else if (strcasecmp(pszToken, "VERSION") == 0) {
61 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
62 if (pszToken)
63 lscp_unquote_dup(&(pDriverInfo->version), &pszToken);
64 }
65 else if (strcasecmp(pszToken, "PARAMETERS") == 0) {
66 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
67 if (pszToken) {
68 if (pDriverInfo->parameters)
69 lscp_szsplit_destroy(pDriverInfo->parameters);
70 pDriverInfo->parameters = lscp_szsplit_create(pszToken, ",");
71 }
72 }
73 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
74 }
75 }
76 else pDriverInfo = NULL;
77
78 // Unlock this section down.
79 lscp_mutex_unlock(pClient->mutex);
80
81 return pDriverInfo;
82 }
83
84
85 // Common device info query command.
_lscp_device_info_query(lscp_client_t * pClient,lscp_device_info_t * pDeviceInfo,char * pszQuery)86 static lscp_device_info_t *_lscp_device_info_query ( lscp_client_t *pClient, lscp_device_info_t *pDeviceInfo, char *pszQuery )
87 {
88 const char *pszResult;
89 const char *pszSeps = ":";
90 const char *pszCrlf = "\r\n";
91 char *pszToken;
92 char *pch;
93 char *pszKey;
94
95 // Lock this section up.
96 lscp_mutex_lock(pClient->mutex);
97
98 lscp_device_info_reset(pDeviceInfo);
99 if (lscp_client_call(pClient, pszQuery, 1) == LSCP_OK) {
100 pszResult = lscp_client_get_result(pClient);
101 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
102 while (pszToken) {
103 if (strcasecmp(pszToken, "DRIVER") == 0) {
104 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
105 if (pszToken)
106 lscp_unquote_dup(&(pDeviceInfo->driver), &pszToken);
107 }
108 else {
109 pszKey = pszToken;
110 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
111 if (pszToken)
112 lscp_plist_append(&(pDeviceInfo->params), pszKey, lscp_unquote(&pszToken, 0));
113 }
114 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
115 }
116 }
117 else pDeviceInfo = NULL;
118
119 // Unlock this section down.
120 lscp_mutex_unlock(pClient->mutex);
121
122 return pDeviceInfo;
123 }
124
125
126 // Common device channel/port info query command.
_lscp_device_port_info_query(lscp_client_t * pClient,lscp_device_port_info_t * pDevicePortInfo,char * pszQuery)127 static lscp_device_port_info_t *_lscp_device_port_info_query ( lscp_client_t *pClient, lscp_device_port_info_t *pDevicePortInfo, char *pszQuery )
128 {
129 const char *pszResult;
130 const char *pszSeps = ":";
131 const char *pszCrlf = "\r\n";
132 char *pszToken;
133 char *pch;
134 char *pszKey;
135 char *pszVal;
136
137 // Lock this section up.
138 lscp_mutex_lock(pClient->mutex);
139
140 lscp_device_port_info_reset(pDevicePortInfo);
141 if (lscp_client_call(pClient, pszQuery, 1) == LSCP_OK) {
142 pszResult = lscp_client_get_result(pClient);
143 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
144 while (pszToken) {
145 pszKey = pszToken;
146 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
147 if (pszKey && pszToken) {
148 pszVal = lscp_unquote(&pszToken, 0);
149 lscp_plist_append(&(pDevicePortInfo->params), pszKey, pszVal);
150 if (strcasecmp(pszKey, "NAME") == 0) {
151 // Free desteny string, if already there.
152 if (pDevicePortInfo->name)
153 free(pDevicePortInfo->name);
154 pDevicePortInfo->name = NULL;
155 if (pszVal)
156 pDevicePortInfo->name = strdup(pszVal);
157 }
158 }
159 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
160 }
161 }
162 else pDevicePortInfo = NULL;
163
164 // Unlock this section down.
165 lscp_mutex_unlock(pClient->mutex);
166
167 return pDevicePortInfo;
168 }
169
170
171 // Common parameter info query command.
_lscp_param_info_query(lscp_client_t * pClient,lscp_param_info_t * pParamInfo,char * pszQuery,int cchMaxQuery,lscp_param_t * pDepList)172 static lscp_param_info_t *_lscp_param_info_query ( lscp_client_t *pClient, lscp_param_info_t *pParamInfo, char *pszQuery, int cchMaxQuery, lscp_param_t *pDepList )
173 {
174 const char *pszResult;
175 const char *pszSeps = ":";
176 const char *pszCrlf = "\r\n";
177 char *pszToken;
178 char *pch;
179
180 // Lock this section up.
181 lscp_mutex_lock(pClient->mutex);
182
183 lscp_param_info_reset(pParamInfo);
184 lscp_param_concat(pszQuery, cchMaxQuery, pDepList);
185 if (lscp_client_call(pClient, pszQuery, 1) == LSCP_OK) {
186 pszResult = lscp_client_get_result(pClient);
187 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
188 while (pszToken) {
189 if (strcasecmp(pszToken, "TYPE") == 0) {
190 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
191 if (pszToken) {
192 pszToken = lscp_unquote(&pszToken, 0);
193 if (strcasecmp(pszToken, "BOOL") == 0)
194 pParamInfo->type = LSCP_TYPE_BOOL;
195 else if (strcasecmp(pszToken, "INT") == 0)
196 pParamInfo->type = LSCP_TYPE_INT;
197 else if (strcasecmp(pszToken, "FLOAT") == 0)
198 pParamInfo->type = LSCP_TYPE_FLOAT;
199 else if (strcasecmp(pszToken, "STRING") == 0)
200 pParamInfo->type = LSCP_TYPE_STRING;
201 }
202 }
203 else if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
204 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
205 if (pszToken)
206 lscp_unquote_dup(&(pParamInfo->description), &pszToken);
207 }
208 else if (strcasecmp(pszToken, "MANDATORY") == 0) {
209 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
210 if (pszToken)
211 pParamInfo->mandatory = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
212 }
213 else if (strcasecmp(pszToken, "FIX") == 0) {
214 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
215 if (pszToken)
216 pParamInfo->fix = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
217 }
218 else if (strcasecmp(pszToken, "MULTIPLICITY") == 0) {
219 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
220 if (pszToken)
221 pParamInfo->multiplicity = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
222 }
223 else if (strcasecmp(pszToken, "DEPENDS") == 0) {
224 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
225 if (pszToken) {
226 if (pParamInfo->depends)
227 lscp_szsplit_destroy(pParamInfo->depends);
228 pParamInfo->depends = lscp_szsplit_create(pszToken, ",");
229 }
230 }
231 else if (strcasecmp(pszToken, "DEFAULT") == 0) {
232 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
233 if (pszToken)
234 lscp_unquote_dup(&(pParamInfo->defaultv), &pszToken);
235 }
236 else if (strcasecmp(pszToken, "RANGE_MIN") == 0) {
237 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
238 if (pszToken)
239 lscp_unquote_dup(&(pParamInfo->range_min), &pszToken);
240 }
241 else if (strcasecmp(pszToken, "RANGE_MAX") == 0) {
242 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
243 if (pszToken)
244 lscp_unquote_dup(&(pParamInfo->range_max), &pszToken);
245 }
246 else if (strcasecmp(pszToken, "POSSIBILITIES") == 0) {
247 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
248 if (pszToken) {
249 if (pParamInfo->possibilities)
250 lscp_szsplit_destroy(pParamInfo->possibilities);
251 pParamInfo->possibilities = lscp_szsplit_create(pszToken, ",");
252 }
253 }
254 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
255 }
256 }
257 else pParamInfo = NULL;
258
259 // Unlock this section down.
260 lscp_mutex_unlock(pClient->mutex);
261
262 return pParamInfo;
263 }
264
265
266 //-------------------------------------------------------------------------
267 // Audio driver control functions.
268
269 /**
270 * Getting all available audio output driver count.
271 * GET AVAILABLE_AUDIO_OUTPUT_DRIVERS
272 *
273 * @param pClient Pointer to client instance structure.
274 *
275 * @returns The current total number of audio output drivers on success,
276 * -1 otherwise.
277 */
lscp_get_available_audio_drivers(lscp_client_t * pClient)278 int lscp_get_available_audio_drivers ( lscp_client_t *pClient )
279 {
280 int iAudioDrivers = -1;
281
282 if (pClient == NULL)
283 return -1;
284
285 // Lock this section up.
286 lscp_mutex_lock(pClient->mutex);
287
288 if (lscp_client_call(pClient, "GET AVAILABLE_AUDIO_OUTPUT_DRIVERS\r\n", 0) == LSCP_OK)
289 iAudioDrivers = atoi(lscp_client_get_result(pClient));
290
291 // Unlock this section down.
292 lscp_mutex_unlock(pClient->mutex);
293
294 return iAudioDrivers;
295 }
296
297
298 /**
299 * Getting all available audio output drivers.
300 * LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS
301 *
302 * @param pClient Pointer to client instance structure.
303 *
304 * @returns A NULL terminated array of audio output driver type
305 * name strings, or NULL in case of failure.
306 */
lscp_list_available_audio_drivers(lscp_client_t * pClient)307 const char ** lscp_list_available_audio_drivers ( lscp_client_t *pClient )
308 {
309 const char *pszSeps = ",";
310
311 if (pClient == NULL)
312 return NULL;
313
314 // Lock this section up.
315 lscp_mutex_lock(pClient->mutex);
316
317 if (pClient->audio_drivers) {
318 lscp_szsplit_destroy(pClient->audio_drivers);
319 pClient->audio_drivers = NULL;
320 }
321
322 if (lscp_client_call(pClient, "LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS\r\n", 0) == LSCP_OK)
323 pClient->audio_drivers = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
324
325 // Unlock this section down.
326 lscp_mutex_unlock(pClient->mutex);
327
328 return (const char **) pClient->audio_drivers;
329 }
330
331
332 /**
333 * Getting informations about a specific audio output driver.
334 * GET AUDIO_OUTPUT_DRIVER INFO <audio-output-type>
335 *
336 * @param pClient Pointer to client instance structure.
337 * @param pszAudioDriver Audio driver type string (e.g. "ALSA").
338 *
339 * @returns A pointer to a @ref lscp_driver_info_t structure, with
340 * the given audio driver information, or NULL in case of failure.
341 */
lscp_get_audio_driver_info(lscp_client_t * pClient,const char * pszAudioDriver)342 lscp_driver_info_t* lscp_get_audio_driver_info ( lscp_client_t *pClient, const char *pszAudioDriver )
343 {
344 char szQuery[LSCP_BUFSIZ];
345
346 if (pszAudioDriver == NULL)
347 return NULL;
348
349 sprintf(szQuery, "GET AUDIO_OUTPUT_DRIVER INFO %s\r\n", pszAudioDriver);
350 return _lscp_driver_info_query(pClient, &(pClient->audio_driver_info), szQuery);
351 }
352
353
354 /**
355 * Getting informations about specific audio output driver parameter.
356 * GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO <audio-output-driver> <param> [<dep-list>]
357 *
358 * @param pClient Pointer to client instance structure.
359 * @param pszAudioDriver Audio driver type string (e.g. "ALSA").
360 * @param pszParam Audio driver parameter name.
361 * @param pDepList Pointer to specific dependencies parameter list.
362 *
363 * @returns A pointer to a @ref lscp_param_info_t structure, with
364 * the given audio driver parameter information, or NULL in case of failure.
365 */
lscp_get_audio_driver_param_info(lscp_client_t * pClient,const char * pszAudioDriver,const char * pszParam,lscp_param_t * pDepList)366 lscp_param_info_t *lscp_get_audio_driver_param_info ( lscp_client_t *pClient, const char *pszAudioDriver, const char *pszParam, lscp_param_t *pDepList )
367 {
368 char szQuery[LSCP_BUFSIZ];
369
370 if (pClient == NULL)
371 return NULL;
372 if (pszAudioDriver == NULL)
373 return NULL;
374 if (pszParam == NULL)
375 return NULL;
376
377 sprintf(szQuery, "GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO %s %s", pszAudioDriver, pszParam);
378 return _lscp_param_info_query(pClient, &(pClient->audio_param_info), szQuery, sizeof(szQuery), pDepList);
379 }
380
381
382 //-------------------------------------------------------------------------
383 // Audio device control functions.
384
385 /**
386 * Creating an audio output device.
387 * CREATE AUDIO_OUTPUT_DEVICE <audio-output-driver> [<params>]
388 *
389 * @param pClient Pointer to client instance structure.
390 * @param pszAudioDriver Audio driver type string (e.g. "ALSA").
391 * @param pParams Pointer to specific parameter list.
392 *
393 * @returns The new audio device number identifier on success,
394 * or -1 in case of failure.
395 */
lscp_create_audio_device(lscp_client_t * pClient,const char * pszAudioDriver,lscp_param_t * pParams)396 int lscp_create_audio_device ( lscp_client_t *pClient, const char *pszAudioDriver, lscp_param_t *pParams )
397 {
398 char szQuery[LSCP_BUFSIZ];
399 int iAudioDevice = -1;
400
401 if (pClient == NULL)
402 return -1;
403 if (pszAudioDriver == NULL)
404 return -1;
405
406 // Lock this section up.
407 lscp_mutex_lock(pClient->mutex);
408
409 sprintf(szQuery, "CREATE AUDIO_OUTPUT_DEVICE %s", pszAudioDriver);
410 lscp_param_concat(szQuery, sizeof(szQuery), pParams);
411 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
412 iAudioDevice = atoi(lscp_client_get_result(pClient));
413
414 // Unlock this section down.
415 lscp_mutex_unlock(pClient->mutex);
416
417 return iAudioDevice;
418 }
419
420
421 /**
422 * Destroying an audio output device.
423 * DESTROY AUDIO_OUTPUT_DEVICE <audio-device-id>
424 *
425 * @param pClient Pointer to client instance structure.
426 * @param iAudioDevice Audio device number identifier.
427 *
428 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
429 */
lscp_destroy_audio_device(lscp_client_t * pClient,int iAudioDevice)430 lscp_status_t lscp_destroy_audio_device ( lscp_client_t *pClient, int iAudioDevice )
431 {
432 lscp_status_t ret = LSCP_FAILED;
433 char szQuery[LSCP_BUFSIZ];
434
435 if (pClient == NULL)
436 return ret;
437 if (iAudioDevice < 0)
438 return ret;
439
440 sprintf(szQuery, "DESTROY AUDIO_OUTPUT_DEVICE %d\r\n", iAudioDevice);
441 return lscp_client_query(pClient, szQuery);
442 }
443
444
445 /**
446 * Getting all created audio output device count.
447 * GET AUDIO_OUTPUT_DEVICES
448 *
449 * @param pClient Pointer to client instance structure.
450 *
451 * @returns The current total number of audio devices on success,
452 * -1 otherwise.
453 */
lscp_get_audio_devices(lscp_client_t * pClient)454 int lscp_get_audio_devices ( lscp_client_t *pClient )
455 {
456 int iAudioDevices = -1;
457
458 if (pClient == NULL)
459 return -1;
460
461 // Lock this section up.
462 lscp_mutex_lock(pClient->mutex);
463
464 if (lscp_client_call(pClient, "GET AUDIO_OUTPUT_DEVICES\r\n", 0) == LSCP_OK)
465 iAudioDevices = atoi(lscp_client_get_result(pClient));
466
467 // Unlock this section down.
468 lscp_mutex_unlock(pClient->mutex);
469
470 return iAudioDevices;
471 }
472
473
474 /**
475 * Getting all created audio output device list.
476 * LIST AUDIO_OUTPUT_DEVICES
477 *
478 * @param pClient Pointer to client instance structure.
479 *
480 * @returns An array of audio device number identifiers,
481 * terminated with -1 on success, or NULL in case of failure.
482 */
lscp_list_audio_devices(lscp_client_t * pClient)483 int *lscp_list_audio_devices ( lscp_client_t *pClient )
484 {
485 const char *pszSeps = ",";
486
487 if (pClient == NULL)
488 return NULL;
489
490 // Lock this section up.
491 lscp_mutex_lock(pClient->mutex);
492
493 if (pClient->audio_devices) {
494 lscp_isplit_destroy(pClient->audio_devices);
495 pClient->audio_devices = NULL;
496 }
497
498 if (lscp_client_call(pClient, "LIST AUDIO_OUTPUT_DEVICES\r\n", 0) == LSCP_OK)
499 pClient->audio_devices = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
500
501 // Unlock this section down.
502 lscp_mutex_unlock(pClient->mutex);
503
504 return pClient->audio_devices;
505 }
506
507
508 /**
509 * Getting current settings of an audio output device.
510 * GET AUDIO_OUTPUT_DEVICE INFO <audio-device-id>
511 *
512 * @param pClient Pointer to client instance structure.
513 * @param iAudioDevice Audio device number identifier.
514 *
515 * @returns A pointer to a @ref lscp_device_info_t structure, with
516 * the given audio device information, or NULL in case of failure.
517 */
lscp_get_audio_device_info(lscp_client_t * pClient,int iAudioDevice)518 lscp_device_info_t *lscp_get_audio_device_info ( lscp_client_t *pClient, int iAudioDevice )
519 {
520 char szQuery[LSCP_BUFSIZ];
521
522 if (pClient == NULL)
523 return NULL;
524 if (iAudioDevice < 0)
525 return NULL;
526
527 sprintf(szQuery, "GET AUDIO_OUTPUT_DEVICE INFO %d\r\n", iAudioDevice);
528 return _lscp_device_info_query(pClient, &(pClient->audio_device_info), szQuery);
529 }
530
531
532 /**
533 * Changing settings of audio output devices.
534 * SET AUDIO_OUTPUT_DEVICE_PARAMETER <audio-device-id> <param>=<value>
535 *
536 * @param pClient Pointer to client instance structure.
537 * @param iAudioDevice Audio device number identifier.
538 * @param pParam Pointer to a key-valued audio device parameter.
539 *
540 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
541 */
lscp_set_audio_device_param(lscp_client_t * pClient,int iAudioDevice,lscp_param_t * pParam)542 lscp_status_t lscp_set_audio_device_param ( lscp_client_t *pClient, int iAudioDevice, lscp_param_t *pParam )
543 {
544 char szQuery[LSCP_BUFSIZ];
545
546 if (pClient == NULL)
547 return LSCP_FAILED;
548 if (iAudioDevice < 0)
549 return LSCP_FAILED;
550 if (pParam == NULL)
551 return LSCP_FAILED;
552
553 sprintf(szQuery, "SET AUDIO_OUTPUT_DEVICE_PARAMETER %d %s='%s'\r\n", iAudioDevice, pParam->key, pParam->value);
554 return lscp_client_query(pClient, szQuery);
555 }
556
557
558 /**
559 * Getting informations about an audio channel.
560 * GET AUDIO_OUTPUT_CHANNEL INFO <audio-device-id> <audio-channel>
561 *
562 * @param pClient Pointer to client instance structure.
563 * @param iAudioDevice Audio device number identifier.
564 * @param iAudioChannel Audio channel number.
565 *
566 * @returns A pointer to a @ref lscp_device_port_info_t structure,
567 * with the given audio channel information, or NULL in case of failure.
568 */
lscp_get_audio_channel_info(lscp_client_t * pClient,int iAudioDevice,int iAudioChannel)569 lscp_device_port_info_t* lscp_get_audio_channel_info ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel )
570 {
571 char szQuery[LSCP_BUFSIZ];
572
573 if (pClient == NULL)
574 return NULL;
575 if (iAudioDevice < 0)
576 return NULL;
577 if (iAudioChannel < 0)
578 return NULL;
579
580 sprintf(szQuery, "GET AUDIO_OUTPUT_CHANNEL INFO %d %d\r\n", iAudioDevice, iAudioChannel);
581 return _lscp_device_port_info_query(pClient, &(pClient->audio_channel_info), szQuery);
582 }
583
584
585 /**
586 * Getting informations about specific audio channel parameter.
587 * GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO <audio-device-id> <audio-channel> <param>
588 *
589 * @param pClient Pointer to client instance structure.
590 * @param iAudioDevice Audio device number identifier.
591 * @param iAudioChannel Audio channel number.
592 * @param pszParam Audio channel parameter name.
593 *
594 * @returns A pointer to a @ref lscp_param_info_t structure, with
595 * the given audio channel parameter information, or NULL in case of failure.
596 */
lscp_get_audio_channel_param_info(lscp_client_t * pClient,int iAudioDevice,int iAudioChannel,const char * pszParam)597 lscp_param_info_t* lscp_get_audio_channel_param_info ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel, const char *pszParam )
598 {
599 char szQuery[LSCP_BUFSIZ];
600
601 if (pClient == NULL)
602 return NULL;
603 if (iAudioDevice < 0)
604 return NULL;
605 if (iAudioChannel < 0)
606 return NULL;
607 if (pszParam == NULL)
608 return NULL;
609
610 sprintf(szQuery, "GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO %d %d %s", iAudioDevice, iAudioChannel, pszParam);
611 return _lscp_param_info_query(pClient, &(pClient->audio_channel_param_info), szQuery, sizeof(szQuery), NULL);
612 }
613
614
615 /**
616 * Changing settings of audio output channels.
617 * SET AUDIO_OUTPUT_CHANNEL_PARAMETER <audio-device-id> <audio-channel> <param> <value>
618 *
619 * @param pClient Pointer to client instance structure.
620 * @param iAudioDevice Audio device number identifier.
621 * @param iAudioChannel Audio channel number.
622 * @param pParam Pointer to a key-valued audio channel parameter.
623 *
624 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
625 */
lscp_set_audio_channel_param(lscp_client_t * pClient,int iAudioDevice,int iAudioChannel,lscp_param_t * pParam)626 lscp_status_t lscp_set_audio_channel_param ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel, lscp_param_t *pParam )
627 {
628 char szQuery[LSCP_BUFSIZ];
629
630 if (pClient == NULL)
631 return LSCP_FAILED;
632 if (iAudioDevice < 0)
633 return LSCP_FAILED;
634 if (iAudioChannel < 0)
635 return LSCP_FAILED;
636 if (pParam == NULL)
637 return LSCP_FAILED;
638
639 sprintf(szQuery, "SET AUDIO_OUTPUT_CHANNEL_PARAMETER %d %d %s='%s'\r\n", iAudioDevice, iAudioChannel, pParam->key, pParam->value);
640 return lscp_client_query(pClient, szQuery);
641 }
642
643
644 //-------------------------------------------------------------------------
645 // MIDI driver control functions.
646
647 /**
648 * Getting all available MIDI input driver count.
649 * GET AVAILABLE_MIDI_INPUT_DRIVERS
650 *
651 * @param pClient Pointer to client instance structure.
652 *
653 * @returns The current total number of MIDI input drivers on success,
654 * -1 otherwise.
655 */
lscp_get_available_midi_drivers(lscp_client_t * pClient)656 int lscp_get_available_midi_drivers ( lscp_client_t *pClient )
657 {
658 int iMidiDrivers = -1;
659
660 if (pClient == NULL)
661 return -1;
662
663 // Lock this section up.
664 lscp_mutex_lock(pClient->mutex);
665
666 if (lscp_client_call(pClient, "GET AVAILABLE_MIDI_INPUT_DRIVERS\r\n", 0) == LSCP_OK)
667 iMidiDrivers = atoi(lscp_client_get_result(pClient));
668
669 // Unlock this section up.
670 lscp_mutex_unlock(pClient->mutex);
671
672 return iMidiDrivers;
673 }
674
675
676 /**
677 * Getting all available MIDI input drivers.
678 * LIST AVAILABLE_MIDI_INPUT_DRIVERS
679 *
680 * @param pClient Pointer to client instance structure.
681 *
682 * @returns A NULL terminated array of MIDI input driver type
683 * name strings, or NULL in case of failure.
684 */
lscp_list_available_midi_drivers(lscp_client_t * pClient)685 const char** lscp_list_available_midi_drivers ( lscp_client_t *pClient )
686 {
687 const char *pszSeps = ",";
688
689 if (pClient == NULL)
690 return NULL;
691
692 // Lock this section up.
693 lscp_mutex_lock(pClient->mutex);
694
695 if (pClient->midi_drivers) {
696 lscp_szsplit_destroy(pClient->midi_drivers);
697 pClient->midi_drivers = NULL;
698 }
699
700 if (lscp_client_call(pClient, "LIST AVAILABLE_MIDI_INPUT_DRIVERS\r\n", 0) == LSCP_OK)
701 pClient->midi_drivers = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
702
703 // Unlock this section up.
704 lscp_mutex_unlock(pClient->mutex);
705
706 return (const char **) pClient->midi_drivers;
707 }
708
709
710 /**
711 * Getting informations about a specific MIDI input driver.
712 * GET MIDI_INPUT_DRIVER INFO <midi-input-type>
713 *
714 * @param pClient Pointer to client instance structure.
715 * @param pszMidiDriver MIDI driver type string (e.g. "ALSA").
716 *
717 * @returns A pointer to a @ref lscp_driver_info_t structure, with
718 * the given MIDI driver information, or NULL in case of failure.
719 */
lscp_get_midi_driver_info(lscp_client_t * pClient,const char * pszMidiDriver)720 lscp_driver_info_t* lscp_get_midi_driver_info ( lscp_client_t *pClient, const char *pszMidiDriver )
721 {
722 char szQuery[LSCP_BUFSIZ];
723
724 if (pszMidiDriver == NULL)
725 return NULL;
726
727 sprintf(szQuery, "GET MIDI_INPUT_DRIVER INFO %s\r\n", pszMidiDriver);
728 return _lscp_driver_info_query(pClient, &(pClient->midi_driver_info), szQuery);
729 }
730
731
732 /**
733 * Getting informations about specific MIDI input driver parameter.
734 * GET MIDI_INPUT_DRIVER_PARAMETER INFO <midi-input-driver> <param> [<dep-list>]
735 *
736 * @param pClient Pointer to client instance structure.
737 * @param pszMidiDriver MIDI driver type string (e.g. "ALSA").
738 * @param pszParam MIDI driver parameter name.
739 * @param pDepList Pointer to specific dependencies parameter list.
740 *
741 * @returns A pointer to a @ref lscp_param_info_t structure, with
742 * the given MIDI driver parameter information, or NULL in case of failure.
743 *
744 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
745 */
lscp_get_midi_driver_param_info(lscp_client_t * pClient,const char * pszMidiDriver,const char * pszParam,lscp_param_t * pDepList)746 lscp_param_info_t *lscp_get_midi_driver_param_info ( lscp_client_t *pClient, const char *pszMidiDriver, const char *pszParam, lscp_param_t *pDepList )
747 {
748 char szQuery[LSCP_BUFSIZ];
749
750 if (pClient == NULL)
751 return NULL;
752 if (pszMidiDriver == NULL)
753 return NULL;
754 if (pszParam == NULL)
755 return NULL;
756
757 sprintf(szQuery, "GET MIDI_INPUT_DRIVER_PARAMETER INFO %s %s", pszMidiDriver, pszParam);
758 return _lscp_param_info_query(pClient, &(pClient->midi_param_info), szQuery, sizeof(szQuery), pDepList);
759 }
760
761
762 //-------------------------------------------------------------------------
763 // MIDI device control functions.
764
765 /**
766 * Creating a MIDI input device.
767 * CREATE MIDI_INPUT_DEVICE <midi-input-driver> [<params>]
768 *
769 * @param pClient Pointer to client instance structure.
770 * @param pszMidiDriver MIDI driver type string (e.g. "ALSA").
771 * @param pParams Pointer to specific parameter list.
772 *
773 * @returns The new audio device number identifier on success,
774 * or -1 in case of failure.
775 */
lscp_create_midi_device(lscp_client_t * pClient,const char * pszMidiDriver,lscp_param_t * pParams)776 int lscp_create_midi_device ( lscp_client_t *pClient, const char *pszMidiDriver, lscp_param_t *pParams )
777 {
778 char szQuery[LSCP_BUFSIZ];
779 int iMidiDevice = -1;
780
781 if (pClient == NULL)
782 return -1;
783 if (pszMidiDriver == NULL)
784 return -1;
785
786 // Lock this section up.
787 lscp_mutex_lock(pClient->mutex);
788
789 sprintf(szQuery, "CREATE MIDI_INPUT_DEVICE %s", pszMidiDriver);
790 lscp_param_concat(szQuery, sizeof(szQuery), pParams);
791 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
792 iMidiDevice = atoi(lscp_client_get_result(pClient));
793
794 // Unlock this section down.
795 lscp_mutex_unlock(pClient->mutex);
796
797 return iMidiDevice;
798 }
799
800
801 /**
802 * Destroying a MIDI input device.
803 * DESTROY MIDI_INPUT_DEVICE <midi-device-id>
804 *
805 * @param pClient Pointer to client instance structure.
806 * @param iMidiDevice MIDI device number identifier.
807 *
808 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
809 */
lscp_destroy_midi_device(lscp_client_t * pClient,int iMidiDevice)810 lscp_status_t lscp_destroy_midi_device ( lscp_client_t *pClient, int iMidiDevice )
811 {
812 lscp_status_t ret = LSCP_FAILED;
813 char szQuery[LSCP_BUFSIZ];
814
815 if (pClient == NULL)
816 return ret;
817 if (iMidiDevice < 0)
818 return ret;
819
820 sprintf(szQuery, "DESTROY MIDI_INPUT_DEVICE %d\r\n", iMidiDevice);
821 return lscp_client_query(pClient, szQuery);
822 }
823
824
825 /**
826 * Getting all created MIDI intput device count.
827 * GET MIDI_INPUT_DEVICES
828 *
829 * @param pClient Pointer to client instance structure.
830 *
831 * @returns The current total number of MIDI devices on success,
832 * -1 otherwise.
833 */
lscp_get_midi_devices(lscp_client_t * pClient)834 int lscp_get_midi_devices ( lscp_client_t *pClient )
835 {
836 int iMidiDevices = -1;
837
838 if (pClient == NULL)
839 return -1;
840
841 // Lock this section up.
842 lscp_mutex_lock(pClient->mutex);
843
844 if (lscp_client_call(pClient, "GET MIDI_INPUT_DEVICES\r\n", 0) == LSCP_OK)
845 iMidiDevices = atoi(lscp_client_get_result(pClient));
846
847 // Unlock this section down.
848 lscp_mutex_unlock(pClient->mutex);
849
850 return iMidiDevices;
851 }
852
853
854 /**
855 * Getting all created MIDI intput device list.
856 * LIST MIDI_INPUT_DEVICES
857 *
858 * @param pClient Pointer to client instance structure.
859 *
860 * @returns An array of MIDI device number identifiers,
861 * terminated with -1 on success, or NULL in case of failure.
862 */
lscp_list_midi_devices(lscp_client_t * pClient)863 int *lscp_list_midi_devices ( lscp_client_t *pClient )
864 {
865 const char *pszSeps = ",";
866
867 if (pClient == NULL)
868 return NULL;
869
870 // Lock this section up.
871 lscp_mutex_lock(pClient->mutex);
872
873 if (pClient->midi_devices) {
874 lscp_isplit_destroy(pClient->midi_devices);
875 pClient->midi_devices = NULL;
876 }
877
878 if (lscp_client_call(pClient, "LIST MIDI_INPUT_DEVICES\r\n", 0) == LSCP_OK)
879 pClient->midi_devices = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
880
881 // Unlock this section down.
882 lscp_mutex_unlock(pClient->mutex);
883
884 return pClient->midi_devices;
885 }
886
887
888 /**
889 * Getting current settings of a MIDI input device.
890 * GET MIDI_INPUT_DEVICE INFO <midi-device-id>
891 *
892 * @param pClient Pointer to client instance structure.
893 * @param iMidiDevice MIDI device number identifier.
894 *
895 * @returns A pointer to a @ref lscp_device_info_t structure, with
896 * the given MIDI device information, or NULL in case of failure.
897 */
lscp_get_midi_device_info(lscp_client_t * pClient,int iMidiDevice)898 lscp_device_info_t* lscp_get_midi_device_info ( lscp_client_t *pClient, int iMidiDevice )
899 {
900 char szQuery[LSCP_BUFSIZ];
901
902 if (pClient == NULL)
903 return NULL;
904 if (iMidiDevice < 0)
905 return NULL;
906
907 sprintf(szQuery, "GET MIDI_INPUT_DEVICE INFO %d\r\n", iMidiDevice);
908 return _lscp_device_info_query(pClient, &(pClient->midi_device_info), szQuery);
909 }
910
911
912 /**
913 * Changing settings of MIDI input devices.
914 * SET MIDI_INPUT_DEVICE_PARAMETER <midi-device-id> <param>=<value>
915 *
916 * @param pClient Pointer to client instance structure.
917 * @param iMidiDevice MIDI device number identifier.
918 * @param pParam Pointer to a key-valued MIDI device parameter.
919 *
920 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
921 */
lscp_set_midi_device_param(lscp_client_t * pClient,int iMidiDevice,lscp_param_t * pParam)922 lscp_status_t lscp_set_midi_device_param ( lscp_client_t *pClient, int iMidiDevice, lscp_param_t *pParam )
923 {
924 char szQuery[LSCP_BUFSIZ];
925
926 if (pClient == NULL)
927 return LSCP_FAILED;
928 if (iMidiDevice < 0)
929 return LSCP_FAILED;
930 if (pParam == NULL)
931 return LSCP_FAILED;
932
933 sprintf(szQuery, "SET MIDI_INPUT_DEVICE_PARAMETER %d %s='%s'\r\n", iMidiDevice, pParam->key, pParam->value);
934 return lscp_client_query(pClient, szQuery);
935 }
936
937
938 /**
939 * Getting informations about a MIDI port.
940 * GET MIDI_INPUT_PORT INFO <midi-device-id> <midi-port>
941 *
942 * @param pClient Pointer to client instance structure.
943 * @param iMidiDevice MIDI device number identifier.
944 * @param iMidiPort MIDI port number.
945 *
946 * @returns A pointer to a @ref lscp_device_port_info_t structure,
947 * with the given MIDI port information, or NULL in case of failure.
948 */
lscp_get_midi_port_info(lscp_client_t * pClient,int iMidiDevice,int iMidiPort)949 lscp_device_port_info_t* lscp_get_midi_port_info ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort )
950 {
951 char szQuery[LSCP_BUFSIZ];
952
953 if (pClient == NULL)
954 return NULL;
955 if (iMidiDevice < 0)
956 return NULL;
957 if (iMidiPort < 0)
958 return NULL;
959
960 sprintf(szQuery, "GET MIDI_INPUT_PORT INFO %d %d\r\n", iMidiDevice, iMidiPort);
961 return _lscp_device_port_info_query(pClient, &(pClient->midi_port_info), szQuery);
962 }
963
964
965 /**
966 * Getting informations about specific MIDI port parameter.
967 * GET MIDI_INPUT_PORT_PARAMETER INFO <midi-device-id> <midi-port> <param>
968 *
969 * @param pClient Pointer to client instance structure.
970 * @param iMidiDevice MIDI device number identifier.
971 * @param iMidiPort MIDI port number.
972 * @param pszParam MIDI port parameter name.
973 *
974 * @returns A pointer to a @ref lscp_param_info_t structure, with
975 * the given MIDI port parameter information, or NULL in case of failure.
976 */
lscp_get_midi_port_param_info(lscp_client_t * pClient,int iMidiDevice,int iMidiPort,const char * pszParam)977 lscp_param_info_t* lscp_get_midi_port_param_info ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort, const char *pszParam )
978 {
979 char szQuery[LSCP_BUFSIZ];
980
981 if (pClient == NULL)
982 return NULL;
983 if (iMidiDevice < 0)
984 return NULL;
985 if (iMidiPort < 0)
986 return NULL;
987 if (pszParam == NULL)
988 return NULL;
989
990 sprintf(szQuery, "GET MIDI_INPUT_PORT_PARAMETER INFO %d %d %s", iMidiDevice, iMidiPort, pszParam);
991 return _lscp_param_info_query(pClient, &(pClient->midi_port_param_info), szQuery, sizeof(szQuery), NULL);
992 }
993
994
995 /**
996 * Changing settings of MIDI input ports.
997 * SET MIDI_INPUT_PORT_PARAMETER <midi-device-id> <midi-port> <param> <value>
998 *
999 * @param pClient Pointer to client instance structure.
1000 * @param iMidiDevice MIDI device number identifier.
1001 * @param iMidiPort MIDI port number.
1002 * @param pParam Pointer to a key-valued MIDI port parameter.
1003 *
1004 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1005 */
lscp_set_midi_port_param(lscp_client_t * pClient,int iMidiDevice,int iMidiPort,lscp_param_t * pParam)1006 lscp_status_t lscp_set_midi_port_param ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort, lscp_param_t *pParam )
1007 {
1008 char szQuery[LSCP_BUFSIZ];
1009
1010 if (pClient == NULL)
1011 return LSCP_FAILED;
1012 if (iMidiDevice < 0)
1013 return LSCP_FAILED;
1014 if (iMidiPort < 0)
1015 return LSCP_FAILED;
1016 if (pParam == NULL)
1017 return LSCP_FAILED;
1018
1019 sprintf(szQuery, "SET MIDI_INPUT_PORT_PARAMETER %d %d %s='%s'\r\n", iMidiDevice, iMidiPort, pParam->key, pParam->value);
1020 return lscp_client_query(pClient, szQuery);
1021 }
1022
1023
1024 //-------------------------------------------------------------------------
1025 // Generic parameter list functions.
1026
lscp_get_param_value(lscp_param_t * pParams,const char * pszParam)1027 const char *lscp_get_param_value ( lscp_param_t *pParams, const char *pszParam )
1028 {
1029 int i;
1030
1031 for (i = 0; pParams && pParams[i].key; i++) {
1032 if (strcasecmp(pParams[i].key, pszParam) == 0)
1033 return (const char *) pParams[i].value;
1034 }
1035 return NULL;
1036 }
1037
1038
1039 // end of device.c
1040
1041