]> git.sesse.net Git - vlc/blob - modules/gui/macosx/AudioEffects.m
macosx: CAS: re-write the destination section's appearance to make it less cluttered
[vlc] / modules / gui / macosx / AudioEffects.m
1 /*****************************************************************************
2  * AudioEffects.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2004-2012 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
8  *          Jérôme Decoodt <djc@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # import "config.h"
27 #endif
28
29 #import "intf.h"
30 #import "AudioEffects.h"
31 #import "../../audio_filter/equalizer_presets.h"
32 #import "CompatibilityFixes.h"
33
34 #import <vlc_common.h>
35 #import <vlc_aout_intf.h>
36
37 #import <math.h>
38
39 #pragma mark -
40 #pragma mark Initialization & Generic code
41
42 @implementation VLCAudioEffects
43 static VLCAudioEffects *_o_sharedInstance = nil;
44
45 + (VLCAudioEffects *)sharedInstance
46 {
47     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
48 }
49
50 - (id)init
51 {
52     if (_o_sharedInstance) {
53         [self dealloc];
54     } else {
55         p_intf = VLCIntf;
56         _o_sharedInstance = [super init];
57     }
58
59     return _o_sharedInstance;
60 }
61
62 - (void)awakeFromNib
63 {
64     /* setup the user's language */
65     /* Equalizer */
66     [o_eq_enable_ckb setTitle:_NS("Enable")];
67     [o_eq_twopass_ckb setTitle:_NS("2 Pass")];
68     [o_eq_preamp_lbl setStringValue:_NS("Preamp")];
69     [o_eq_presets_popup removeAllItems];
70     for( int i = 0; i < NB_PRESETS ; i++ )
71     {
72         [o_eq_presets_popup addItemWithTitle: _NS(preset_list_text[i])];
73         [[o_eq_presets_popup lastItem] setTag: i];
74     }
75
76     /* Compressor */
77     [o_comp_enable_ckb setTitle:_NS("Enable dynamic range compressor")];
78     [o_comp_reset_btn setTitle:_NS("Reset")];
79     [o_comp_band1_lbl setStringValue:_NS("RMS/peak")];;
80     [o_comp_band2_lbl setStringValue:_NS("Attack")];
81     [o_comp_band3_lbl setStringValue:_NS("Release")];
82     [o_comp_band4_lbl setStringValue:_NS("Threshold")];
83     [o_comp_band5_lbl setStringValue:_NS("Ratio")];
84     [o_comp_band6_lbl setStringValue:_NS("Knee radius")];
85     [o_comp_band7_lbl setStringValue:_NS("Makeup gain")];
86
87     /* Spatializer */
88     [o_spat_enable_ckb setTitle:_NS("Enable Spatializer")];
89     [o_spat_reset_btn setTitle:_NS("Reset")];
90     [o_spat_band1_lbl setStringValue:_NS("Size")];
91     [o_spat_band2_lbl setStringValue:_NS("Width")];
92     [o_spat_band3_lbl setStringValue:_NS("Wet")];
93     [o_spat_band4_lbl setStringValue:_NS("Dry")];
94     [o_spat_band5_lbl setStringValue:_NS("Damp")];
95
96     /* Filter */
97     [o_filter_headPhone_ckb setTitle:_NS("Headphone virtualization")];
98     [o_filter_normLevel_ckb setTitle:_NS("Volume normalization")];
99     [o_filter_normLevel_lbl setStringValue:_NS("Maximum level")];
100
101     /* generic */
102     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"equalizer"]] setLabel:_NS("Equalizer")];
103     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"compressor"]] setLabel:_NS("Compressor")];
104     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"spatializer"]] setLabel:_NS("Spatializer")];
105     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"filter"]] setLabel:_NS("Filter")];
106     [o_window setTitle:_NS("Audio Effects")];
107     [o_window setExcludedFromWindowsMenu:YES];
108     if (OSX_LION)
109         [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
110
111     [self setupEqualizer];
112     [self resetCompressor];
113     [self resetSpatializer];
114     [self resetAudioFilters];
115 }
116
117 - (IBAction)toggleWindow:(id)sender
118 {
119     if( [o_window isVisible] )
120         [o_window orderOut:sender];
121     else
122         [o_window makeKeyAndOrderFront:sender];
123 }
124
125 - (void)setAudioFilter: (char *)psz_name on:(BOOL)b_on
126 {
127     char *psz_tmp;
128     audio_output_t * p_aout = getAout();
129     if( p_aout )
130         psz_tmp = var_GetNonEmptyString( p_aout, "audio-filter" );
131     else
132         psz_tmp = config_GetPsz( p_intf, "audio-filter" );
133
134     if( b_on )
135     {
136         if(! psz_tmp)
137             config_PutPsz( p_intf, "audio-filter", psz_name );
138         else if( (NSInteger)strstr( psz_tmp, psz_name ) == NO )
139         {
140             psz_tmp = (char *)[[NSString stringWithFormat: @"%s:%s", psz_tmp, psz_name] UTF8String];
141             config_PutPsz( p_intf, "audio-filter", psz_tmp );
142         }
143     } else {
144         if( psz_tmp )
145         {
146             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@":%s",psz_name]]] UTF8String];
147             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"%s:",psz_name]]] UTF8String];
148             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithUTF8String:psz_name]]] UTF8String];
149             config_PutPsz( p_intf, "audio-filter", psz_tmp );
150         }
151     }
152
153     if( p_aout ) {
154         aout_EnableFilter( pl_Get( p_intf ), psz_name, b_on );
155         vlc_object_release( p_aout );
156     }
157 }
158
159 #pragma mark -
160 #pragma mark Equalizer
161 static bool GetEqualizerStatus( intf_thread_t *p_custom_intf,
162                              char *psz_name )
163 {
164     char *psz_parser, *psz_string = NULL;
165     vlc_object_t *p_object = VLC_OBJECT(getAout());
166     if( p_object == NULL )
167         p_object = vlc_object_hold(pl_Get( p_custom_intf ));
168
169     psz_string = config_GetPsz( p_custom_intf, "audio-filter" );
170
171     if(! psz_string )
172         psz_string = var_GetNonEmptyString( p_object, "audio-filter" );
173
174     vlc_object_release( p_object );
175
176     if( !psz_string ) return false;
177
178     psz_parser = strstr( psz_string, psz_name );
179
180     free( psz_string );
181
182     if ( psz_parser )
183         return true;
184     else
185         return false;
186 }
187
188 - (void)setupEqualizer
189 {
190     vlc_object_t *p_object = VLC_OBJECT(getAout());
191     if( p_object == NULL )
192         p_object = vlc_object_hold(pl_Get( p_intf ));
193
194     char *psz_preset;
195
196     var_Create( p_object, "equalizer-preset", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
197     psz_preset = var_GetNonEmptyString( p_object, "equalizer-preset" );
198
199     for( int i = 0 ; i < NB_PRESETS ; i++ )
200     {
201         if( strcmp( preset_list[i], psz_preset ) )
202             continue;
203
204         [o_eq_presets_popup selectItemWithTag:i];
205
206         [o_eq_preamp_sld setFloatValue: eqz_preset_10b[i].f_preamp];
207         [self setBandSlidersValues: (float *)eqz_preset_10b[i].f_amp];
208
209         if( strcmp( psz_preset, "flat" ) )
210         {
211             char psz_bands[100];
212
213             snprintf( psz_bands, sizeof( psz_bands ),
214                      "%.1f %.1f %.1f %.1f %.1f %.1f %.1f "
215                      "%.1f %.1f %.1f",
216                      eqz_preset_10b[i].f_amp[0],
217                      eqz_preset_10b[i].f_amp[1],
218                      eqz_preset_10b[i].f_amp[2],
219                      eqz_preset_10b[i].f_amp[3],
220                      eqz_preset_10b[i].f_amp[4],
221                      eqz_preset_10b[i].f_amp[5],
222                      eqz_preset_10b[i].f_amp[6],
223                      eqz_preset_10b[i].f_amp[7],
224                      eqz_preset_10b[i].f_amp[8],
225                      eqz_preset_10b[i].f_amp[9] );
226
227             var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
228             var_Create( p_object, "equalizer-bands", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
229             var_SetFloat( p_object, "equalizer-preamp", eqz_preset_10b[i].f_preamp );
230             var_SetString( p_object, "equalizer-bands", psz_bands );
231         }
232     }
233     free( psz_preset );
234     vlc_object_release( p_object );
235
236     [self equalizerUpdated];
237 }
238
239 - (void)equalizerUpdated
240 {
241     float f_preamp, f_band[10];
242     char *psz_bands, *psz_bands_init, *p_next;
243     bool b_2p;
244     bool b_enabled = GetEqualizerStatus( p_intf, (char *)"equalizer" );
245     vlc_object_t *p_object = VLC_OBJECT(getAout());
246
247     if( p_object == NULL )
248         p_object = vlc_object_hold(pl_Get( p_intf ));
249
250     var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT |
251                VLC_VAR_DOINHERIT );
252     var_Create( p_object, "equalizer-bands", VLC_VAR_STRING |
253                VLC_VAR_DOINHERIT );
254
255     psz_bands = var_GetNonEmptyString( p_object, "equalizer-bands" );
256
257     if( psz_bands == NULL )
258         psz_bands = strdup( "0 0 0 0 0 0 0 0 0 0" );
259
260     b_2p = (BOOL)config_GetInt( p_object, "equalizer-2pass" );
261     f_preamp = config_GetFloat( p_object, "equalizer-preamp" );
262
263     vlc_object_release( p_object );
264
265     /* Set the preamp slider */
266     [o_eq_preamp_sld setFloatValue: f_preamp];
267
268     /* Set the bands slider */
269     psz_bands_init = psz_bands;
270
271     for( int i = 0; i < 10; i++ )
272     {
273         /* Read dB -20/20 */
274         f_band[i] = strtof( psz_bands, &p_next );
275         if( !p_next || p_next == psz_bands ) break; /* strtof() failed */
276
277         if( !*psz_bands ) break; /* end of line */
278         psz_bands = p_next+1;
279     }
280     free( psz_bands_init );
281     [self setBandSlidersValues:f_band];
282
283     /* Set the the checkboxes */
284     [o_eq_enable_ckb setState: b_enabled];
285     [o_eq_twopass_ckb setState: b_2p];
286 }
287
288 - (id)sliderByIndex:(int)index
289 {
290     switch(index)
291     {
292         case 0 : return o_eq_band1_sld;
293         case 1 : return o_eq_band2_sld;
294         case 2 : return o_eq_band3_sld;
295         case 3 : return o_eq_band4_sld;
296         case 4 : return o_eq_band5_sld;
297         case 5 : return o_eq_band6_sld;
298         case 6 : return o_eq_band7_sld;
299         case 7 : return o_eq_band8_sld;
300         case 8 : return o_eq_band9_sld;
301         case 9 : return o_eq_band10_sld;
302         default : return nil;
303     }
304 }
305
306 - (void)setBandSlidersValues:(float *)values
307 {
308     for (int i = 0 ; i<= 9 ; i++)
309         [self setValue:values[i] forSlider:i];
310 }
311
312 - (void)initBandSliders
313 {
314     for (int i = 0 ; i< 9 ; i++)
315         [self setValue:0.0 forSlider:i];
316 }
317
318 - (void)setValue:(float)value forSlider:(int)index
319 {
320     id slider = [self sliderByIndex:index];
321
322     if (slider != nil)
323         [slider setFloatValue:value];
324 }
325
326 - (IBAction)eq_enable:(id)sender
327 {
328     [self setAudioFilter: "equalizer" on:[sender state]];
329 }
330
331 - (IBAction)eq_bandSliderUpdated:(id)sender
332 {
333     vlc_object_t *p_object = VLC_OBJECT(getAout());
334
335     if( p_object == NULL )
336         p_object = vlc_object_hold(pl_Get( p_intf ));
337
338     const char *psz_values;
339     NSString *preset = [NSString stringWithFormat:@"%.1f ", [o_eq_band1_sld floatValue] ];
340     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band2_sld floatValue] ];
341     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band3_sld floatValue] ];
342     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band4_sld floatValue] ];
343     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band5_sld floatValue] ];
344     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band6_sld floatValue] ];
345     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band7_sld floatValue] ];
346     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band8_sld floatValue] ];
347     preset = [preset stringByAppendingFormat:@"%.1f ", [o_eq_band9_sld floatValue] ];
348     preset = [preset stringByAppendingFormat:@"%.1f", [o_eq_band10_sld floatValue] ];
349
350     psz_values = [preset UTF8String];
351     var_SetString( p_object, "equalizer-bands", psz_values );
352
353     /* save changed to config */
354     config_PutPsz( p_intf, "equalizer-bands", psz_values );
355
356     vlc_object_release( p_object );
357 }
358 - (IBAction)eq_changePreset:(id)sender
359 {
360     vlc_object_t *p_object= VLC_OBJECT(getAout());
361     if( p_object == NULL )
362         p_object = vlc_object_hold(pl_Get( p_intf ));
363     NSInteger numberOfChosenPreset = [[sender selectedItem] tag];
364
365     var_SetString( p_object , "equalizer-preset" , preset_list[numberOfChosenPreset] );
366
367     NSString *preset = @"";
368     const char *psz_values;
369     for( int i = 0; i < EQZ_BANDS_MAX; i++ )
370     {
371         preset = [preset stringByAppendingFormat:@"%.1f ", eqz_preset_10b[numberOfChosenPreset].f_amp[i] ];
372     }
373     psz_values = [preset UTF8String];
374     var_SetString( p_object, "equalizer-bands", psz_values );
375     var_SetFloat( p_object, "equalizer-preamp", eqz_preset_10b[[[sender selectedItem] tag]].f_preamp);
376
377     [o_eq_preamp_sld setFloatValue: eqz_preset_10b[numberOfChosenPreset].f_preamp];
378
379     [self setBandSlidersValues:(float *)eqz_preset_10b[numberOfChosenPreset].f_amp];
380
381     /* save changed to config */
382     config_PutPsz( p_intf, "equalizer-bands", psz_values );
383     config_PutFloat( p_intf, "equalizer-preamp", eqz_preset_10b[numberOfChosenPreset].f_preamp );
384     config_PutPsz( p_intf, "equalizer-preset", preset_list[numberOfChosenPreset] );
385
386     vlc_object_release( p_object );
387 }
388 - (IBAction)eq_preampSliderUpdated:(id)sender
389 {
390     float f_preamp = [sender floatValue] ;
391
392     vlc_object_t *p_object = VLC_OBJECT(getAout());
393     if( p_object == NULL )
394         p_object = vlc_object_hold(pl_Get( p_intf ));
395
396     var_SetFloat( p_object, "equalizer-preamp", f_preamp );
397
398     /* save changed to config */
399     config_PutFloat( p_intf, "equalizer-preamp", f_preamp );
400
401     vlc_object_release( p_object );
402 }
403 - (IBAction)eq_twopass:(id)sender
404 {
405     bool b_2p = [sender state] ? true : false;
406     audio_output_t *p_aout = getAout();
407     vlc_object_t *p_object= VLC_OBJECT(p_aout);
408     if( p_object == NULL )
409         p_object = vlc_object_hold(pl_Get( p_intf ));
410
411     var_SetBool( p_object, "equalizer-2pass", b_2p );
412
413     /* save changed to config */
414     config_PutInt( p_intf, "equalizer-2pass", (int)b_2p );
415
416     vlc_object_release( p_object );
417 }
418
419 #pragma mark -
420 #pragma mark Compressor
421 - (void)resetCompressor
422 {
423     char * psz_afilters;
424     psz_afilters = config_GetPsz( p_intf, "audio-filter" );
425     if( psz_afilters ) {
426         [o_comp_enable_ckb setState: (NSInteger)strstr( psz_afilters, "compressor" ) ];
427         free( psz_afilters );
428     }
429     else
430         [o_comp_enable_ckb setState: NSOffState];
431
432     [o_comp_band1_sld setFloatValue: config_GetFloat( p_intf, "compressor-rms-peak" )];
433     [o_comp_band1_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [o_comp_band1_sld floatValue]]];
434     [o_comp_band2_sld setFloatValue: config_GetFloat( p_intf, "compressor-attack" )];
435     [o_comp_band2_fld setStringValue:[NSString localizedStringWithFormat:@"%2.1f ms", [o_comp_band2_sld floatValue]]];
436     [o_comp_band3_sld setFloatValue: config_GetFloat( p_intf, "compressor-release" )];
437     [o_comp_band3_fld setStringValue:[NSString localizedStringWithFormat:@"%3.1f ms", [o_comp_band3_sld floatValue]]];
438     [o_comp_band4_sld setFloatValue: config_GetFloat( p_intf, "compressor-threshold" )];
439     [o_comp_band4_fld setStringValue:[NSString localizedStringWithFormat:@"%2.1f dB", [o_comp_band4_sld floatValue]]];
440     [o_comp_band5_sld setFloatValue: config_GetFloat( p_intf, "compressor-ratio" )];
441     [o_comp_band5_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f:1", [o_comp_band5_sld floatValue]]];
442     [o_comp_band6_sld setFloatValue: config_GetFloat( p_intf, "compressor-knee" )];
443     [o_comp_band6_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f dB", [o_comp_band6_sld floatValue]]];
444     [o_comp_band7_sld setFloatValue: config_GetFloat( p_intf, "compressor-makeup-gain" )];
445     [o_comp_band7_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f dB", [o_comp_band7_sld floatValue]]];
446 }
447
448 - (IBAction)resetCompressorValues:(id)sender
449 {
450     config_PutFloat( p_intf, "compressor-rms-peak", 0.000000 );
451     config_PutFloat( p_intf, "compressor-attack", 25.000000 );
452     config_PutFloat( p_intf, "compressor-release", 100.000000 );
453     config_PutFloat( p_intf, "compressor-threshold", -11.000000 );
454     config_PutFloat( p_intf, "compressor-ratio", 8.000000 );
455     config_PutFloat( p_intf, "compressor-knee", 2.500000 );
456     config_PutFloat( p_intf, "compressor-makeup-gain", 7.000000 );
457
458     audio_output_t * p_aout = getAout();
459     if (p_aout) {
460         var_SetFloat( p_aout, "compressor-rms-peak", 0.000000 );
461         var_SetFloat( p_aout, "compressor-attack", 25.000000 );
462         var_SetFloat( p_aout, "compressor-release", 100.000000 );
463         var_SetFloat( p_aout, "compressor-threshold", -11.000000 );
464         var_SetFloat( p_aout, "compressor-ratio", 8.000000 );
465         var_SetFloat( p_aout, "compressor-knee", 2.500000 );
466         var_SetFloat( p_aout, "compressor-makeup-gain", 7.000000 );
467         vlc_object_release( p_aout );
468     }
469     [self resetCompressor];
470 }
471
472 - (IBAction)comp_enable:(id)sender
473 {
474     [self setAudioFilter:"compressor" on:[sender state]];
475 }
476
477 - (IBAction)comp_sliderUpdated:(id)sender
478 {
479     audio_output_t * p_aout = getAout();
480     char * value;
481     if( sender == o_comp_band1_sld )
482         value = "compressor-rms-peak";
483     else if( sender == o_comp_band2_sld )
484         value = "compressor-attack";
485     else if( sender == o_comp_band3_sld )
486         value = "compressor-release";
487     else if( sender == o_comp_band4_sld )
488         value = "compressor-threshold";
489     else if( sender == o_comp_band5_sld )
490         value = "compressor-ratio";
491     else if( sender == o_comp_band6_sld )
492         value = "compressor-knee";
493     else if( sender == o_comp_band7_sld )
494         value = "compressor-makeup-gain";
495
496     if( p_aout ) {
497         var_SetFloat( p_aout, value, [sender floatValue] );
498         vlc_object_release( p_aout );
499     }
500     config_PutFloat( p_intf, value, [sender floatValue] );
501
502     if( sender == o_comp_band1_sld )
503         [o_comp_band1_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
504     else if( sender == o_comp_band2_sld )
505         [o_comp_band2_fld setStringValue:[NSString localizedStringWithFormat:@"%2.1f ms", [sender floatValue]]];
506     else if( sender == o_comp_band3_sld )
507         [o_comp_band3_fld setStringValue:[NSString localizedStringWithFormat:@"%3.1f ms", [sender floatValue]]];
508     else if( sender == o_comp_band4_sld )
509         [o_comp_band4_fld setStringValue:[NSString localizedStringWithFormat:@"%2.1f dB", [sender floatValue]]];
510     else if( sender == o_comp_band5_sld )
511         [o_comp_band5_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f:1", [sender floatValue]]];
512     else if( sender == o_comp_band6_sld )
513         [o_comp_band6_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f dB", [sender floatValue]]];
514     else if( sender == o_comp_band7_sld )
515         [o_comp_band7_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f dB", [sender floatValue]]];
516 }
517
518 #pragma mark -
519 #pragma mark Spatializer
520 - (void)resetSpatializer
521 {
522     char * psz_afilters;
523     psz_afilters = config_GetPsz( p_intf, "audio-filter" );
524     if( psz_afilters ) {
525         [o_spat_enable_ckb setState: (NSInteger)strstr( psz_afilters, "spatializer" ) ];
526         free( psz_afilters );
527     }
528     else
529         [o_spat_enable_ckb setState: NSOffState];
530
531 #define setSlider( bandsld, bandfld, var ) \
532     [bandsld setFloatValue: config_GetFloat( p_intf, var ) * 10.]; \
533     [bandfld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [bandsld floatValue]]]
534
535     setSlider( o_spat_band1_sld, o_spat_band1_fld, "spatializer-roomsize" );
536     setSlider( o_spat_band2_sld, o_spat_band2_fld, "spatializer-width" );
537     setSlider( o_spat_band3_sld, o_spat_band3_fld, "spatializer-wet" );
538     setSlider( o_spat_band4_sld, o_spat_band4_fld, "spatializer-dry" );
539     setSlider( o_spat_band5_sld, o_spat_band5_fld, "spatializer-damp" );
540
541 #undef setSlider
542 }
543
544 - (IBAction)resetSpatializerValues:(id)sender
545 {
546     config_PutFloat( p_intf, "spatializer-roomsize", .85 );
547     config_PutFloat( p_intf, "spatializer-width", 1. );
548     config_PutFloat( p_intf, "spatializer-wet", .4 );
549     config_PutFloat( p_intf, "spatializer-dry", .5 );
550     config_PutFloat( p_intf, "spatializer-damp", .5 );
551
552     audio_output_t * p_aout = getAout();
553     if (p_aout) {
554         var_SetFloat( p_aout, "spatializer-roomsize", .85 );
555         var_SetFloat( p_aout, "spatializer-width", 1. );
556         var_SetFloat( p_aout, "spatializer-wet", .4 );
557         var_SetFloat( p_aout, "spatializer-dry", .5 );
558         var_SetFloat( p_aout, "spatializer-damp", .5 );
559         vlc_object_release( p_aout );
560     }
561     [self resetSpatializer];
562 }
563
564 - (IBAction)spat_enable:(id)sender
565 {
566     [self setAudioFilter:"spatializer" on:[sender state]];
567 }
568
569 - (IBAction)spat_sliderUpdated:(id)sender
570 {
571     audio_output_t * p_aout = getAout();
572     char * value;
573     if( sender == o_spat_band1_sld )
574         value = "spatializer-roomsize";
575     else if( sender == o_spat_band2_sld )
576         value = "spatializer-width";
577     else if( sender == o_spat_band3_sld )
578         value = "spatializer-wet";
579     else if( sender == o_spat_band4_sld )
580         value = "spatializer-dry";
581     else if( sender == o_spat_band5_sld )
582         value = "spatializer-damp";
583
584     if( p_aout ) {
585         var_SetFloat( p_aout, value, [sender floatValue] / 10. );
586         vlc_object_release( p_aout );
587     }
588     config_PutFloat( p_intf, value, [sender floatValue] / 10. );
589
590     if( sender == o_spat_band1_sld )
591         [o_spat_band1_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
592     else if( sender == o_spat_band2_sld )
593         [o_spat_band2_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
594     else if( sender == o_spat_band3_sld )
595         [o_spat_band3_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
596     else if( sender == o_spat_band4_sld )
597         [o_spat_band4_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
598     else if( sender == o_spat_band5_sld )
599         [o_spat_band5_fld setStringValue:[NSString localizedStringWithFormat:@"%1.1f", [sender floatValue]]];
600 }
601
602 #pragma mark -
603 #pragma mark Filter
604 - (void)resetAudioFilters
605 {
606     char * psz_afilters;
607     psz_afilters = config_GetPsz( p_intf, "audio-filter" );
608     if( psz_afilters )
609     {
610         [o_filter_headPhone_ckb setState: (NSInteger)strstr( psz_afilters, "headphone" ) ];
611         [o_filter_normLevel_ckb setState: (NSInteger)strstr( psz_afilters, "normvol" ) ];
612         free( psz_afilters );
613     } else {
614         [o_filter_headPhone_ckb setState: NSOffState];
615         [o_filter_normLevel_ckb setState: NSOffState];
616     }
617     [o_filter_normLevel_sld setFloatValue: config_GetFloat( p_intf, "norm-max-level" )];
618 }
619
620 - (IBAction)filter_enableHeadPhoneVirt:(id)sender
621 {
622     [self setAudioFilter: "headphone" on:[sender state]];
623 }
624
625 - (IBAction)filter_enableVolumeNorm:(id)sender
626 {
627     [self setAudioFilter: "normvol" on:[sender state]];
628 }
629
630 - (IBAction)filter_volNormSliderUpdated:(id)sender
631 {
632     audio_output_t * p_aout= getAout();
633
634     if( p_aout )
635     {
636         var_SetFloat( p_aout, "norm-max-level", [o_filter_normLevel_sld floatValue] );
637         vlc_object_release( p_aout );
638     }
639
640     config_PutFloat( p_intf, "norm-max-level", [o_filter_normLevel_sld floatValue] );
641 }
642
643 @end