+ p_config = config_FindConfig( VLC_OBJECT(p_aout), "equalizer-preset" );
+ if( p_config && p_config->i_list )
+ {
+ var_Create( p_aout, "equalizer",
+ VLC_VAR_STRING | VLC_VAR_HASCHOICE );
+ text.psz_string = _("Equalizer");
+ var_Change( p_aout, "equalizer", VLC_VAR_SETTEXT, &text, NULL );
+
+ val.psz_string = ""; text.psz_string = _("Disable");
+ var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE, &val, &text );
+
+ for( i = 0; i < p_config->i_list; i++ )
+ {
+ val.psz_string = p_config->ppsz_list[i];
+ text.psz_string = p_config->ppsz_list_text[i];
+ var_Change( p_aout, "equalizer", VLC_VAR_ADDCHOICE,
+ &val, &text );
+ }
+
+ var_AddCallback( p_aout, "equalizer", EqualizerCallback, NULL );
+ }
+ }
+
+ if( var_Type( p_aout, "audio-filter" ) == 0 )
+ {
+ var_Create( p_aout, "audio-filter",
+ VLC_VAR_STRING | VLC_VAR_DOINHERIT );
+ text.psz_string = _("Audio filters");
+ var_Change( p_aout, "audio-filter", VLC_VAR_SETTEXT, &text, NULL );
+ }
+ if( var_Type( p_aout, "audio-visual" ) == 0 )
+ {
+ var_Create( p_aout, "audio-visual",
+ VLC_VAR_STRING | VLC_VAR_DOINHERIT );
+ text.psz_string = _("Audio visualizations");
+ var_Change( p_aout, "audio-visual", VLC_VAR_SETTEXT, &text, NULL );
+ }
+
+ var_Get( p_aout, "audio-filter", &val );
+ psz_filters = val.psz_string;
+ var_Get( p_aout, "audio-visual", &val );
+ psz_visual = val.psz_string;
+
+ /* parse user filter lists */
+ for( i_visual = 0; i_visual < 2; i_visual++ )
+ {
+ char *psz_next = NULL;
+ char *psz_parser = i_visual ? psz_visual : psz_filters;
+
+ if( psz_parser == NULL || !*psz_parser )
+ continue;
+
+ while( psz_parser && *psz_parser )
+ {
+ aout_filter_t * p_filter = NULL;
+
+ if( p_input->i_nb_filters >= AOUT_MAX_FILTERS )
+ {
+ msg_Dbg( p_aout, "max filter reached (%d)", AOUT_MAX_FILTERS );
+ break;
+ }
+
+ while( *psz_parser == ' ' && *psz_parser == ':' )
+ {
+ psz_parser++;
+ }
+ if( ( psz_next = strchr( psz_parser , ':' ) ) )
+ {
+ *psz_next++ = '\0';
+ }
+ if( *psz_parser =='\0' )
+ {
+ break;
+ }
+
+ /* Create a VLC object */
+ p_filter = vlc_object_create( p_aout, sizeof(aout_filter_t) );
+ if( p_filter == NULL )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+ psz_parser = psz_next;
+ continue;
+ }
+
+ vlc_object_attach( p_filter , p_aout );
+
+ /* try to find the requested filter */
+ if( i_visual == 1 ) /* this can only be a visualization module */
+ {
+ /* request format */
+ memcpy( &p_filter->input, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+
+ p_filter->p_module = module_Need( p_filter, "visualization",
+ psz_parser, VLC_TRUE );
+ }
+ else /* this can be a audio filter module as well as a visualization module */
+ {
+ /* request format */
+ memcpy( &p_filter->input, &chain_input_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+
+ p_filter->p_module = module_Need( p_filter, "audio filter",
+ psz_parser, VLC_TRUE );
+
+ if ( p_filter->p_module == NULL )
+ {
+ /* if the filter requested a special format, retry */
+ if ( !( AOUT_FMTS_IDENTICAL( &p_filter->input,
+ &chain_input_format )
+ && AOUT_FMTS_IDENTICAL( &p_filter->output,
+ &chain_output_format ) ) )
+ {
+ aout_FormatPrepare( &p_filter->input );
+ aout_FormatPrepare( &p_filter->output );
+ p_filter->p_module = module_Need( p_filter, "audio filter",
+ psz_parser, VLC_TRUE );
+ }
+ /* try visual filters */
+ else
+ {
+ memcpy( &p_filter->input, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ memcpy( &p_filter->output, &chain_output_format,
+ sizeof(audio_sample_format_t) );
+ p_filter->p_module = module_Need( p_filter, "visualization",
+ psz_parser, VLC_TRUE );
+ }
+ }
+ }
+
+ /* failure */
+ if ( p_filter->p_module == NULL )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+
+ vlc_object_detach( p_filter );
+ vlc_object_destroy( p_filter );
+
+ psz_parser = psz_next;
+ continue;
+ }
+
+ /* complete the filter chain if necessary */
+ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &p_filter->input ) )
+ {
+ if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
+ &p_input->i_nb_filters,
+ &chain_input_format,
+ &p_filter->input ) < 0 )
+ {
+ msg_Err( p_aout, "cannot add user filter %s (skipped)",
+ psz_parser );
+
+ module_Unneed( p_filter, p_filter->p_module );
+ vlc_object_detach( p_filter );
+ vlc_object_destroy( p_filter );
+
+ psz_parser = psz_next;
+ continue;
+ }
+ }
+
+ /* success */
+ p_filter->b_continuity = VLC_FALSE;
+ p_input->pp_filters[p_input->i_nb_filters++] = p_filter;
+ memcpy( &chain_input_format, &p_filter->output,
+ sizeof( audio_sample_format_t ) );
+
+ /* next filter if any */
+ psz_parser = psz_next;
+ }
+ }
+ if( psz_filters ) free( psz_filters );
+ if( psz_visual ) free( psz_visual );
+
+ /* complete the filter chain if necessary */
+ if ( !AOUT_FMTS_IDENTICAL( &chain_input_format, &chain_output_format ) )
+ {
+ if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
+ &p_input->i_nb_filters,
+ &chain_input_format,
+ &chain_output_format ) < 0 )
+ {
+ inputFailure( p_aout, p_input, "couldn't set an input pipeline" );
+ return -1;
+ }