Commit 32596ea8 authored by Mark Lee's avatar Mark Lee Committed by Jean-Baptiste Kempf

Add new API to libvlc for persistent equalizer settings.

New methods are provided to:

 - get the available equalizer presets;
 - get the available frequency bands (useful for creating a UI);
 - create a new default equalizer, or create a new equalizer from a preset;
 - release a previously created equalizer;
 - get/set preamp and individual frequency amplification values;
 - apply equalizer settings to a media player.

Equalizer settings are persistent, can be made whether media is currently playing or not, and will automatically be applied to subsequently played media.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 22532b5c
...@@ -113,6 +113,7 @@ libVLC: ...@@ -113,6 +113,7 @@ libVLC:
to replace the deprecated libvlc_audio_output_device_count, libvlc_audio_output_device_longname to replace the deprecated libvlc_audio_output_device_count, libvlc_audio_output_device_longname
and libvlc_audio_output_device_id and libvlc_audio_output_device_id
* new libvlc_log_subscribe and libvlc_log_unsubscribe function to register logging callbacks * new libvlc_log_subscribe and libvlc_log_unsubscribe function to register logging callbacks
* new audio equalizer API
Removed modules: Removed modules:
* portaudio audio output: use the native audio output instead * portaudio audio output: use the native audio output instead
......
...@@ -120,6 +120,13 @@ typedef enum libvlc_navigate_mode_t ...@@ -120,6 +120,13 @@ typedef enum libvlc_navigate_mode_t
libvlc_navigate_right libvlc_navigate_right
} libvlc_navigate_mode_t; } libvlc_navigate_mode_t;
/**
* Opaque equalizer handle.
*
* Equalizer settings can be applied to a media player.
*/
typedef struct libvlc_equalizer_t libvlc_equalizer_t;
/** /**
* Create an empty Media Player object * Create an empty Media Player object
* *
...@@ -1626,6 +1633,166 @@ LIBVLC_API int64_t libvlc_audio_get_delay( libvlc_media_player_t *p_mi ); ...@@ -1626,6 +1633,166 @@ LIBVLC_API int64_t libvlc_audio_get_delay( libvlc_media_player_t *p_mi );
*/ */
LIBVLC_API int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay ); LIBVLC_API int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay );
/**
* Get the number of equalizer presets.
*
* \return number of presets
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API unsigned libvlc_audio_equalizer_get_preset_count( void );
/**
* Get the name of a particular equalizer preset.
*
* This name can be used, for example, to prepare a preset label or menu in a user
* interface.
*
* \param u_index index of the preset, counting from zero
* \return preset name, or NULL if there is no such preset
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API const char *libvlc_audio_equalizer_get_preset_name( unsigned u_index );
/**
* Get the number of distinct frequency bands for an equalizer.
*
* \return number of frequency bands
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API unsigned libvlc_audio_equalizer_get_band_count( void );
/**
* Get a particular equalizer band frequency.
*
* This value can be used, for example, to create a label for an equalizer band control
* in a user interface.
*
* \param u_index index of the band, counting from zero
* \return equalizer band frequency (Hz), or -1 if there is no such band
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API float libvlc_audio_equalizer_get_band_frequency( unsigned u_index );
/**
* Create a new default equalizer, with all frequency values zeroed.
*
* The new equalizer can subsequently be applied to a media player by invoking
* libvlc_media_player_set_equalizer().
*
* The returned handle should be freed via libvlc_audio_equalizer_release() when
* it is no longer needed.
*
* \return opaque equalizer handle, or NULL on error
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API libvlc_equalizer_t *libvlc_audio_equalizer_new( void );
/**
* Create a new equalizer, with initial frequency values copied from an existing
* preset.
*
* The new equalizer can subsequently be applied to a media player by invoking
* libvlc_media_player_set_equalizer().
*
* The returned handle should be freed via libvlc_audio_equalizer_release() when
* it is no longer needed.
*
* \param u_index index of the preset, counting from zero
* \return opaque equalizer handle, or NULL on error
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API libvlc_equalizer_t *libvlc_audio_equalizer_new_from_preset( unsigned u_index );
/**
* Release a previously created equalizer instance.
*
* The equalizer was previously created by using libvlc_audio_equalizer_new() or
* libvlc_audio_equalizer_new_from_preset().
*
* It is safe to invoke this method with a NULL p_equalizer parameter for no effect.
*
* \param p_equalizer opaque equalizer handle, or NULL
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_audio_equalizer_release( libvlc_equalizer_t *p_equalizer );
/**
* Set a new pre-amplification value for an equalizer.
*
* The new equalizer settings are subsequently applied to a media player by invoking
* libvlc_media_player_set_equalizer().
*
* \param p_equalizer opaque equalizer handle
* \param f_preamp preamp value (-20.0 to 20.0 Hz)
* \return zero on success, -1 on error
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API int libvlc_audio_equalizer_set_preamp( libvlc_equalizer_t *p_equalizer, float f_preamp );
/**
* Get the current pre-amplification value from an equalizer.
*
* \param p_equalizer opaque equalizer handle
* \return preamp value (Hz)
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API float libvlc_audio_equalizer_get_preamp( libvlc_equalizer_t *p_equalizer );
/**
* Set a new amplification value for a particular equalizer frequency band.
*
* The new equalizer settings are subsequently applied to a media player by invoking
* libvlc_media_player_set_equalizer().
*
* \param p_equalizer opaque equalizer handle
* \param f_amp amplification value (-20.0 to 20.0 Hz)
* \param u_band index, counting from zero, of the frequency band to set
* \return zero on success, -1 on error
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API int libvlc_audio_equalizer_set_amp_at_index( libvlc_equalizer_t *p_equalizer, float f_amp, unsigned u_band );
/**
* Get the amplification value for a particular equalizer frequency band.
*
* \param p_equalizer opaque equalizer handle
* \param u_band index, counting from zero, of the frequency band to get
* \return amplification value (Hz); zero if there is no such frequency band
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API float libvlc_audio_equalizer_get_amp_at_index( libvlc_equalizer_t *p_equalizer, unsigned u_band );
/**
* Apply new equalizer settings to a media player.
*
* The equalizer is first created by invoking libvlc_audio_equalizer_new() or
* libvlc_audio_equalizer_new_from_preset().
*
* It is possible to apply new equalizer settings to a media player whether the media
* player is currently playing media or not.
*
* Invoking this method will immediately apply the new equalizer settings to the audio
* output of the currently playing media if there is any.
*
* If there is no currently playing media, the new equalizer settings will be applied
* later if and when new media is played.
*
* Equalizer settings will automatically be applied to subsequently played media.
*
* To disable the equalizer for a media player invoke this method passing NULL for the
* p_equalizer parameter.
*
* The media player does not keep a reference to the supplied equalizer so it is safe
* for an application to release the equalizer reference any time after this method
* returns.
*
* \param p_mi opaque media player handle
* \param p_equalizer opaque equalizer handle, or NULL to disable the equalizer for this media player
* \return zero on success, -1 on error
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API int libvlc_media_player_set_equalizer( libvlc_media_player_t *p_mi, libvlc_equalizer_t *p_equalizer );
/** @} audio */ /** @} audio */
/** @} media_player */ /** @} media_player */
......
...@@ -449,3 +449,152 @@ int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay ) ...@@ -449,3 +449,152 @@ int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay )
} }
return ret; return ret;
} }
/*****************************************************************************
* libvlc_audio_equalizer_get_preset_count : Get the number of equalizer presets
*****************************************************************************/
unsigned libvlc_audio_equalizer_get_preset_count( void )
{
return NB_PRESETS;
}
/*****************************************************************************
* libvlc_audio_equalizer_get_preset_name : Get the name for a preset
*****************************************************************************/
const char *libvlc_audio_equalizer_get_preset_name( unsigned u_index )
{
if ( u_index >= NB_PRESETS )
return NULL;
return preset_list_text[ u_index ];
}
/*****************************************************************************
* libvlc_audio_equalizer_get_band_count : Get the number of equalizer frequency bands
*****************************************************************************/
unsigned libvlc_audio_equalizer_get_band_count( void )
{
return EQZ_BANDS_MAX;
}
/*****************************************************************************
* libvlc_audio_equalizer_get_band_frequency : Get the frequency for a band
*****************************************************************************/
float libvlc_audio_equalizer_get_band_frequency( unsigned u_index )
{
if ( u_index >= EQZ_BANDS_MAX )
return -1.f;
return f_vlc_frequency_table_10b[ u_index ];
}
/*****************************************************************************
* libvlc_audio_equalizer_new : Create a new audio equalizer with zeroed values
*****************************************************************************/
libvlc_equalizer_t *libvlc_audio_equalizer_new( void )
{
libvlc_equalizer_t *p_equalizer;
p_equalizer = malloc( sizeof( *p_equalizer ) );
if ( unlikely( p_equalizer == NULL ) )
return NULL;
p_equalizer->f_preamp = 0.f;
for ( unsigned i = 0; i < EQZ_BANDS_MAX; i++ )
p_equalizer->f_amp[ i ] = 0.f;
return p_equalizer;
}
/*****************************************************************************
* libvlc_audio_equalizer_new_from_preset : Create a new audio equalizer based on a preset
*****************************************************************************/
libvlc_equalizer_t *libvlc_audio_equalizer_new_from_preset( unsigned u_index )
{
libvlc_equalizer_t *p_equalizer;
if ( u_index >= NB_PRESETS )
return NULL;
p_equalizer = malloc( sizeof( *p_equalizer ) );
if ( unlikely( p_equalizer == NULL ) )
return NULL;
p_equalizer->f_preamp = eqz_preset_10b[ u_index ].f_preamp;
for ( unsigned i = 0; i < EQZ_BANDS_MAX; i++ )
p_equalizer->f_amp[ i ] = eqz_preset_10b[ u_index ].f_amp[ i ];
return p_equalizer;
}
/*****************************************************************************
* libvlc_audio_equalizer_release : Release a previously created equalizer
*****************************************************************************/
void libvlc_audio_equalizer_release( libvlc_equalizer_t *p_equalizer )
{
free( p_equalizer );
}
/*****************************************************************************
* libvlc_audio_equalizer_set_preamp : Set the preamp value for an equalizer
*****************************************************************************/
int libvlc_audio_equalizer_set_preamp( libvlc_equalizer_t *p_equalizer, float f_preamp )
{
if ( !p_equalizer )
return -1;
if ( f_preamp < -20.0f )
f_preamp = -20.0f;
else if ( f_preamp > 20.0f )
f_preamp = 20.0f;
p_equalizer->f_preamp = f_preamp;
return 0;
}
/*****************************************************************************
* libvlc_audio_equalizer_get_preamp : Get the preamp value for an equalizer
*****************************************************************************/
float libvlc_audio_equalizer_get_preamp( libvlc_equalizer_t *p_equalizer )
{
if ( !p_equalizer )
return 0.f;
return p_equalizer->f_preamp;
}
/*****************************************************************************
* libvlc_audio_equalizer_set_amp_at_index : Set the amplification value for an equalizer band
*****************************************************************************/
int libvlc_audio_equalizer_set_amp_at_index( libvlc_equalizer_t *p_equalizer, float f_amp, unsigned u_band )
{
if ( !p_equalizer )
return -1;
if ( u_band >= EQZ_BANDS_MAX )
return -1;
if ( f_amp < -20.0f )
f_amp = -20.0f;
else if ( f_amp > 20.0f )
f_amp = 20.0f;
p_equalizer->f_amp[ u_band ] = f_amp;
return 0;
}
/*****************************************************************************
* libvlc_audio_equalizer_get_amp_at_index : Get the amplification value for an equalizer band
*****************************************************************************/
float libvlc_audio_equalizer_get_amp_at_index( libvlc_equalizer_t *p_equalizer, unsigned u_band )
{
if ( !p_equalizer )
return 0.f;
if ( u_band >= EQZ_BANDS_MAX )
return 0.f;
return p_equalizer->f_amp[ u_band ];
}
...@@ -3,6 +3,17 @@ libvlc_clearerr ...@@ -3,6 +3,17 @@ libvlc_clearerr
libvlc_printerr libvlc_printerr
libvlc_vprinterr libvlc_vprinterr
libvlc_add_intf libvlc_add_intf
libvlc_audio_equalizer_get_amp_at_index
libvlc_audio_equalizer_get_band_count
libvlc_audio_equalizer_get_band_frequency
libvlc_audio_equalizer_get_preamp
libvlc_audio_equalizer_get_preset_count
libvlc_audio_equalizer_get_preset_name
libvlc_audio_equalizer_new
libvlc_audio_equalizer_new_from_preset
libvlc_audio_equalizer_release
libvlc_audio_equalizer_set_amp_at_index
libvlc_audio_equalizer_set_preamp
libvlc_audio_output_device_count libvlc_audio_output_device_count
libvlc_audio_output_device_id libvlc_audio_output_device_id
libvlc_audio_output_device_list_get libvlc_audio_output_device_list_get
...@@ -150,6 +161,7 @@ libvlc_media_player_release ...@@ -150,6 +161,7 @@ libvlc_media_player_release
libvlc_media_player_retain libvlc_media_player_retain
libvlc_media_player_set_agl libvlc_media_player_set_agl
libvlc_media_player_set_chapter libvlc_media_player_set_chapter
libvlc_media_player_set_equalizer
libvlc_media_player_set_hwnd libvlc_media_player_set_hwnd
libvlc_media_player_set_media libvlc_media_player_set_media
libvlc_media_player_set_nsobject libvlc_media_player_set_nsobject
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <vlc_input.h> #include <vlc_input.h>
#include <vlc_vout.h> #include <vlc_vout.h>
#include <vlc_keys.h> #include <vlc_keys.h>
#include <vlc_aout_intf.h>
#include "libvlc_internal.h" #include "libvlc_internal.h"
#include "media_internal.h" // libvlc_media_set_state() #include "media_internal.h" // libvlc_media_set_state()
...@@ -482,6 +483,9 @@ libvlc_media_player_new( libvlc_instance_t *instance ) ...@@ -482,6 +483,9 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
var_Create (mp, "equalizer-preamp", VLC_VAR_FLOAT);
var_Create (mp, "equalizer-bands", VLC_VAR_STRING);
mp->p_md = NULL; mp->p_md = NULL;
mp->state = libvlc_NothingSpecial; mp->state = libvlc_NothingSpecial;
mp->p_libvlc_instance = instance; mp->p_libvlc_instance = instance;
...@@ -746,6 +750,10 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi ) ...@@ -746,6 +750,10 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi )
} }
p_mi->input.p_thread = p_input_thread; p_mi->input.p_thread = p_input_thread;
unlock_input(p_mi); unlock_input(p_mi);
if( strlen( var_GetString( p_mi, "equalizer-bands" ) ) > 0 )
aout_EnableFilter( p_mi, "equalizer", true );
return 0; return 0;
} }
...@@ -1409,3 +1417,33 @@ void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi ) ...@@ -1409,3 +1417,33 @@ void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi )
vlc_object_release( p_input_thread ); vlc_object_release( p_input_thread );
} }
} }
int libvlc_media_player_set_equalizer( libvlc_media_player_t *p_mi, libvlc_equalizer_t *p_equalizer )
{
if ( !p_equalizer )
{
aout_EnableFilter( p_mi, "equalizer", false );
var_SetString( p_mi, "equalizer-bands", NULL );
return 0;
}
var_SetFloat( p_mi, "equalizer-preamp", p_equalizer->f_preamp );
char *psz_bands = NULL;
for ( int i = 0; i < EQZ_BANDS_MAX; i++ )
{
char *psz;
if ( asprintf( &psz, "%s %.07f", psz_bands ? psz_bands : "", p_equalizer->f_amp[i] ) == -1 )
{
free( psz_bands );
return -1;
}
free( psz_bands );
psz_bands = psz;
}
var_SetString( p_mi, "equalizer-bands", psz_bands );
free( psz_bands );
aout_EnableFilter( p_mi, "equalizer", true );
return 0;
}
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <vlc/libvlc_media.h> #include <vlc/libvlc_media.h>
#include <vlc_input.h> #include <vlc_input.h>
#include "../modules/audio_filter/equalizer_presets.h"
struct libvlc_media_player_t struct libvlc_media_player_t
{ {
VLC_COMMON_MEMBERS VLC_COMMON_MEMBERS
...@@ -62,4 +64,13 @@ libvlc_track_description_t * libvlc_get_track_description( ...@@ -62,4 +64,13 @@ libvlc_track_description_t * libvlc_get_track_description(
libvlc_media_player_t *p_mi, libvlc_media_player_t *p_mi,
const char *psz_variable ); const char *psz_variable );
/**
* Internal equalizer structure.
*/
struct libvlc_equalizer_t
{
float f_preamp;
float f_amp[EQZ_BANDS_MAX];
};
#endif #endif
...@@ -232,17 +232,6 @@ typedef struct ...@@ -232,17 +232,6 @@ typedef struct
} eqz_config_t; } eqz_config_t;
/* The frequency tables */
static const float f_vlc_frequency_table_10b[EQZ_BANDS_MAX] =
{
60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000,
};
static const float f_iso_frequency_table_10b[EQZ_BANDS_MAX] =
{
31.25, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000,
};
/* Equalizer coefficient calculation function based on equ-xmms */ /* Equalizer coefficient calculation function based on equ-xmms */
static void EqzCoeffs( int i_rate, float f_octave_percent, static void EqzCoeffs( int i_rate, float f_octave_percent,
bool b_use_vlc_freqs, bool b_use_vlc_freqs,
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/ *****************************************************************************/
#ifndef _EQUALIZER_PRESETS_H
#define _EQUALIZER_PRESETS_H 1
/***************************************************************************** /*****************************************************************************
* Equalizer presets * Equalizer presets
*****************************************************************************/ *****************************************************************************/
...@@ -30,6 +33,17 @@ ...@@ -30,6 +33,17 @@
#define EQZ_BANDS_MAX 10 #define EQZ_BANDS_MAX 10
/* The frequency tables */
static const float f_vlc_frequency_table_10b[EQZ_BANDS_MAX] =
{
60, 170, 310, 600, 1000, 3000, 6000, 12000, 14000, 16000,
};
static const float f_iso_frequency_table_10b[EQZ_BANDS_MAX] =
{
31.25, 62.5, 125, 250, 500, 1000, 2000, 4000, 8000, 16000,
};
#define NB_PRESETS 18 #define NB_PRESETS 18
static const char *const preset_list[NB_PRESETS] = { static const char *const preset_list[NB_PRESETS] = {
"flat", "classical", "club", "dance", "fullbass", "fullbasstreble", "flat", "classical", "club", "dance", "fullbass", "fullbasstreble",
...@@ -132,3 +146,5 @@ static const eqz_preset_t eqz_preset_10b[NB_PRESETS] = ...@@ -132,3 +146,5 @@ static const eqz_preset_t eqz_preset_10b[NB_PRESETS] =
{ 8, 5.6, -1.11022e-15, -5.6, -4.8, -1.11022e-15, 8, 9.6, 9.6, 8.8 } { 8, 5.6, -1.11022e-15, -5.6, -4.8, -1.11022e-15, 8, 9.6, 9.6, 8.8 }
}, },
}; };
#endif
...@@ -177,6 +177,15 @@ audio_output_t *aout_New( vlc_object_t * p_parent ) ...@@ -177,6 +177,15 @@ audio_output_t *aout_New( vlc_object_t * p_parent )
&val, &text); &val, &text);
} }
if (var_Type (p_parent, "equalizer-bands"))
{
var_Create (aout, "equalizer-preamp", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT);
var_Create (aout, "equalizer-bands", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
var_AddCallback (p_parent, "equalizer-preamp", var_Copy, aout);
var_AddCallback (p_parent, "equalizer-bands", var_Copy, aout);
}
return aout; return aout;
} }
...@@ -190,6 +199,13 @@ void aout_Destroy (audio_output_t *aout) ...@@ -190,6 +199,13 @@ void aout_Destroy (audio_output_t *aout)
var_DelCallback (aout, "mute", var_Copy, aout->p_parent); var_DelCallback (aout, "mute", var_Copy, aout->p_parent);
var_SetFloat (aout, "volume", -1.f); var_SetFloat (aout, "volume", -1.f);
var_DelCallback (aout, "volume", var_Copy, aout->p_parent); var_DelCallback (aout, "volume", var_Copy, aout->p_parent);
if (var_Type (aout->p_parent, "equalizer-bands"))
{
var_DelCallback (aout->p_parent, "equalizer-preamp", var_Copy, aout);
var_DelCallback (aout->p_parent, "equalizer-bands", var_Copy, aout);
}
vlc_object_release (aout); vlc_object_release (aout);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment