Changeset d20dd24295a3f43ad2cdec0fcd8a83793cb45bde
- Timestamp:
- 06/17/07 15:54:20 (1 year ago)
- git-parent:
- Files:
-
- include/vlc_aout.h (modified) (1 diff)
- include/vlc_es.h (modified) (4 diffs)
- include/vlc_input.h (modified) (1 diff)
- include/vlc_meta.h (modified) (1 diff)
- modules/audio_mixer/float32.c (modified) (3 diffs)
- src/audio_output/aout_internal.h (modified) (1 diff)
- src/audio_output/dec.c (modified) (5 diffs)
- src/audio_output/input.c (modified) (6 diffs)
- src/input/decoder.c (modified) (2 diffs)
- src/libvlc-module.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
include/vlc_aout.h
r70a8bb9 rd20dd24 271 271 /* Mixer information */ 272 272 byte_t * p_first_byte_to_mix; 273 audio_replay_gain_t replay_gain; 274 float f_multiplier; 273 275 274 276 /* If b_restart == 1, the input pipeline will be re-created. */ include/vlc_es.h
r9ab64bc rd20dd24 46 46 47 47 /** 48 * audio replay gain description 49 */ 50 #define AUDIO_REPLAY_GAIN_MAX (2) 51 #define AUDIO_REPLAY_GAIN_TRACK (0) 52 #define AUDIO_REPLAY_GAIN_ALBUM (1) 53 typedef struct 54 { 55 /* true if we have the peak value */ 56 vlc_bool_t pb_peak[AUDIO_REPLAY_GAIN_MAX]; 57 /* peak value where 1.0 means full sample value */ 58 float pf_peak[AUDIO_REPLAY_GAIN_MAX]; 59 60 /* true if we have the gain value */ 61 vlc_bool_t pb_gain[AUDIO_REPLAY_GAIN_MAX]; 62 /* gain value in dB */ 63 float pf_gain[AUDIO_REPLAY_GAIN_MAX]; 64 } audio_replay_gain_t; 65 66 /** 48 67 * audio format description 49 68 */ … … 174 193 extra_languages_t *p_extra_languages; 175 194 176 audio_format_t audio; 195 audio_format_t audio; 196 audio_replay_gain_t audio_replay_gain; 177 197 video_format_t video; 178 198 subs_format_t subs; … … 209 229 210 230 memset( &fmt->audio, 0, sizeof(audio_format_t) ); 231 memset( &fmt->audio_replay_gain, 0, sizeof(audio_replay_gain_t) ); 211 232 memset( &fmt->video, 0, sizeof(video_format_t) ); 212 233 memset( &fmt->subs, 0, sizeof(subs_format_t) ); … … 268 289 { 269 290 if( fmt->psz_language ) free( fmt->psz_language ); 270 fmt->psz_language = NULL;271 291 272 292 if( fmt->psz_description ) free( fmt->psz_description ); 273 fmt->psz_description = NULL;274 293 275 294 if( fmt->i_extra > 0 ) free( fmt->p_extra ); 276 fmt->i_extra = 0;277 fmt->p_extra = NULL;278 295 279 296 if( fmt->video.p_palette ) 280 297 free( fmt->video.p_palette ); 281 fmt->video.p_palette = NULL;282 298 283 299 if( fmt->subs.psz_encoding ) free( fmt->subs.psz_encoding ); 284 fmt->subs.psz_encoding = NULL; 285 286 if( fmt->i_extra_languages && fmt->p_extra_languages ) { 287 int i = 0; 288 while( i < fmt->i_extra_languages ) { 300 301 if( fmt->i_extra_languages > 0 && fmt->p_extra_languages ) 302 { 303 int i; 304 for( i = 0; i < fmt->i_extra_languages; i++ ) 305 { 289 306 if( fmt->p_extra_languages[i].psz_language ) 290 307 free( fmt->p_extra_languages[i].psz_language ); 291 308 if( fmt->p_extra_languages[i].psz_description ) 292 309 free( fmt->p_extra_languages[i].psz_description ); 293 i++;294 310 } 295 311 free(fmt->p_extra_languages); 296 312 } 297 fmt->i_extra_languages = 0; 298 fmt->p_extra_languages = NULL; 313 314 /* es_format_Clean can be called multiple times */ 315 memset( fmt, 0, sizeof(*fmt) ); 299 316 } 300 317 #endif include/vlc_input.h
ra8a47dd rd20dd24 197 197 198 198 /***************************************************************************** 199 * Meta data helpers 200 *****************************************************************************/ 201 static inline void vlc_audio_replay_gain_MergeFromMeta( audio_replay_gain_t *p_dst, 202 const vlc_meta_t *p_meta ) 203 { 204 int i; 205 if( !p_meta ) 206 return; 207 208 for( i = 0; i < p_meta->i_extra; i++ ) 209 { 210 const char *psz_name = p_meta->ppsz_extra_name[i]; 211 const char *psz_value = p_meta->ppsz_extra_value[i]; 212 213 if( !strcasecmp( psz_name, "REPLAYGAIN_TRACK_GAIN" ) || 214 !strcasecmp( psz_name, "RG_RADIO" ) ) 215 { 216 p_dst->pb_gain[AUDIO_REPLAY_GAIN_TRACK] = VLC_TRUE; 217 p_dst->pf_gain[AUDIO_REPLAY_GAIN_TRACK] = atof( psz_value ); 218 } 219 else if( !strcasecmp( psz_name, "REPLAYGAIN_TRACK_PEAK" ) || 220 !strcasecmp( psz_name, "RG_PEAK" ) ) 221 { 222 p_dst->pb_peak[AUDIO_REPLAY_GAIN_TRACK] = VLC_TRUE; 223 p_dst->pf_peak[AUDIO_REPLAY_GAIN_TRACK] = atof( psz_value ); 224 } 225 else if( !strcasecmp( psz_name, "REPLAYGAIN_ALBUM_GAIN" ) || 226 !strcasecmp( psz_name, "RG_AUDIOPHILE" ) ) 227 { 228 p_dst->pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = VLC_TRUE; 229 p_dst->pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = atof( psz_value ); 230 } 231 else if( !strcasecmp( psz_name, "REPLAYGAIN_ALBUM_PEAK" ) ) 232 { 233 p_dst->pb_peak[AUDIO_REPLAY_GAIN_ALBUM] = VLC_TRUE; 234 p_dst->pf_peak[AUDIO_REPLAY_GAIN_ALBUM] = atof( psz_value ); 235 } 236 } 237 } 238 239 /***************************************************************************** 199 240 * Seek point: (generalisation of chapters) 200 241 *****************************************************************************/ include/vlc_meta.h
r8919d21 rd20dd24 210 210 for( j = 0; j < dst->i_extra; j++ ) 211 211 { 212 if( !strcmp( dst->ppsz_extra_name[ i], src->ppsz_extra_name[i] ) )212 if( !strcmp( dst->ppsz_extra_name[j], src->ppsz_extra_name[i] ) ) 213 213 { 214 free( dst->ppsz_extra_value[ i] );215 dst->ppsz_extra_value[ i] = strdup( src->ppsz_extra_value[i] );214 free( dst->ppsz_extra_value[j] ); 215 dst->ppsz_extra_value[j] = strdup( src->ppsz_extra_value[i] ); 216 216 break; 217 217 } 218 if( j >= dst->i_extra )219 vlc_meta_AddExtra( dst, src->ppsz_extra_name[i], src->ppsz_extra_value[i] );220 218 } 219 if( j >= dst->i_extra ) 220 vlc_meta_AddExtra( dst, src->ppsz_extra_name[i], src->ppsz_extra_value[i] ); 221 221 } 222 222 } modules/audio_mixer/float32.c
rd3fe7f2 rd20dd24 61 61 } 62 62 63 /* Use the trivial mixer when we can */ 63 64 if ( p_aout->i_nb_inputs == 1 && p_aout->mixer.f_multiplier == 1.0 ) 64 65 { 65 /* Tell the trivial mixer to go for it. */ 66 return -1; 66 int i; 67 for( i = 0; i < p_aout->i_nb_inputs; i++ ) 68 { 69 if( p_aout->pp_inputs[i]->f_multiplier != 1.0 ) 70 break; 71 } 72 if( i >= p_aout->i_nb_inputs ) 73 return -1; 67 74 } 68 75 69 76 p_aout->mixer.pf_do_work = DoWork; 70 71 77 return 0; 72 78 } … … 110 116 static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) 111 117 { 112 int i_nb_inputs = p_aout->i_nb_inputs; 113 float f_multiplier = p_aout->mixer.f_multiplier; 118 const int i_nb_inputs = p_aout->i_nb_inputs; 119 const float f_multiplier_global = p_aout->mixer.f_multiplier; 120 const int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer ); 114 121 int i_input; 115 int i_nb_channels = aout_FormatNbChannels( &p_aout->mixer.mixer );116 122 117 123 for ( i_input = 0; i_input < i_nb_inputs; i_input++ ) … … 119 125 int i_nb_words = p_buffer->i_nb_samples * i_nb_channels; 120 126 aout_input_t * p_input = p_aout->pp_inputs[i_input]; 127 float f_multiplier = f_multiplier_global * p_input->f_multiplier; 128 121 129 float * p_out = (float *)p_buffer->p_buffer; 122 130 float * p_in = (float *)p_input->p_first_byte_to_mix; src/audio_output/aout_internal.h
r70a8bb9 rd20dd24 125 125 126 126 /* From dec.c */ 127 #define aout_DecNew(a, b, c ) __aout_DecNew(VLC_OBJECT(a), b, c)128 aout_input_t * __aout_DecNew( vlc_object_t *, aout_instance_t **, audio_sample_format_t * );127 #define aout_DecNew(a, b, c, d) __aout_DecNew(VLC_OBJECT(a), b, c, d) 128 aout_input_t * __aout_DecNew( vlc_object_t *, aout_instance_t **, audio_sample_format_t *, audio_replay_gain_t * ); 129 129 int aout_DecDelete ( aout_instance_t *, aout_input_t * ); 130 130 aout_buffer_t * aout_DecNewBuffer( aout_instance_t *, aout_input_t *, size_t ); src/audio_output/dec.c
r70a8bb9 rd20dd24 46 46 *****************************************************************************/ 47 47 static aout_input_t * DecNew( vlc_object_t * p_this, aout_instance_t * p_aout, 48 audio_sample_format_t * p_format ) 48 audio_sample_format_t *p_format, 49 audio_replay_gain_t *p_replay_gain ) 49 50 { 50 51 aout_input_t * p_input; … … 83 84 goto error; 84 85 } 86 memset( p_input, 0, sizeof(aout_input_t) ); 85 87 86 88 vlc_mutex_init( p_aout, &p_input->lock ); … … 91 93 memcpy( &p_input->input, p_format, 92 94 sizeof(audio_sample_format_t) ); 95 if( p_replay_gain ) 96 p_input->replay_gain = *p_replay_gain; 93 97 94 98 p_aout->pp_inputs[p_aout->i_nb_inputs] = p_input; … … 167 171 aout_input_t * __aout_DecNew( vlc_object_t * p_this, 168 172 aout_instance_t ** pp_aout, 169 audio_sample_format_t * p_format ) 173 audio_sample_format_t * p_format, 174 audio_replay_gain_t *p_replay_gain ) 170 175 { 171 176 if ( *pp_aout == NULL ) … … 192 197 } 193 198 194 return DecNew( p_this, *pp_aout, p_format );199 return DecNew( p_this, *pp_aout, p_format, p_replay_gain ); 195 200 } 196 201 src/audio_output/input.c
r3b7381f rd20dd24 31 31 #include <stdlib.h> /* calloc(), malloc(), free() */ 32 32 #include <string.h> 33 #include <math.h> 33 34 34 35 #include <vlc_input.h> /* for input_thread_t and i_pts_delay */ … … 52 53 static int EqualizerCallback( vlc_object_t *, char const *, 53 54 vlc_value_t, vlc_value_t, void * ); 54 55 static int ReplayGainCallback( vlc_object_t *, char const *, 56 vlc_value_t, vlc_value_t, void * ); 57 static void ReplayGainSelect( aout_instance_t *, aout_input_t * ); 55 58 /***************************************************************************** 56 59 * aout_InputNew : allocate a new input and rework the filter pipeline … … 161 164 text.psz_string = _("Audio visualizations"); 162 165 var_Change( p_aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL ); 166 } 167 168 if( var_Type( p_aout, "audio-replay-gain-mode" ) == 0 ) 169 { 170 module_config_t *p_config; 171 int i; 172 173 p_config = config_FindConfig( VLC_OBJECT(p_aout), "audio-replay-gain-mode" ); 174 if( p_config && p_config->i_list ) 175 { 176 var_Create( p_aout, "audio-replay-gain-mode", 177 VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 178 179 text.psz_string = _("Replay gain"); 180 var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_SETTEXT, &text, NULL ); 181 182 for( i = 0; i < p_config->i_list; i++ ) 183 { 184 val.psz_string = (char *)p_config->ppsz_list[i]; 185 text.psz_string = (char *)p_config->ppsz_list_text[i]; 186 var_Change( p_aout, "audio-replay-gain-mode", VLC_VAR_ADDCHOICE, 187 &val, &text ); 188 } 189 190 var_AddCallback( p_aout, "audio-replay-gain-mode", ReplayGainCallback, NULL ); 191 } 192 } 193 if( var_Type( p_aout, "audio-replay-gain-preamp" ) == 0 ) 194 { 195 var_Create( p_aout, "audio-replay-gain-preamp", 196 VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 197 } 198 if( var_Type( p_aout, "audio-replay-gain-default" ) == 0 ) 199 { 200 var_Create( p_aout, "audio-replay-gain-default", 201 VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); 202 } 203 if( var_Type( p_aout, "audio-replay-gain-peak-protection" ) == 0 ) 204 { 205 var_Create( p_aout, "audio-replay-gain-peak-protection", 206 VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); 163 207 } 164 208 … … 367 411 * p_input->input.i_rate 368 412 / p_input->input.i_frame_length) ); 413 414 ReplayGainSelect( p_aout, p_input ); 415 369 416 /* Success */ 370 417 p_input->b_error = VLC_FALSE; … … 659 706 var_Destroy( p_aout, "audio-visual" ); 660 707 708 var_Destroy( p_aout, "audio-replay-gain-mode" ); 709 var_Destroy( p_aout, "audio-replay-gain-default" ); 710 var_Destroy( p_aout, "audio-replay-gain-preamp" ); 711 var_Destroy( p_aout, "audio-replay-gain-peak-protection" ); 712 661 713 /* error flag */ 662 714 p_input->b_error = 1; … … 818 870 return VLC_SUCCESS; 819 871 } 872 873 static int ReplayGainCallback( vlc_object_t *p_this, char const *psz_cmd, 874 vlc_value_t oldval, vlc_value_t newval, void *p_data ) 875 { 876 aout_instance_t *p_aout = (aout_instance_t *)p_this; 877 int i; 878 879 vlc_mutex_lock( &p_aout->mixer_lock ); 880 for( i = 0; i < p_aout->i_nb_inputs; i++ ) 881 ReplayGainSelect( p_aout, p_aout->pp_inputs[i] ); 882 vlc_mutex_unlock( &p_aout->mixer_lock ); 883 884 return VLC_SUCCESS; 885 } 886 887 static void ReplayGainSelect( aout_instance_t *p_aout, aout_input_t *p_input ) 888 { 889 char *psz_replay_gain = var_GetString( p_aout, "audio-replay-gain-mode" ); 890 int i_mode; 891 int i_use; 892 float f_gain; 893 894 p_input->f_multiplier = 1.0; 895 896 if( !psz_replay_gain ) 897 return; 898 899 /* Find select mode */ 900 if( !strcmp( psz_replay_gain, "track" ) ) 901 i_mode = AUDIO_REPLAY_GAIN_TRACK; 902 else if( !strcmp( psz_replay_gain, "album" ) ) 903 i_mode = AUDIO_REPLAY_GAIN_ALBUM; 904 else 905 i_mode = AUDIO_REPLAY_GAIN_MAX; 906 907 /* If the select mode is not available, prefer the other one */ 908 i_use = i_mode; 909 if( i_use != AUDIO_REPLAY_GAIN_MAX && !p_input->replay_gain.pb_gain[i_use] ) 910 { 911 for( i_use = 0; i_use < AUDIO_REPLAY_GAIN_MAX; i_use++ ) 912 { 913 if( p_input->replay_gain.pb_gain[i_use] ) 914 break; 915 } 916 } 917 918 /* */ 919 if( i_use != AUDIO_REPLAY_GAIN_MAX ) 920 f_gain = p_input->replay_gain.pf_gain[i_use] + var_GetFloat( p_aout, "audio-replay-gain-preamp" ); 921 else if( i_mode != AUDIO_REPLAY_GAIN_MAX ) 922 f_gain = var_GetFloat( p_aout, "audio-replay-gain-default" ); 923 else 924 f_gain = 0.0; 925 p_input->f_multiplier = pow( 10.0, f_gain / 20.0 ); 926 927 /* */ 928 if( p_input->replay_gain.pb_peak[i_use] && 929 var_GetBool( p_aout, "audio-replay-gain-peak-protection" ) && 930 p_input->replay_gain.pf_peak[i_use] * p_input->f_multiplier > 1.0 ) 931 { 932 p_input->f_multiplier = 1.0f / p_input->replay_gain.pf_peak[i_use]; 933 } 934 935 free( psz_replay_gain ); 936 } 937 src/input/decoder.c
r954866c rd20dd24 416 416 } 417 417 418 /* Copy ourself the input replay gain */ 419 if( fmt->i_cat == AUDIO_ES ) 420 { 421 int i; 422 for( i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ ) 423 { 424 if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] ) 425 { 426 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i]; 427 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i]; 428 } 429 if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] ) 430 { 431 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i]; 432 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i]; 433 } 434 } 435 } 418 436 return p_dec; 419 437 } … … 887 905 888 906 p_sys->p_aout_input = 889 aout_DecNew( p_dec, &p_sys->p_aout, &format );907 aout_DecNew( p_dec, &p_sys->p_aout, &format, &p_dec->fmt_out.audio_replay_gain ); 890 908 if( p_sys->p_aout_input == NULL ) 891 909 { src/libvlc-module.c
rb271b9f rd20dd24 220 220 #define AUDIO_VISUAL_LONGTEXT N_( \ 221 221 "This adds visualization modules (spectrum analyzer, etc.).") 222 223 224 #define AUDIO_REPLAY_GAIN_MODE_TEXT N_( \ 225 "Replay gain mode" ) 226 #define AUDIO_REPLAY_GAIN_MODE_LONGTEXT N_( \ 227 "Select the replay gain mode" ) 228 #define AUDIO_REPLAY_GAIN_PREAMP_TEXT N_( \ 229 "Replay preamp" ) 230 #define AUDIO_REPLAY_GAIN_PREAMP_LONGTEXT N_( \ 231 "This allows you to change the default target level (89 dB) " \ 232 "for stream with replay gain information" ) 233 #define AUDIO_REPLAY_GAIN_DEFAULT_TEXT N_( \ 234 "Default replay gain" ) 235 #define AUDIO_REPLAY_GAIN_DEFAULT_LONGTEXT N_( \ 236 "This is the gain used for stream without replay gain information" ) 237 #define AUDIO_REPLAY_GAIN_PEAK_PROTECTION_TEXT N_( \ 238 "Peak protection" ) 239 #define AUDIO_REPLAY_GAIN_PEAK_PROTECTION_LONGTEXT N_( \ 240 "Protect against sound clipping" ) 241 242 static const char *ppsz_replay_gain_mode[] = { "none", "track", "album" }; 243 static const char *ppsz_replay_gain_mode_text[] = { N_("None"), N_("Track"), N_("Album") }; 222 244 223 245 /***************************************************************************** … … 1293 1315 add_integer( "audio-desync", 0, NULL, DESYNC_TEXT, 1294 1316 DESYNC_LONGTEXT, VLC_TRUE ); 1317 1318 /* FIXME TODO create a subcat replay gain ? */ 1319 add_string( "audio-replay-gain-mode", ppsz_replay_gain_mode[0], NULL, AUDIO_REPLAY_GAIN_MODE_TEXT, 1320 AUDIO_REPLAY_GAIN_MODE_LONGTEXT, VLC_FALSE ); 1321 change_string_list( ppsz_replay_gain_mode, ppsz_replay_gain_mode_text, 0 ); 1322 add_float( "audio-replay-gain-preamp", 0.0, NULL, 1323 AUDIO_REPLAY_GAIN_PREAMP_TEXT, AUDIO_REPLAY_GAIN_PREAMP_LONGTEXT, VLC_FALSE ); 1324 add_float( "audio-replay-gain-default", -7.0, NULL, 1325 AUDIO_REPLAY_GAIN_DEFAULT_TEXT, AUDIO_REPLAY_GAIN_DEFAULT_LONGTEXT, VLC_FALSE ); 1326 add_bool( "audio-replay-gain-peak-protection", VLC_TRUE, NULL, 1327 AUDIO_REPLAY_GAIN_PEAK_PROTECTION_TEXT, AUDIO_REPLAY_GAIN_PEAK_PROTECTION_LONGTEXT, VLC_TRUE ); 1328 1295 1329 set_subcategory( SUBCAT_AUDIO_AOUT ); 1296 1330 add_module( "aout", "audio output", NULL, NULL, AOUT_TEXT, AOUT_LONGTEXT,
