]> git.sesse.net Git - vlc/blob - modules/gui/macosx/equalizer.m
ed5fe88385f897fb2de1b3a196ad60bde23615b5
[vlc] / modules / gui / macosx / equalizer.m
1 /*****************************************************************************
2  * equalizer.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2004-2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Jerome Decoodt <djc@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc_aout.h>
29
30 #include "intf.h"
31
32 #include <math.h>
33
34 #include "equalizer.h"
35 #include "../../audio_filter/equalizer_presets.h"
36
37 /*****************************************************************************
38  * VLCEqualizer implementation 
39  *****************************************************************************/
40 @implementation VLCEqualizer
41
42 static void ChangeFiltersString( intf_thread_t *p_intf,
43                                  char *psz_name, vlc_bool_t b_add )
44 {
45     char *psz_parser, *psz_string;
46     int i;
47     vlc_object_t *p_object = vlc_object_find( p_intf,
48                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
49     aout_instance_t *p_aout = (aout_instance_t *)p_object;
50     if( p_object == NULL )
51         p_object = vlc_object_find( p_intf,
52                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
53     if( p_object == NULL )
54         return;
55
56     psz_string = var_GetString( p_object, "audio-filter" );
57
58     if( !psz_string ) psz_string = strdup( "" );
59
60     psz_parser = strstr( psz_string, psz_name );
61
62     if( b_add )
63     {
64         if( !psz_parser )
65         {
66             psz_parser = psz_string;
67             asprintf( &psz_string, ( *psz_string ) ? "%s,%s" : "%s%s",
68                             psz_string, psz_name );
69             free( psz_parser );
70         }
71         else
72         {
73             return;
74         }
75     }
76     else
77     {
78         if( psz_parser )
79         {
80             memmove( psz_parser, psz_parser + strlen( psz_name ) +
81                             ( *( psz_parser + strlen( psz_name ) ) == ',' ? 1 : 0 ),
82                             strlen( psz_parser + strlen( psz_name ) ) + 1 );
83
84             if( *( psz_string+strlen( psz_string ) - 1 ) == ',' )
85             {
86                 *( psz_string+strlen( psz_string ) - 1 ) = '\0';
87             }
88          }
89          else
90          {
91              free( psz_string );
92              return;
93          }
94     }
95
96     var_SetString( p_object, "audio-filter", psz_string );
97     if( p_aout )
98     {
99         for( i = 0; i < p_aout->i_nb_inputs; i++ )
100         {
101             p_aout->pp_inputs[i]->b_restart = VLC_TRUE;
102         }
103     }
104     free( psz_string );
105     vlc_object_release( p_object );
106 }
107
108 static vlc_bool_t GetFiltersStatus( intf_thread_t *p_intf,
109                                  char *psz_name )
110 {
111     char *psz_parser, *psz_string;
112     vlc_object_t *p_object = vlc_object_find( p_intf,
113                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
114     if( p_object == NULL )
115         p_object = vlc_object_find( p_intf,
116                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
117     if( p_object == NULL )
118         return VLC_FALSE;
119
120     psz_string = var_GetString( p_object, "audio-filter" );
121
122     vlc_object_release( p_object );
123
124     if( !psz_string ) return VLC_FALSE;
125
126     psz_parser = strstr( psz_string, psz_name );
127
128     free( psz_string );
129
130     if ( psz_parser )
131         return VLC_TRUE;
132     else
133         return VLC_FALSE;
134 }
135
136 - (void)initStrings
137 {
138     int i;
139     [o_btn_equalizer setToolTip: _NS("Equalizer")];
140     [o_ckb_2pass setTitle: _NS("2 Pass")];
141     [o_ckb_2pass setToolTip: _NS("Apply the "
142         "equalizer filter twice. The effect will be sharper.")];
143     [o_ckb_enable setTitle: _NS("Enable")];
144     [o_ckb_enable setToolTip: _NS("Enable the equalizer. Bands can be set "
145         "manually or using a preset.")];
146     [o_fld_preamp setStringValue: _NS("Preamp")];
147
148     [o_popup_presets removeAllItems];
149     for( i = 0; i < 18 ; i++ )
150     {
151         [o_popup_presets insertItemWithTitle: _NS(preset_list_text[i]) atIndex: i];
152     }
153     [o_window setTitle: _NS("Equalizer")];
154
155         /*
156     [o_slider_band1 setFloatValue: 0];
157     [o_slider_band2 setFloatValue: 0];
158     [o_slider_band3 setFloatValue: 0];
159     [o_slider_band4 setFloatValue: 0];
160     [o_slider_band5 setFloatValue: 0];
161     [o_slider_band6 setFloatValue: 0];
162     [o_slider_band7 setFloatValue: 0];
163     [o_slider_band8 setFloatValue: 0];
164     [o_slider_band9 setFloatValue: 0];
165     [o_slider_band10 setFloatValue: 0];
166         */
167         [self initBandSliders];
168     [o_ckb_enable setState: NSOffState];
169     [o_ckb_2pass setState: NSOffState];
170 }
171
172 - (void)equalizerUpdated
173 {
174     intf_thread_t *p_intf = VLCIntf;
175     float f_preamp, f_band[10];
176     char *psz_bands, *psz_bands_init, *p_next;
177     vlc_bool_t b_2p;
178     int i;
179     vlc_bool_t b_enabled = GetFiltersStatus( p_intf, (char *)"equalizer" );
180     vlc_object_t *p_object = vlc_object_find( p_intf,
181                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
182
183     if( p_object == NULL )
184         p_object = vlc_object_find( p_intf,
185                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
186     if( p_object == NULL )
187         return;
188
189     var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT |
190                                                     VLC_VAR_DOINHERIT );
191     var_Create( p_object, "equalizer-bands", VLC_VAR_STRING |
192                                                     VLC_VAR_DOINHERIT );
193
194     f_preamp = var_GetFloat( p_object, "equalizer-preamp" );
195     psz_bands = var_GetString( p_object, "equalizer-bands" );
196
197     if( !strcmp( psz_bands, "" ) )
198         psz_bands = strdup( "0 0 0 0 0 0 0 0 0 0" );
199
200     b_2p = var_GetBool( p_object, "equalizer-2pass" );
201
202     vlc_object_release( p_object );
203
204 /* Set the preamp slider */
205     [o_slider_preamp setFloatValue: f_preamp];
206
207 /* Set the bands slider */
208     psz_bands_init = psz_bands;
209
210     for( i = 0; i < 10; i++ )
211     {
212         /* Read dB -20/20 */
213 #ifdef HAVE_STRTOF
214         f_band[i] = strtof( psz_bands, &p_next );
215 #else
216         f_band[i] = (float)strtod( psz_bands, &p_next );
217 #endif
218         if( !p_next || p_next == psz_bands ) break; /* strtof() failed */
219
220         if( !*psz_bands ) break; /* end of line */
221         psz_bands = p_next+1;
222     }
223     free( psz_bands_init );
224         [self setBandSlidersValues:f_band];
225
226         /*
227     [o_slider_band1 setFloatValue: f_band[0]];
228     [o_slider_band2 setFloatValue: f_band[1]];
229     [o_slider_band3 setFloatValue: f_band[2]];
230     [o_slider_band4 setFloatValue: f_band[3]];
231     [o_slider_band5 setFloatValue: f_band[4]];
232     [o_slider_band6 setFloatValue: f_band[5]];
233     [o_slider_band7 setFloatValue: f_band[6]];
234     [o_slider_band8 setFloatValue: f_band[7]];
235     [o_slider_band9 setFloatValue: f_band[8]];
236     [o_slider_band10 setFloatValue: f_band[9]];
237         */
238         
239 /* Set the the checkboxes */
240     if( b_enabled == VLC_TRUE )
241         [o_ckb_enable setState:NSOnState];
242     else
243         [o_ckb_enable setState:NSOffState];
244
245     [o_ckb_2pass setState:( ( b_2p == VLC_TRUE ) ? NSOnState : NSOffState )];
246 }
247
248 - (IBAction)bandSliderUpdated:(id)sender
249 {
250     intf_thread_t *p_intf = VLCIntf;
251     vlc_object_t *p_object = vlc_object_find( p_intf,
252                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
253     char psz_values[102];
254     memset( psz_values, 0, 102 );
255
256     if( p_object == NULL )
257         p_object = vlc_object_find( p_intf,
258                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
259     if( p_object == NULL )
260         return;
261
262     /* Write the new bands values */
263 /* TODO: write a generic code instead of ten times the same thing */
264
265     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band1 floatValue] );
266     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band2 floatValue] );
267     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band3 floatValue] );
268     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band4 floatValue] );
269     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band5 floatValue] );
270     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band6 floatValue] );
271     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band7 floatValue] );
272     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band8 floatValue] );
273     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band9 floatValue] );
274     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band10 floatValue] );
275
276     var_SetString( p_object, "equalizer-bands", psz_values );
277     vlc_object_release( p_object );
278 }
279
280 - (IBAction)changePreset:(id)sender
281 {
282     intf_thread_t *p_intf = VLCIntf;
283     int i;
284     vlc_object_t *p_object= vlc_object_find( p_intf,
285                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
286     char psz_values[102];
287     memset( psz_values, 0, 102 );
288
289     if( p_object == NULL )
290         p_object = vlc_object_find( p_intf,
291                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
292     if( p_object == NULL )
293         return;
294
295     var_SetString( p_object , "equalizer-preset" , preset_list[[sender indexOfSelectedItem]] );
296
297     for( i = 0; i < 10; i++ )
298         sprintf( psz_values, "%s %.1f", psz_values, eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[i] );
299     var_SetString( p_object, "equalizer-bands", psz_values );
300     var_SetFloat( p_object, "equalizer-preamp", eqz_preset_10b[[sender indexOfSelectedItem]]->f_preamp);
301
302     [o_slider_preamp setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_preamp];
303         /*
304     [o_slider_band1 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[0]];
305     [o_slider_band2 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[1]];
306     [o_slider_band3 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[2]];
307     [o_slider_band4 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[3]];
308     [o_slider_band5 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[4]];
309     [o_slider_band6 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[5]];
310     [o_slider_band7 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[6]];
311     [o_slider_band8 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[7]];
312     [o_slider_band9 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[8]];
313     [o_slider_band10 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[9]];
314         */
315         [self setBandSlidersValues:(float *)eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp];
316         
317     vlc_object_release( p_object );
318 }
319
320 - (IBAction)enable:(id)sender
321 {
322     ChangeFiltersString( VLCIntf, (char *)"equalizer", [sender state] );
323 }
324
325 - (IBAction)preampSliderUpdated:(id)sender
326 {
327     intf_thread_t *p_intf = VLCIntf;
328     float f_preamp = [sender floatValue] ;
329
330     vlc_object_t *p_object = vlc_object_find( p_intf,
331                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
332     if( p_object == NULL )
333         p_object = vlc_object_find( p_intf,
334                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
335     if( p_object == NULL )
336         return;
337
338     var_SetFloat( p_object, "equalizer-preamp", f_preamp );
339
340     vlc_object_release( p_object );
341 }
342
343 - (IBAction)toggleWindow:(id)sender
344 {
345     if( [o_window isVisible] )
346     {
347         [o_window orderOut:sender];
348         [o_btn_equalizer setState:NSOffState];
349     }
350     else
351     {
352         [o_window makeKeyAndOrderFront:sender];
353         [o_btn_equalizer setState:NSOnState];
354     }
355 }
356
357 - (IBAction)twopass:(id)sender
358 {
359     intf_thread_t *p_intf = VLCIntf;
360     vlc_bool_t b_2p = [sender state] ? VLC_TRUE : VLC_FALSE;
361     vlc_object_t *p_object= vlc_object_find( p_intf,
362                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
363     aout_instance_t *p_aout = (aout_instance_t *)p_object;
364     if( p_object == NULL )
365         p_object = vlc_object_find( p_intf,
366                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
367     if( p_object == NULL )
368         return;
369
370     var_SetBool( p_object, "equalizer-2pass", b_2p );
371     if( ( [o_ckb_enable state] ) && ( p_aout != NULL ) )
372     {
373        int i;
374         for( i = 0; i < p_aout->i_nb_inputs; i++ )
375         {
376             p_aout->pp_inputs[i]->b_restart = VLC_TRUE;
377         }
378     }
379
380     vlc_object_release( p_object );
381 }
382
383 - (void)windowWillClose:(NSNotification *)aNotification
384 {
385     [o_btn_equalizer setState: NSOffState];
386 }
387
388 - (void)awakeFromNib
389 {
390     int i;
391     vlc_object_t *p_object= vlc_object_find( VLCIntf,
392                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
393     if( p_object == NULL )
394                 p_object = vlc_object_find( VLCIntf,
395                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
396
397     [o_window setExcludedFromWindowsMenu: TRUE];
398
399     [self initStrings];
400
401     if( p_object )
402     {
403         char *psz_preset;
404
405         var_Create( p_object, "equalizer-preset", VLC_VAR_STRING |
406                                                         VLC_VAR_DOINHERIT );
407         psz_preset = var_GetString( p_object, "equalizer-preset" );
408
409         for( i = 0 ; i < 18 ; i++ )
410         {
411             if( !strcmp( preset_list[i], psz_preset ) )
412             {
413                 [o_popup_presets selectItemAtIndex: i];
414
415                 [o_slider_preamp setFloatValue: eqz_preset_10b[i]->f_preamp];
416                                 [self setBandSlidersValues: (float *)eqz_preset_10b[i]->f_amp];
417                                 
418                                 /*
419                 [o_slider_band1 setFloatValue: eqz_preset_10b[i]->f_amp[0]];
420                 [o_slider_band2 setFloatValue: eqz_preset_10b[i]->f_amp[1]];
421                 [o_slider_band3 setFloatValue: eqz_preset_10b[i]->f_amp[2]];
422                 [o_slider_band4 setFloatValue: eqz_preset_10b[i]->f_amp[3]];
423                 [o_slider_band5 setFloatValue: eqz_preset_10b[i]->f_amp[4]];
424                 [o_slider_band6 setFloatValue: eqz_preset_10b[i]->f_amp[5]];
425                 [o_slider_band7 setFloatValue: eqz_preset_10b[i]->f_amp[6]];
426                 [o_slider_band8 setFloatValue: eqz_preset_10b[i]->f_amp[7]];
427                 [o_slider_band9 setFloatValue: eqz_preset_10b[i]->f_amp[8]];
428                 [o_slider_band10 setFloatValue: eqz_preset_10b[i]->f_amp[9]];
429                                 */
430                                 
431                 if( strcmp( psz_preset, "flat" ) )
432                 {
433                     char psz_bands[100];
434                     memset( psz_bands, 0, 100 );
435
436                     sprintf( psz_bands, "%.1f %.1f %.1f %.1f %.1f %.1f %.1f "
437                                         "%.1f %.1f %.1f",
438                                         eqz_preset_10b[i]->f_amp[0],
439                                         eqz_preset_10b[i]->f_amp[1],
440                                         eqz_preset_10b[i]->f_amp[2],
441                                         eqz_preset_10b[i]->f_amp[3],
442                                         eqz_preset_10b[i]->f_amp[4],
443                                         eqz_preset_10b[i]->f_amp[5],
444                                         eqz_preset_10b[i]->f_amp[6],
445                                         eqz_preset_10b[i]->f_amp[7],
446                                         eqz_preset_10b[i]->f_amp[8],
447                                         eqz_preset_10b[i]->f_amp[9] );
448
449                     var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT |
450                                                             VLC_VAR_DOINHERIT );
451                     var_Create( p_object, "equalizer-bands", VLC_VAR_STRING |
452                                                             VLC_VAR_DOINHERIT );
453                     var_SetFloat( p_object, "equalizer-preamp",
454                                                 eqz_preset_10b[i]->f_preamp );
455                     var_SetString( p_object, "equalizer-bands", psz_bands );
456                 }
457             }
458         }
459         free( psz_preset );
460         vlc_object_release( p_object );
461     }
462
463     [self equalizerUpdated];
464
465 }
466
467
468 - (id)getSliderByIndex:(int)index
469 {
470         switch(index)
471         {
472                 case 0 : return o_slider_band1;
473                 case 1 : return o_slider_band2;
474                 case 2 : return o_slider_band3;
475                 case 3 : return o_slider_band4;
476                 case 4 : return o_slider_band5;
477                 case 5 : return o_slider_band6;
478                 case 6 : return o_slider_band7;
479                 case 7 : return o_slider_band8;
480                 case 8 : return o_slider_band9;
481                 case 9 : return o_slider_band10;
482                 default : return nil;
483         }
484 }
485
486 - (void)setBandSlidersValues:(float *)values
487 {
488         int i = 0;
489         for (i = 0 ; i<= 9 ; i++)
490         {
491                 [self setValue:values[i] forSlider:i];
492         }
493 }
494
495 - (void)initBandSliders
496 {
497         int i = 0;
498         for (i = 0 ; i< 9 ; i++)
499         {
500                 [self setValue:0.0 forSlider:i];
501         }
502 }
503
504 - (void)setValue:(float)value forSlider:(int)index
505 {
506         id slider = [self getSliderByIndex:index];
507         
508         if (slider != nil)
509         {
510                 [slider setFloatValue:value];
511         }
512 }
513
514 @end