--- liblscp/trunk/src/device.c 2004/06/04 21:06:59 107 +++ liblscp/trunk/src/device.c 2005/05/09 10:17:12 523 @@ -2,7 +2,7 @@ // /**************************************************************************** liblscp - LinuxSampler Control Protocol API - Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved. + Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,14 +25,18 @@ // Local prototypes. -static lscp_driver_info_t *_lscp_driver_info_query (lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, const char *pszQuery); +static lscp_driver_info_t *_lscp_driver_info_query (lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, char *pszQuery); +static lscp_device_info_t *_lscp_device_info_query (lscp_client_t *pClient, lscp_device_info_t *pDeviceInfo, char *pszQuery); +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); + +static lscp_device_port_info_t *_lscp_device_port_info_query (lscp_client_t *pClient, lscp_device_port_info_t *pDevicePortInfo, char *pszQuery); //------------------------------------------------------------------------- // Local funtions. // Common driver type query command. -static lscp_driver_info_t *_lscp_driver_info_query ( lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, const char *pszQuery ) +static lscp_driver_info_t *_lscp_driver_info_query ( lscp_client_t *pClient, lscp_driver_info_t *pDriverInfo, char *pszQuery ) { const char *pszResult; const char *pszSeps = ":"; @@ -40,33 +44,218 @@ char *pszToken; char *pch; + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + lscp_driver_info_reset(pDriverInfo); + if (lscp_client_call(pClient, pszQuery) == LSCP_OK) { + pszResult = lscp_client_get_result(pClient); + pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch)); + while (pszToken) { + if (strcasecmp(pszToken, "DESCRIPTION") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pDriverInfo->description), &pszToken); + } + else if (strcasecmp(pszToken, "VERSION") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pDriverInfo->version), &pszToken); + } + else if (strcasecmp(pszToken, "PARAMETERS") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) { + if (pDriverInfo->parameters) + lscp_szsplit_destroy(pDriverInfo->parameters); + pDriverInfo->parameters = lscp_szsplit_create(pszToken, ","); + } + } + pszToken = lscp_strtok(NULL, pszSeps, &(pch)); + } + } + else pDriverInfo = NULL; + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); - if (lscp_client_query(pClient, pszQuery) != LSCP_OK) - return NULL; + return pDriverInfo; +} + + +// Common device info query command. +static lscp_device_info_t *_lscp_device_info_query ( lscp_client_t *pClient, lscp_device_info_t *pDeviceInfo, char *pszQuery ) +{ + const char *pszResult; + const char *pszSeps = ":"; + const char *pszCrlf = "\r\n"; + char *pszToken; + char *pch; + char *pszKey; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); - pszResult = lscp_client_get_result(pClient); - pszToken = lscp_strtok(pszResult, pszSeps, &(pch)); - while (pszToken) { - if (strcasecmp(pszToken, "DESCRIPTION") == 0) { - pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); - if (pszToken) - pDriverInfo->description = lscp_unquote(&pszToken, 1); + lscp_device_info_reset(pDeviceInfo); + if (lscp_client_call(pClient, pszQuery) == LSCP_OK) { + pszResult = lscp_client_get_result(pClient); + pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch)); + while (pszToken) { + if (strcasecmp(pszToken, "DRIVER") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pDeviceInfo->driver), &pszToken); + } + else { + pszKey = pszToken; + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_plist_append(&(pDeviceInfo->params), pszKey, lscp_unquote(&pszToken, 0)); + } + pszToken = lscp_strtok(NULL, pszSeps, &(pch)); } - else if (strcasecmp(pszToken, "VERSION") == 0) { - pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); - if (pszToken) - pDriverInfo->version = lscp_unquote(&pszToken, 1); + } + else pDeviceInfo = NULL; + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return pDeviceInfo; +} + + +// Common device channel/port info query command. +static lscp_device_port_info_t *_lscp_device_port_info_query ( lscp_client_t *pClient, lscp_device_port_info_t *pDevicePortInfo, char *pszQuery ) +{ + const char *pszResult; + const char *pszSeps = ":"; + const char *pszCrlf = "\r\n"; + char *pszToken; + char *pch; + char *pszKey; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + lscp_device_port_info_reset(pDevicePortInfo); + if (lscp_client_call(pClient, pszQuery) == LSCP_OK) { + pszResult = lscp_client_get_result(pClient); + pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch)); + while (pszToken) { + if (strcasecmp(pszToken, "NAME") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pDevicePortInfo->name), &pszToken); + } + else { + pszKey = pszToken; + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_plist_append(&(pDevicePortInfo->params), pszKey, lscp_unquote(&pszToken, 0)); + } + pszToken = lscp_strtok(NULL, pszSeps, &(pch)); } - else if (strcasecmp(pszToken, "PARAMETERS") == 0) { - pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); - if (pszToken) - pDriverInfo->parameters = lscp_szsplit_create(pszToken, ","); + } + else pDevicePortInfo = NULL; + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return pDevicePortInfo; +} + + +// Common parameter info query command. +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 ) +{ + const char *pszResult; + const char *pszSeps = ":"; + const char *pszCrlf = "\r\n"; + char *pszToken; + char *pch; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + lscp_param_info_reset(pParamInfo); + lscp_param_concat(pszQuery, cchMaxQuery, pDepList); + if (lscp_client_call(pClient, pszQuery) == LSCP_OK) { + pszResult = lscp_client_get_result(pClient); + pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch)); + while (pszToken) { + if (strcasecmp(pszToken, "TYPE") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) { + pszToken = lscp_unquote(&pszToken, 0); + if (strcasecmp(pszToken, "BOOL") == 0) + pParamInfo->type = LSCP_TYPE_BOOL; + else if (strcasecmp(pszToken, "INT") == 0) + pParamInfo->type = LSCP_TYPE_INT; + else if (strcasecmp(pszToken, "FLOAT") == 0) + pParamInfo->type = LSCP_TYPE_FLOAT; + else if (strcasecmp(pszToken, "STRING") == 0) + pParamInfo->type = LSCP_TYPE_STRING; + } + } + else if (strcasecmp(pszToken, "DESCRIPTION") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pParamInfo->description), &pszToken); + } + else if (strcasecmp(pszToken, "MANDATORY") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + pParamInfo->mandatory = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0); + } + else if (strcasecmp(pszToken, "FIX") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + pParamInfo->fix = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0); + } + else if (strcasecmp(pszToken, "MULTIPLICITY") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + pParamInfo->multiplicity = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0); + } + else if (strcasecmp(pszToken, "DEPENDS") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) { + if (pParamInfo->depends) + lscp_szsplit_destroy(pParamInfo->depends); + pParamInfo->depends = lscp_szsplit_create(pszToken, ","); + } + } + else if (strcasecmp(pszToken, "DEFAULT") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pParamInfo->defaultv), &pszToken); + } + else if (strcasecmp(pszToken, "RANGE_MIN") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pParamInfo->range_min), &pszToken); + } + else if (strcasecmp(pszToken, "RANGE_MAX") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) + lscp_unquote_dup(&(pParamInfo->range_max), &pszToken); + } + else if (strcasecmp(pszToken, "POSSIBILITIES") == 0) { + pszToken = lscp_strtok(NULL, pszCrlf, &(pch)); + if (pszToken) { + if (pParamInfo->possibilities) + lscp_szsplit_destroy(pParamInfo->possibilities); + pParamInfo->possibilities = lscp_szsplit_create(pszToken, ","); + } + } + pszToken = lscp_strtok(NULL, pszSeps, &(pch)); } - pszToken = lscp_strtok(NULL, pszSeps, &(pch)); } + else pParamInfo = NULL; - return pDriverInfo; + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return pParamInfo; } @@ -74,26 +263,58 @@ // Audio driver control functions. /** - * Getting all available audio output drivers. + * Getting all available audio output driver count. * GET AVAILABLE_AUDIO_OUTPUT_DRIVERS * * @param pClient Pointer to client instance structure. * + * @returns The current total number of audio output drivers on success, + * -1 otherwise. + */ +int lscp_get_available_audio_drivers ( lscp_client_t *pClient ) +{ + int iAudioDrivers = -1; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (lscp_client_call(pClient, "GET AVAILABLE_AUDIO_OUTPUT_DRIVERS\r\n") == LSCP_OK) + iAudioDrivers = atoi(lscp_client_get_result(pClient)); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return iAudioDrivers; +} + + +/** + * Getting all available audio output drivers. + * LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS + * + * @param pClient Pointer to client instance structure. + * * @returns A NULL terminated array of audio output driver type * name strings, or NULL in case of failure. */ -const char ** lscp_get_available_audio_drivers ( lscp_client_t *pClient ) +const char ** lscp_list_available_audio_drivers ( lscp_client_t *pClient ) { const char *pszSeps = ","; + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + if (pClient->audio_drivers) { lscp_szsplit_destroy(pClient->audio_drivers); pClient->audio_drivers = NULL; } - if (lscp_client_query(pClient, "GET AVAILABLE_AUDIO_OUTPUT_DRIVERS\r\n") == LSCP_OK) + if (lscp_client_call(pClient, "LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS\r\n") == LSCP_OK) pClient->audio_drivers = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps); + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + return (const char **) pClient->audio_drivers; } @@ -116,7 +337,7 @@ return NULL; sprintf(szQuery, "GET AUDIO_OUTPUT_DRIVER INFO %s\r\n", pszAudioDriver); - return _lscp_driver_info_query(pClient, &(pClient->audio_info), szQuery); + return _lscp_driver_info_query(pClient, &(pClient->audio_driver_info), szQuery); } @@ -134,7 +355,7 @@ */ lscp_param_info_t *lscp_get_audio_driver_param_info ( lscp_client_t *pClient, const char *pszAudioDriver, const char *pszParam, lscp_param_t *pDepList ) { - lscp_param_info_t *pParamInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -142,10 +363,9 @@ return NULL; if (pszParam == NULL) return NULL; - if (pDepList == NULL) - return NULL; - return pParamInfo; + sprintf(szQuery, "GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO %s %s", pszAudioDriver, pszParam); + return _lscp_param_info_query(pClient, &(pClient->audio_param_info), szQuery, sizeof(szQuery), pDepList); } @@ -165,14 +385,24 @@ */ int lscp_create_audio_device ( lscp_client_t *pClient, const char *pszAudioDriver, lscp_param_t *pParams ) { + char szQuery[LSCP_BUFSIZ]; int iAudioDevice = -1; if (pClient == NULL) - return -1; + return iAudioDevice; if (pszAudioDriver == NULL) - return -1; - if (pParams == NULL) - return -1; + return iAudioDevice; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + sprintf(szQuery, "CREATE AUDIO_OUTPUT_DEVICE %s", pszAudioDriver); + lscp_param_concat(szQuery, sizeof(szQuery), pParams); + if (lscp_client_call(pClient, szQuery) == LSCP_OK) + iAudioDevice = atoi(lscp_client_get_result(pClient)); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); return iAudioDevice; } @@ -190,33 +420,75 @@ lscp_status_t lscp_destroy_audio_device ( lscp_client_t *pClient, int iAudioDevice ) { lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return ret; if (iAudioDevice < 0) return ret; - return ret; + sprintf(szQuery, "DESTROY AUDIO_OUTPUT_DEVICE %d\r\n", iAudioDevice); + return lscp_client_query(pClient, szQuery); } /** - * Getting all created audio output devices. + * Getting all created audio output device count. * GET AUDIO_OUTPUT_DEVICES * * @param pClient Pointer to client instance structure. * + * @returns The current total number of audio devices on success, + * -1 otherwise. + */ +int lscp_get_audio_devices ( lscp_client_t *pClient ) +{ + int iAudioDevices = -1; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (lscp_client_call(pClient, "GET AUDIO_OUTPUT_DEVICES\r\n") == LSCP_OK) + iAudioDevices = atoi(lscp_client_get_result(pClient)); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return iAudioDevices; +} + + +/** + * Getting all created audio output device list. + * LIST AUDIO_OUTPUT_DEVICES + * + * @param pClient Pointer to client instance structure. + * * @returns An array of audio device number identifiers, * terminated with -1 on success, or NULL in case of failure. */ -int *lscp_get_audio_devices ( lscp_client_t *pClient ) +int *lscp_list_audio_devices ( lscp_client_t *pClient ) { - int *piAudioDevices = NULL; + const char *pszSeps = ","; if (pClient == NULL) return NULL; - return piAudioDevices; + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (pClient->audio_devices) { + lscp_isplit_destroy(pClient->audio_devices); + pClient->audio_devices = NULL; + } + + if (lscp_client_call(pClient, "LIST AUDIO_OUTPUT_DEVICES\r\n") == LSCP_OK) + pClient->audio_devices = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return pClient->audio_devices; } @@ -232,20 +504,21 @@ */ lscp_device_info_t *lscp_get_audio_device_info ( lscp_client_t *pClient, int iAudioDevice ) { - lscp_device_info_t *pDeviceInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; if (iAudioDevice < 0) return NULL; - return pDeviceInfo; + sprintf(szQuery, "GET AUDIO_OUTPUT_DEVICE INFO %d\r\n", iAudioDevice); + return _lscp_device_info_query(pClient, &(pClient->audio_device_info), szQuery); } /** * Changing settings of audio output devices. - * SET AUDIO_OUTPUT_DEVICE_PARAMETER + * SET AUDIO_OUTPUT_DEVICE_PARAMETER = * * @param pClient Pointer to client instance structure. * @param iAudioDevice Audio device number identifier. @@ -255,16 +528,17 @@ */ lscp_status_t lscp_set_audio_device_param ( lscp_client_t *pClient, int iAudioDevice, lscp_param_t *pParam ) { - lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) - return ret; + return LSCP_FAILED; if (iAudioDevice < 0) - return ret; + return LSCP_FAILED; if (pParam == NULL) - return ret; + return LSCP_FAILED; - return ret; + sprintf(szQuery, "SET AUDIO_OUTPUT_DEVICE_PARAMETER %d %s='%s'\r\n", iAudioDevice, pParam->key, pParam->value); + return lscp_client_query(pClient, szQuery); } @@ -276,12 +550,12 @@ * @param iAudioDevice Audio device number identifier. * @param iAudioChannel Audio channel number. * - * @returns A pointer to a @ref lscp_device_channel_info_t structure, + * @returns A pointer to a @ref lscp_device_port_info_t structure, * with the given audio channel information, or NULL in case of failure. */ -lscp_device_channel_info_t* lscp_get_audio_channel_info ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel ) +lscp_device_port_info_t* lscp_get_audio_channel_info ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel ) { - lscp_device_channel_info_t *pDevChannelInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -290,7 +564,8 @@ if (iAudioChannel < 0) return NULL; - return pDevChannelInfo; + sprintf(szQuery, "GET AUDIO_OUTPUT_CHANNEL INFO %d %d\r\n", iAudioDevice, iAudioChannel); + return _lscp_device_port_info_query(pClient, &(pClient->audio_channel_info), szQuery); } @@ -308,7 +583,7 @@ */ lscp_param_info_t* lscp_get_audio_channel_param_info ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel, const char *pszParam ) { - lscp_param_info_t *pParamInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -319,7 +594,8 @@ if (pszParam == NULL) return NULL; - return pParamInfo; + sprintf(szQuery, "GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO %d %d %s", iAudioDevice, iAudioChannel, pszParam); + return _lscp_param_info_query(pClient, &(pClient->audio_channel_param_info), szQuery, sizeof(szQuery), NULL); } @@ -336,18 +612,19 @@ */ lscp_status_t lscp_set_audio_channel_param ( lscp_client_t *pClient, int iAudioDevice, int iAudioChannel, lscp_param_t *pParam ) { - lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) - return ret; + return LSCP_FAILED; if (iAudioDevice < 0) - return ret; + return LSCP_FAILED; if (iAudioChannel < 0) - return ret; + return LSCP_FAILED; if (pParam == NULL) - return ret; + return LSCP_FAILED; - return ret; + sprintf(szQuery, "SET AUDIO_OUTPUT_CHANNEL_PARAMETER %d %d %s='%s'\r\n", iAudioDevice, iAudioChannel, pParam->key, pParam->value); + return lscp_client_query(pClient, szQuery); } @@ -355,26 +632,58 @@ // MIDI driver control functions. /** - * Getting all available MIDI input drivers. + * Getting all available MIDI input driver count. * GET AVAILABLE_MIDI_INPUT_DRIVERS * * @param pClient Pointer to client instance structure. * + * @returns The current total number of MIDI input drivers on success, + * -1 otherwise. + */ +int lscp_get_available_midi_drivers ( lscp_client_t *pClient ) +{ + int iMidiDrivers = -1; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (lscp_client_call(pClient, "GET AVAILABLE_MIDI_INPUT_DRIVERS\r\n") == LSCP_OK) + iMidiDrivers = atoi(lscp_client_get_result(pClient)); + + // Unlock this section up. + lscp_mutex_unlock(pClient->mutex); + + return iMidiDrivers; +} + + +/** + * Getting all available MIDI input drivers. + * LIST AVAILABLE_MIDI_INPUT_DRIVERS + * + * @param pClient Pointer to client instance structure. + * * @returns A NULL terminated array of MIDI input driver type * name strings, or NULL in case of failure. */ -const char** lscp_get_available_midi_drivers ( lscp_client_t *pClient ) +const char** lscp_list_available_midi_drivers ( lscp_client_t *pClient ) { const char *pszSeps = ","; + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + if (pClient->midi_drivers) { lscp_szsplit_destroy(pClient->midi_drivers); pClient->midi_drivers = NULL; } - if (lscp_client_query(pClient, "GET AVAILABLE_MIDI_INPUT_DRIVERS\r\n") == LSCP_OK) + if (lscp_client_call(pClient, "LIST AVAILABLE_MIDI_INPUT_DRIVERS\r\n") == LSCP_OK) pClient->midi_drivers = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps); + // Unlock this section up. + lscp_mutex_unlock(pClient->mutex); + return (const char **) pClient->midi_drivers; } @@ -397,7 +706,7 @@ return NULL; sprintf(szQuery, "GET MIDI_INPUT_DRIVER INFO %s\r\n", pszMidiDriver); - return _lscp_driver_info_query(pClient, &(pClient->midi_info), szQuery); + return _lscp_driver_info_query(pClient, &(pClient->midi_driver_info), szQuery); } @@ -417,7 +726,7 @@ */ lscp_param_info_t *lscp_get_midi_driver_param_info ( lscp_client_t *pClient, const char *pszMidiDriver, const char *pszParam, lscp_param_t *pDepList ) { - lscp_param_info_t *pParamInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -425,10 +734,9 @@ return NULL; if (pszParam == NULL) return NULL; - if (pDepList == NULL) - return NULL; - return pParamInfo; + sprintf(szQuery, "GET MIDI_INPUT_DRIVER_PARAMETER INFO %s %s", pszMidiDriver, pszParam); + return _lscp_param_info_query(pClient, &(pClient->midi_param_info), szQuery, sizeof(szQuery), pDepList); } @@ -448,14 +756,24 @@ */ int lscp_create_midi_device ( lscp_client_t *pClient, const char *pszMidiDriver, lscp_param_t *pParams ) { + char szQuery[LSCP_BUFSIZ]; int iMidiDevice = -1; if (pClient == NULL) - return -1; + return iMidiDevice; if (pszMidiDriver == NULL) - return -1; - if (pParams == NULL) - return -1; + return iMidiDevice; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + sprintf(szQuery, "CREATE MIDI_INPUT_DEVICE %s", pszMidiDriver); + lscp_param_concat(szQuery, sizeof(szQuery), pParams); + if (lscp_client_call(pClient, szQuery) == LSCP_OK) + iMidiDevice = atoi(lscp_client_get_result(pClient)); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); return iMidiDevice; } @@ -473,33 +791,75 @@ lscp_status_t lscp_destroy_midi_device ( lscp_client_t *pClient, int iMidiDevice ) { lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return ret; if (iMidiDevice < 0) return ret; - return ret; + sprintf(szQuery, "DESTROY MIDI_INPUT_DEVICE %d\r\n", iMidiDevice); + return lscp_client_query(pClient, szQuery); } /** - * Getting all created MIDI input devices. + * Getting all created MIDI intput device count. * GET MIDI_INPUT_DEVICES * * @param pClient Pointer to client instance structure. * + * @returns The current total number of MIDI devices on success, + * -1 otherwise. + */ +int lscp_get_midi_devices ( lscp_client_t *pClient ) +{ + int iMidiDevices = -1; + + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (lscp_client_call(pClient, "GET MIDI_INPUT_DEVICES\r\n") == LSCP_OK) + iMidiDevices = atoi(lscp_client_get_result(pClient)); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return iMidiDevices; +} + + +/** + * Getting all created MIDI intput device list. + * LIST MIDI_INPUT_DEVICES + * + * @param pClient Pointer to client instance structure. + * * @returns An array of MIDI device number identifiers, * terminated with -1 on success, or NULL in case of failure. */ -int *lscp_get_midi_devices ( lscp_client_t *pClient ) +int *lscp_list_midi_devices ( lscp_client_t *pClient ) { - int *piMidiDevices = NULL; + const char *pszSeps = ","; if (pClient == NULL) return NULL; - return piMidiDevices; + // Lock this section up. + lscp_mutex_lock(pClient->mutex); + + if (pClient->midi_devices) { + lscp_isplit_destroy(pClient->midi_devices); + pClient->midi_devices = NULL; + } + + if (lscp_client_call(pClient, "LIST MIDI_INPUT_DEVICES\r\n") == LSCP_OK) + pClient->midi_devices = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps); + + // Unlock this section down. + lscp_mutex_unlock(pClient->mutex); + + return pClient->midi_devices; } @@ -515,20 +875,21 @@ */ lscp_device_info_t* lscp_get_midi_device_info ( lscp_client_t *pClient, int iMidiDevice ) { - lscp_device_info_t *pDeviceInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; if (iMidiDevice < 0) return NULL; - return pDeviceInfo; + sprintf(szQuery, "GET MIDI_INPUT_DEVICE INFO %d\r\n", iMidiDevice); + return _lscp_device_info_query(pClient, &(pClient->midi_device_info), szQuery); } /** * Changing settings of MIDI input devices. - * SET MIDI_INPUT_DEVICE_PARAMETER + * SET MIDI_INPUT_DEVICE_PARAMETER = * * @param pClient Pointer to client instance structure. * @param iMidiDevice MIDI device number identifier. @@ -538,16 +899,17 @@ */ lscp_status_t lscp_set_midi_device_param ( lscp_client_t *pClient, int iMidiDevice, lscp_param_t *pParam ) { - lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) - return ret; + return LSCP_FAILED; if (iMidiDevice < 0) - return ret; + return LSCP_FAILED; if (pParam == NULL) - return ret; + return LSCP_FAILED; - return ret; + sprintf(szQuery, "SET MIDI_INPUT_DEVICE_PARAMETER %d %s='%s'\r\n", iMidiDevice, pParam->key, pParam->value); + return lscp_client_query(pClient, szQuery); } @@ -559,12 +921,12 @@ * @param iMidiDevice MIDI device number identifier. * @param iMidiPort MIDI port number. * - * @returns A pointer to a @ref lscp_device_channel_info_t structure, + * @returns A pointer to a @ref lscp_device_port_info_t structure, * with the given MIDI port information, or NULL in case of failure. */ -lscp_device_channel_info_t* lscp_get_midi_port_info ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort ) +lscp_device_port_info_t* lscp_get_midi_port_info ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort ) { - lscp_device_channel_info_t *pDevChannelInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -573,7 +935,8 @@ if (iMidiPort < 0) return NULL; - return pDevChannelInfo; + sprintf(szQuery, "GET MIDI_INPUT_PORT INFO %d %d\r\n", iMidiDevice, iMidiPort); + return _lscp_device_port_info_query(pClient, &(pClient->midi_port_info), szQuery); } @@ -591,7 +954,7 @@ */ lscp_param_info_t* lscp_get_midi_port_param_info ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort, const char *pszParam ) { - lscp_param_info_t *pParamInfo = NULL; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) return NULL; @@ -602,7 +965,8 @@ if (pszParam == NULL) return NULL; - return pParamInfo; + sprintf(szQuery, "GET MIDI_INPUT_PORT_PARAMETER INFO %d %d %s", iMidiDevice, iMidiPort, pszParam); + return _lscp_param_info_query(pClient, &(pClient->midi_port_param_info), szQuery, sizeof(szQuery), NULL); } @@ -619,19 +983,36 @@ */ lscp_status_t lscp_set_midi_port_param ( lscp_client_t *pClient, int iMidiDevice, int iMidiPort, lscp_param_t *pParam ) { - lscp_status_t ret = LSCP_FAILED; + char szQuery[LSCP_BUFSIZ]; if (pClient == NULL) - return ret; + return LSCP_FAILED; if (iMidiDevice < 0) - return ret; + return LSCP_FAILED; if (iMidiPort < 0) - return ret; + return LSCP_FAILED; if (pParam == NULL) - return ret; + return LSCP_FAILED; - return ret; + sprintf(szQuery, "SET MIDI_INPUT_PORT_PARAMETER %d %d %s='%s'\r\n", iMidiDevice, iMidiPort, pParam->key, pParam->value); + return lscp_client_query(pClient, szQuery); } + +//------------------------------------------------------------------------- +// Generic parameter list functions. + +const char *lscp_get_param_value ( lscp_param_t *pParams, const char *pszParam ) +{ + int i; + + for (i = 0; pParams && pParams[i].key; i++) { + if (strcasecmp(pParams[i].key, pszParam) == 0) + return (const char *) pParams[i].value; + } + return NULL; +} + + // end of device.c