From 59b29b20605efab97ba62c75629cd43053e91b86 Mon Sep 17 00:00:00 2001 From: Lukas Durfina Date: Sat, 1 Nov 2008 13:23:25 +0100 Subject: [PATCH] libvlc: better audio handling Signed-off-by: Jean-Baptiste Kempf --- include/vlc/libvlc.h | 150 +++++++++++++++- include/vlc/libvlc_structures.h | 23 +++ src/control/audio.c | 301 +++++++++++++++++++++++++++++--- src/libvlc.sym | 11 ++ 4 files changed, 457 insertions(+), 28 deletions(-) diff --git a/include/vlc/libvlc.h b/include/vlc/libvlc.h index 3a8ef99ce8..80a387010b 100644 --- a/include/vlc/libvlc.h +++ b/include/vlc/libvlc.h @@ -1022,6 +1022,135 @@ VLC_PUBLIC_API void libvlc_video_set_viewport( libvlc_instance_t *, const libvlc * @{ */ +/** + * Audio device types + */ +typedef enum libvlc_audio_output_device_types_t { + libvlc_AudioOutputDevice_Error = -1, + libvlc_AudioOutputDevice_Mono = 1, + libvlc_AudioOutputDevice_Stereo = 2, + libvlc_AudioOutputDevice_2F2R = 4, + libvlc_AudioOutputDevice_3F2R = 5, + libvlc_AudioOutputDevice_5_1 = 6, + libvlc_AudioOutputDevice_6_1 = 7, + libvlc_AudioOutputDevice_7_1 = 8, + libvlc_AudioOutputDevice_SPDIF = 10 +} libvlc_audio_output_device_types_t; + +/** + * Audio channels + */ +typedef enum libvlc_audio_output_channel_t { + libvlc_AudioChannel_Error = -1, + libvlc_AudioChannel_Stereo = 1, + libvlc_AudioChannel_RStereo = 2, + libvlc_AudioChannel_Left = 3, + libvlc_AudioChannel_Right = 4, + libvlc_AudioChannel_Dolbys = 5 +} libvlc_audio_output_channel_t; + + +/** + * Get the list of available audio outputs + * + * \param p_instance libvlc instance + * \param p_e an initialized exception pointer + * \return list of available audio outputs, at the end free it with +* \see libvlc_audio_output_list_release \see libvlc_audio_output_t + */ +VLC_PUBLIC_API libvlc_audio_output_t * + libvlc_audio_output_list_get( libvlc_instance_t *, + libvlc_exception_t * ); + +/** + * Free the list of available audio outputs + * + * \param p_list list with audio outputs for release + */ +VLC_PUBLIC_API void libvlc_audio_output_list_release( libvlc_audio_output_t * ); + +/** + * Set the audio output. + * Change will be applied after stop and play. + * + * \param p_instance libvlc instance + * \param psz_name name of audio output, + * use psz_name of \see libvlc_audio_output_t + * \return true if function succeded + */ +VLC_PUBLIC_API int libvlc_audio_output_set( libvlc_instance_t *, + const char * ); + +/** + * Get count of devices for audio output, these devices are hardware oriented + * like analor or digital output of sound card + * + * \param p_instance libvlc instance + * \param psz_audio_output - name of audio output, \see libvlc_audio_output_t + * \return number of devices + */ +VLC_PUBLIC_API int libvlc_audio_output_device_count( libvlc_instance_t *, + const char * ); + +/** + * Get long name of device, if not available short name given + * + * \param p_instance libvlc instance + * \param psz_audio_output - name of audio output, \see libvlc_audio_output_t + * \param i_device device index + * \return long name of device + */ +VLC_PUBLIC_API char * libvlc_audio_output_device_longname( libvlc_instance_t *, + const char *, + int ); + +/** + * Get id name of device + * + * \param p_instance libvlc instance + * \param psz_audio_output - name of audio output, \see libvlc_audio_output_t + * \param i_device device index + * \return id name of device, use for setting device, need to be free after use + */ +VLC_PUBLIC_API char * libvlc_audio_output_device_id( libvlc_instance_t *, + const char *, + int ); + +/** + * Set device for using + * + * \param p_instance libvlc instance + * \param psz_audio_output - name of audio output, \see libvlc_audio_output_t + * \param psz_device_id device + */ +VLC_PUBLIC_API void libvlc_audio_output_device_set( libvlc_instance_t *, + const char *, + const char * ); + +/** + * Get current audio device type. Device type describes something like + * character of output sound - stereo sound, 2.1, 5.1 etc + * + * \param p_instance vlc instance + * \param p_e an initialized exception pointer + * \return the audio devices type \see libvlc_audio_output_device_types_t + */ +VLC_PUBLIC_API int libvlc_audio_output_get_device_type( + libvlc_instance_t *, libvlc_exception_t * ); + +/** + * Set current audio device type. + * + * \param p_instance vlc instance + * \param device_type the audio device type, + according to \see libvlc_audio_output_device_types_t + * \param p_e an initialized exception pointer + */ +VLC_PUBLIC_API void libvlc_audio_output_set_device_type( libvlc_instance_t *, + int, + libvlc_exception_t * ); + + /** * Toggle mute status. * @@ -1075,6 +1204,16 @@ VLC_PUBLIC_API void libvlc_audio_set_volume( libvlc_instance_t *, int, libvlc_ex */ VLC_PUBLIC_API int libvlc_audio_get_track_count( libvlc_media_player_t *, libvlc_exception_t * ); + /** + * Get the description of available audio tracks. + * + * \param p_mi media player + * \param p_e an initialized exception + * \return list with description of available audio tracks + */ +VLC_PUBLIC_API libvlc_track_description_t * + libvlc_audio_get_track_description( libvlc_media_player_t *, libvlc_exception_t * ); + /** * Get current audio track. * @@ -1098,18 +1237,21 @@ VLC_PUBLIC_API void libvlc_audio_set_track( libvlc_media_player_t *, int, libvlc * * \param p_instance vlc instance * \param p_e an initialized exception pointer - * \return the audio channel (int) + * \return the audio channel \see libvlc_audio_output_channel_t */ -VLC_PUBLIC_API int libvlc_audio_get_channel( libvlc_instance_t *, libvlc_exception_t * ); +VLC_PUBLIC_API int + libvlc_audio_get_channel( libvlc_instance_t *, libvlc_exception_t * ); /** * Set current audio channel. * * \param p_instance vlc instance - * \param i_channel the audio channel (int) + * \param channel the audio channel, \see libvlc_audio_output_channel_t * \param p_e an initialized exception pointer */ -VLC_PUBLIC_API void libvlc_audio_set_channel( libvlc_instance_t *, int, libvlc_exception_t * ); +VLC_PUBLIC_API void libvlc_audio_set_channel( libvlc_instance_t *, + int, + libvlc_exception_t * ); /** @} audio */ diff --git a/include/vlc/libvlc_structures.h b/include/vlc/libvlc_structures.h index 3339afb795..867712f41f 100644 --- a/include/vlc/libvlc_structures.h +++ b/include/vlc/libvlc_structures.h @@ -233,6 +233,29 @@ typedef struct libvlc_track_description_t /**@} */ +/***************************************************************************** + * Audio + *****************************************************************************/ +/** \defgroup libvlc_audio libvlc_audio + * \ingroup libvlc_media_player + * LibVLC Audio handling + * @{ + */ + +/** + * Description for audio output. It contains + * name, description and pointer to next record. + */ +typedef struct libvlc_audio_output_t +{ + char *psz_name; + char *psz_description; + struct libvlc_audio_output_t *p_next; + +} libvlc_audio_output_t; + +/**@} */ + /***************************************************************************** * Video diff --git a/src/control/audio.c b/src/control/audio.c index 6bacd3ce82..21147fe825 100644 --- a/src/control/audio.c +++ b/src/control/audio.c @@ -36,6 +36,9 @@ static aout_instance_t *GetAOut( libvlc_instance_t *p_instance, libvlc_exception_t *p_exception ) { + if( !p_instance ) + return NULL; + aout_instance_t * p_aout = NULL; p_aout = vlc_object_find( p_instance->p_libvlc_int, VLC_OBJECT_AOUT, FIND_CHILD ); @@ -48,6 +51,269 @@ static aout_instance_t *GetAOut( libvlc_instance_t *p_instance, return p_aout; } +/***************************************** + * Get the list of available audio outputs + *****************************************/ +VLC_PUBLIC_API libvlc_audio_output_t * + libvlc_audio_output_list_get( libvlc_instance_t *p_instance, + libvlc_exception_t *p_e ) +{ + VLC_UNUSED( p_instance ); + libvlc_audio_output_t *p_list = NULL, + *p_actual = NULL, + *p_previous = NULL; + module_t **module_list = module_list_get( NULL ); + + for (size_t i = 0; module_list[i]; i++) + { + module_t *p_module = module_list[i]; + + if( module_provides( p_module, "audio output" ) ) + { + if( p_actual == NULL) + { + p_actual = ( libvlc_audio_output_t * ) + malloc( sizeof( libvlc_audio_output_t ) ); + if( p_actual == NULL ) + { + libvlc_exception_raise( p_e, "Not enough memory" ); + libvlc_audio_output_list_release( p_list ); + module_list_free( module_list ); + return NULL; + } + if( p_list == NULL ) + { + p_list = p_actual; + p_previous = p_actual; + } + } + p_actual->psz_name = strdup( module_get_name( p_module, false ) ); + p_actual->psz_description = strdup( module_get_name( p_module, true ) ); + p_actual->p_next = NULL; + if( p_previous != p_actual ) /* not first item */ + p_previous->p_next = p_actual; + p_previous = p_actual; + p_actual = p_actual->p_next; + } + } + + module_list_free( module_list ); + + return p_list; +} + +/******************************************** + * Free the list of available audio outputs + ***********************************************/ +VLC_PUBLIC_API void libvlc_audio_output_list_release( libvlc_audio_output_t *p_list ) +{ + libvlc_audio_output_t *p_actual, *p_before; + p_actual = p_list; + + while ( p_actual ) + { + free( p_actual->psz_name ); + free( p_actual->psz_description ); + p_before = p_actual; + p_actual = p_before->p_next; + free( p_before ); + } +} + + +/*********************** + * Set the audio output. + ***********************/ +VLC_PUBLIC_API int libvlc_audio_output_set( libvlc_instance_t *p_instance, + const char *psz_name ) +{ + if( module_exists( psz_name ) ) + { + config_PutPsz( p_instance->p_libvlc_int, "aout", psz_name ); + return true; + } + else + return false; +} + +/**************************** + * Get count of devices. + *****************************/ +int libvlc_audio_output_device_count( libvlc_instance_t *p_instance, + const char *psz_audio_output ) +{ + char *psz_config_name = NULL; + if( !psz_audio_output ) + return 0; + if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 ) + return 0; + + module_config_t *p_module_config = config_FindConfig( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name ); + + if( p_module_config && p_module_config->pf_update_list ) + { + vlc_value_t val; + val.psz_string = strdup( p_module_config->value.psz ); + + p_module_config->pf_update_list( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL ); + free( val.psz_string ); + free( psz_config_name ); + + return p_module_config->i_list; + } + else + free( psz_config_name ); + + + return 0; +} + +/******************************** + * Get long name of device + *********************************/ +char * libvlc_audio_output_device_longname( libvlc_instance_t *p_instance, + const char *psz_audio_output, + int i_device ) +{ + char *psz_config_name = NULL; + if( !psz_audio_output ) + return NULL; + if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 ) + return NULL; + + module_config_t *p_module_config = config_FindConfig( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name ); + + if( p_module_config ) + { + // refresh if there arent devices + if( p_module_config->i_list < 2 && p_module_config->pf_update_list ) + { + vlc_value_t val; + val.psz_string = strdup( p_module_config->value.psz ); + + p_module_config->pf_update_list( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL ); + free( val.psz_string ); + } + free( psz_config_name ); + + if( i_device >= 0 && i_device < p_module_config->i_list ) + { + if( p_module_config->ppsz_list_text[i_device] ) + return strdup( p_module_config->ppsz_list_text[i_device] ); + else + return strdup( p_module_config->ppsz_list[i_device] ); + } + } + else + free( psz_config_name ); + + return NULL; +} + +/******************************** + * Get id name of device + *********************************/ +char * libvlc_audio_output_device_id( libvlc_instance_t *p_instance, + const char *psz_audio_output, + int i_device ) +{ + char *psz_config_name = NULL; + if( !psz_audio_output ) + return NULL; + if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1) + return NULL; + + module_config_t *p_module_config = config_FindConfig( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name ); + + if( p_module_config ) + { + // refresh if there arent devices + if( p_module_config->i_list < 2 && p_module_config->pf_update_list ) + { + vlc_value_t val; + val.psz_string = strdup( p_module_config->value.psz ); + + p_module_config->pf_update_list( + VLC_OBJECT( p_instance->p_libvlc_int ), psz_config_name, val, val, NULL ); + free( val.psz_string ); + } + free( psz_config_name ); + + if( i_device >= 0 && i_device < p_module_config->i_list ) + return strdup( p_module_config->ppsz_list[i_device] ); + + } + else + free( psz_config_name ); + + return NULL; +} + +/***************************** + * Set device for using + *****************************/ +VLC_PUBLIC_API void libvlc_audio_output_device_set( libvlc_instance_t *p_instance, + const char *psz_audio_output, + const char *psz_device_id ) +{ + char *psz_config_name = NULL; + if( !psz_audio_output || !psz_device_id ) + return; + if( asprintf( &psz_config_name, "%s-audio-device", psz_audio_output ) == -1 ) + return; + config_PutPsz( p_instance->p_libvlc_int, psz_config_name, psz_device_id ); + free( psz_config_name ); +} + +/***************************************************************************** + * libvlc_audio_output_get_device_type : Get the current audio device type + *****************************************************************************/ +int libvlc_audio_output_get_device_type( libvlc_instance_t *p_instance, + libvlc_exception_t *p_e ) +{ + aout_instance_t *p_aout = GetAOut( p_instance, p_e ); + if( p_aout ) + { + vlc_value_t val; + + var_Get( p_aout, "audio-device", &val ); + vlc_object_release( p_aout ); + return val.i_int; + } + libvlc_exception_raise( p_e, "Unable to get audio output" ); + return libvlc_AudioOutputDevice_Error; +} + +/***************************************************************************** + * libvlc_audio_output_set_device_type : Set the audio device type + *****************************************************************************/ +void libvlc_audio_output_set_device_type( libvlc_instance_t *p_instance, + int device_type, + libvlc_exception_t *p_e ) +{ + aout_instance_t *p_aout = GetAOut( p_instance, p_e ); + if( p_aout ) + { + vlc_value_t val; + int i_ret = -1; + + val.i_int = (int) device_type; + i_ret = var_Set( p_aout, "audio-device", val ); + if( i_ret < 0 ) + { + libvlc_exception_raise( p_e, "Failed setting audio device" ); + vlc_object_release( p_aout ); + return; + } + + vlc_object_release( p_aout ); + } +} /***************************************************************************** * libvlc_audio_get_mute : Get the volume state, true if muted @@ -217,7 +483,7 @@ void libvlc_audio_set_track( libvlc_media_player_t *p_mi, int i_track, * libvlc_audio_get_channel : Get the current audio channel *****************************************************************************/ int libvlc_audio_get_channel( libvlc_instance_t *p_instance, - libvlc_exception_t *p_e ) + libvlc_exception_t *p_e ) { aout_instance_t *p_aout = GetAOut( p_instance, p_e ); if( p_aout ) @@ -228,13 +494,15 @@ int libvlc_audio_get_channel( libvlc_instance_t *p_instance, vlc_object_release( p_aout ); return val.i_int; } - return -1; + libvlc_exception_raise( p_e, "Unable to get audio output" ); + return libvlc_AudioChannel_Error; } /***************************************************************************** * libvlc_audio_set_channel : Set the current audio channel *****************************************************************************/ -void libvlc_audio_set_channel( libvlc_instance_t *p_instance, int i_channel, +void libvlc_audio_set_channel( libvlc_instance_t *p_instance, + int channel, libvlc_exception_t *p_e ) { aout_instance_t *p_aout = GetAOut( p_instance, p_e ); @@ -243,27 +511,12 @@ void libvlc_audio_set_channel( libvlc_instance_t *p_instance, int i_channel, vlc_value_t val; int i_ret = -1; - val.i_int = i_channel; - switch( i_channel ) - { - case AOUT_VAR_CHAN_RSTEREO: - case AOUT_VAR_CHAN_STEREO: - case AOUT_VAR_CHAN_LEFT: - case AOUT_VAR_CHAN_RIGHT: - case AOUT_VAR_CHAN_DOLBYS: - i_ret = var_Set( p_aout, "audio-channels", val ); - if( i_ret < 0 ) - { - libvlc_exception_raise( p_e, "Failed setting audio channel" ); - vlc_object_release( p_aout ); - return; - } - vlc_object_release( p_aout ); - return; /* Found */ - default: - libvlc_exception_raise( p_e, "Audio channel out of range" ); - break; - } + val.i_int = channel; + i_ret = var_Set( p_aout, "audio-channels", val ); + if( i_ret < 0 ) + libvlc_exception_raise( p_e, "Failed setting audio channel" ); + vlc_object_release( p_aout ); } + } diff --git a/src/libvlc.sym b/src/libvlc.sym index 9a39769520..759751e008 100644 --- a/src/libvlc.sym +++ b/src/libvlc.sym @@ -1,11 +1,22 @@ libvlc_add_intf +libvlc_audio_output_device_count +libvlc_audio_output_device_id +libvlc_audio_output_device_longname +libvlc_audio_output_device_set +libvlc_audio_output_get_device_type +libvlc_audio_output_list_get +libvlc_audio_output_list_release +libvlc_audio_output_set +libvlc_audio_output_set_device_type libvlc_audio_get_channel +libvlc_audio_get_device libvlc_audio_get_mute libvlc_audio_get_track libvlc_audio_get_track_count libvlc_audio_get_track_description libvlc_audio_get_volume libvlc_audio_set_channel +libvlc_audio_set_device libvlc_audio_set_mute libvlc_audio_set_track libvlc_audio_set_volume -- 2.39.2