]> git.sesse.net Git - vlc/blob - modules/gui/macosx/equalizer.m
* fspanel usability fixes (forward-port of [18077]) plus some further clean up
[vlc] / modules / gui / macosx / equalizer.m
1 /*****************************************************************************
2  * equalizer.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2004 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 /// \bug [String] missing space
143         "equalizer filter twice. The effect will be sharper.")];
144     [o_ckb_enable setTitle: _NS("Enable")];
145     [o_ckb_enable setToolTip: _NS("Enable the equalizer. Bands can be set "
146         "manually or using a preset.")];
147     [o_fld_preamp setStringValue: _NS("Preamp")];
148
149     [o_popup_presets removeAllItems];
150     for( i = 0; i < 18 ; i++ )
151     {
152         [o_popup_presets insertItemWithTitle: _NS(preset_list_text[i]) atIndex: i];
153     }
154     [o_window setTitle: _NS("Equalizer")];
155
156         /*
157     [o_slider_band1 setFloatValue: 0];
158     [o_slider_band2 setFloatValue: 0];
159     [o_slider_band3 setFloatValue: 0];
160     [o_slider_band4 setFloatValue: 0];
161     [o_slider_band5 setFloatValue: 0];
162     [o_slider_band6 setFloatValue: 0];
163     [o_slider_band7 setFloatValue: 0];
164     [o_slider_band8 setFloatValue: 0];
165     [o_slider_band9 setFloatValue: 0];
166     [o_slider_band10 setFloatValue: 0];
167         */
168         [self initBandSliders];
169     [o_ckb_enable setState: NSOffState];
170     [o_ckb_2pass setState: NSOffState];
171 }
172
173 - (void)equalizerUpdated
174 {
175     intf_thread_t *p_intf = VLCIntf;
176     float f_preamp, f_band[10];
177     char *psz_bands, *psz_bands_init, *p_next;
178     vlc_bool_t b_2p;
179     int i;
180     vlc_bool_t b_enabled = GetFiltersStatus( p_intf, (char *)"equalizer" );
181     vlc_object_t *p_object = vlc_object_find( p_intf,
182                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
183
184     if( p_object == NULL )
185         p_object = vlc_object_find( p_intf,
186                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
187     if( p_object == NULL )
188         return;
189
190     var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT |
191                                                     VLC_VAR_DOINHERIT );
192     var_Create( p_object, "equalizer-bands", VLC_VAR_STRING |
193                                                     VLC_VAR_DOINHERIT );
194
195     f_preamp = var_GetFloat( p_object, "equalizer-preamp" );
196     psz_bands = var_GetString( p_object, "equalizer-bands" );
197
198     if( !strcmp( psz_bands, "" ) )
199         psz_bands = strdup( "0 0 0 0 0 0 0 0 0 0" );
200
201     b_2p = var_GetBool( p_object, "equalizer-2pass" );
202
203     vlc_object_release( p_object );
204
205 /* Set the preamp slider */
206     [o_slider_preamp setFloatValue: f_preamp];
207
208 /* Set the bands slider */
209     psz_bands_init = psz_bands;
210
211     for( i = 0; i < 10; i++ )
212     {
213         /* Read dB -20/20 */
214 #ifdef HAVE_STRTOF
215         f_band[i] = strtof( psz_bands, &p_next );
216 #else
217         f_band[i] = (float)strtod( psz_bands, &p_next );
218 #endif
219         if( !p_next || p_next == psz_bands ) break; /* strtof() failed */
220
221         if( !*psz_bands ) break; /* end of line */
222         psz_bands = p_next+1;
223     }
224     free( psz_bands_init );
225         [self setBandSlidersValues:f_band];
226
227         /*
228     [o_slider_band1 setFloatValue: f_band[0]];
229     [o_slider_band2 setFloatValue: f_band[1]];
230     [o_slider_band3 setFloatValue: f_band[2]];
231     [o_slider_band4 setFloatValue: f_band[3]];
232     [o_slider_band5 setFloatValue: f_band[4]];
233     [o_slider_band6 setFloatValue: f_band[5]];
234     [o_slider_band7 setFloatValue: f_band[6]];
235     [o_slider_band8 setFloatValue: f_band[7]];
236     [o_slider_band9 setFloatValue: f_band[8]];
237     [o_slider_band10 setFloatValue: f_band[9]];
238         */
239         
240 /* Set the the checkboxes */
241     if( b_enabled == VLC_TRUE )
242         [o_ckb_enable setState:NSOnState];
243     else
244         [o_ckb_enable setState:NSOffState];
245
246     [o_ckb_2pass setState:( ( b_2p == VLC_TRUE ) ? NSOnState : NSOffState )];
247 }
248
249 - (IBAction)bandSliderUpdated:(id)sender
250 {
251     intf_thread_t *p_intf = VLCIntf;
252     vlc_object_t *p_object = vlc_object_find( p_intf,
253                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
254     char psz_values[102];
255     memset( psz_values, 0, 102 );
256
257     if( p_object == NULL )
258         p_object = vlc_object_find( p_intf,
259                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
260     if( p_object == NULL )
261         return;
262
263     /* Write the new bands values */
264 /* TODO: write a generic code instead of ten times the same thing */
265
266     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band1 floatValue] );
267     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band2 floatValue] );
268     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band3 floatValue] );
269     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band4 floatValue] );
270     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band5 floatValue] );
271     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band6 floatValue] );
272     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band7 floatValue] );
273     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band8 floatValue] );
274     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band9 floatValue] );
275     sprintf( psz_values, "%s %.1f", psz_values, [o_slider_band10 floatValue] );
276
277     var_SetString( p_object, "equalizer-bands", psz_values );
278     vlc_object_release( p_object );
279 }
280
281 - (IBAction)changePreset:(id)sender
282 {
283     intf_thread_t *p_intf = VLCIntf;
284     int i;
285     vlc_object_t *p_object= vlc_object_find( p_intf,
286                                 VLC_OBJECT_AOUT, FIND_ANYWHERE );
287     char psz_values[102];
288     memset( psz_values, 0, 102 );
289
290     if( p_object == NULL )
291         p_object = vlc_object_find( p_intf,
292                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
293     if( p_object == NULL )
294         return;
295
296     var_SetString( p_object , "equalizer-preset" , preset_list[[sender indexOfSelectedItem]] );
297
298     for( i = 0; i < 10; i++ )
299         sprintf( psz_values, "%s %.1f", psz_values, eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[i] );
300     var_SetString( p_object, "equalizer-bands", psz_values );
301     var_SetFloat( p_object, "equalizer-preamp", eqz_preset_10b[[sender indexOfSelectedItem]]->f_preamp);
302
303     [o_slider_preamp setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_preamp];
304         /*
305     [o_slider_band1 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[0]];
306     [o_slider_band2 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[1]];
307     [o_slider_band3 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[2]];
308     [o_slider_band4 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[3]];
309     [o_slider_band5 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[4]];
310     [o_slider_band6 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[5]];
311     [o_slider_band7 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[6]];
312     [o_slider_band8 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[7]];
313     [o_slider_band9 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[8]];
314     [o_slider_band10 setFloatValue: eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp[9]];
315         */
316         [self setBandSlidersValues:(float *)eqz_preset_10b[[sender indexOfSelectedItem]]->f_amp];
317         
318     vlc_object_release( p_object );
319 }
320
321 - (IBAction)enable:(id)sender
322 {
323     ChangeFiltersString( VLCIntf, (char *)"equalizer", [sender state] );
324 }
325
326 - (IBAction)preampSliderUpdated:(id)sender
327 {
328     intf_thread_t *p_intf = VLCIntf;
329     float f_preamp = [sender floatValue] ;
330
331     vlc_object_t *p_object = vlc_object_find( p_intf,
332                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
333     if( p_object == NULL )
334         p_object = vlc_object_find( p_intf,
335                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
336     if( p_object == NULL )
337         return;
338
339     var_SetFloat( p_object, "equalizer-preamp", f_preamp );
340
341     vlc_object_release( p_object );
342 }
343
344 - (IBAction)toggleWindow:(id)sender
345 {
346     if( [o_window isVisible] )
347     {
348         [o_window orderOut:sender];
349         [o_btn_equalizer setState:NSOffState];
350     }
351     else
352     {
353         [o_window makeKeyAndOrderFront:sender];
354         [o_btn_equalizer setState:NSOnState];
355     }
356 }
357
358 - (IBAction)twopass:(id)sender
359 {
360     intf_thread_t *p_intf = VLCIntf;
361     vlc_bool_t b_2p = [sender state] ? VLC_TRUE : VLC_FALSE;
362     vlc_object_t *p_object= vlc_object_find( p_intf,
363                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
364     aout_instance_t *p_aout = (aout_instance_t *)p_object;
365     if( p_object == NULL )
366         p_object = vlc_object_find( p_intf,
367                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
368     if( p_object == NULL )
369         return;
370
371     var_SetBool( p_object, "equalizer-2pass", b_2p );
372     if( ( [o_ckb_enable state] ) && ( p_aout != NULL ) )
373     {
374        int i;
375         for( i = 0; i < p_aout->i_nb_inputs; i++ )
376         {
377             p_aout->pp_inputs[i]->b_restart = VLC_TRUE;
378         }
379     }
380
381     vlc_object_release( p_object );
382 }
383
384 - (void)windowWillClose:(NSNotification *)aNotification
385 {
386     [o_btn_equalizer setState: NSOffState];
387 }
388
389 - (void)awakeFromNib
390 {
391     int i;
392     vlc_object_t *p_object= vlc_object_find( VLCIntf,
393                                  VLC_OBJECT_AOUT, FIND_ANYWHERE );
394     if( p_object == NULL )
395                 p_object = vlc_object_find( VLCIntf,
396                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
397
398     [o_window setExcludedFromWindowsMenu: TRUE];
399
400     [self initStrings];
401
402     if( p_object )
403     {
404         char *psz_preset;
405
406         var_Create( p_object, "equalizer-preset", VLC_VAR_STRING |
407                                                         VLC_VAR_DOINHERIT );
408         psz_preset = var_GetString( p_object, "equalizer-preset" );
409
410         for( i = 0 ; i < 18 ; i++ )
411         {
412             if( !strcmp( preset_list[i], psz_preset ) )
413             {
414                 [o_popup_presets selectItemAtIndex: i];
415
416                 [o_slider_preamp setFloatValue: eqz_preset_10b[i]->f_preamp];
417                                 [self setBandSlidersValues: (float *)eqz_preset_10b[i]->f_amp];
418                                 
419                                 /*
420                 [o_slider_band1 setFloatValue: eqz_preset_10b[i]->f_amp[0]];
421                 [o_slider_band2 setFloatValue: eqz_preset_10b[i]->f_amp[1]];
422                 [o_slider_band3 setFloatValue: eqz_preset_10b[i]->f_amp[2]];
423                 [o_slider_band4 setFloatValue: eqz_preset_10b[i]->f_amp[3]];
424                 [o_slider_band5 setFloatValue: eqz_preset_10b[i]->f_amp[4]];
425                 [o_slider_band6 setFloatValue: eqz_preset_10b[i]->f_amp[5]];
426                 [o_slider_band7 setFloatValue: eqz_preset_10b[i]->f_amp[6]];
427                 [o_slider_band8 setFloatValue: eqz_preset_10b[i]->f_amp[7]];
428                 [o_slider_band9 setFloatValue: eqz_preset_10b[i]->f_amp[8]];
429                 [o_slider_band10 setFloatValue: eqz_preset_10b[i]->f_amp[9]];
430                                 */
431                                 
432                 if( strcmp( psz_preset, "flat" ) )
433                 {
434                     char psz_bands[100];
435                     memset( psz_bands, 0, 100 );
436
437                     sprintf( psz_bands, "%.1f %.1f %.1f %.1f %.1f %.1f %.1f "
438                                         "%.1f %.1f %.1f",
439                                         eqz_preset_10b[i]->f_amp[0],
440                                         eqz_preset_10b[i]->f_amp[1],
441                                         eqz_preset_10b[i]->f_amp[2],
442                                         eqz_preset_10b[i]->f_amp[3],
443                                         eqz_preset_10b[i]->f_amp[4],
444                                         eqz_preset_10b[i]->f_amp[5],
445                                         eqz_preset_10b[i]->f_amp[6],
446                                         eqz_preset_10b[i]->f_amp[7],
447                                         eqz_preset_10b[i]->f_amp[8],
448                                         eqz_preset_10b[i]->f_amp[9] );
449
450                     var_Create( p_object, "equalizer-preamp", VLC_VAR_FLOAT |
451                                                             VLC_VAR_DOINHERIT );
452                     var_Create( p_object, "equalizer-bands", VLC_VAR_STRING |
453                                                             VLC_VAR_DOINHERIT );
454                     var_SetFloat( p_object, "equalizer-preamp",
455                                                 eqz_preset_10b[i]->f_preamp );
456                     var_SetString( p_object, "equalizer-bands", psz_bands );
457                 }
458             }
459         }
460         free( psz_preset );
461         vlc_object_release( p_object );
462     }
463
464     [self equalizerUpdated];
465
466 }
467
468
469 - (id)getSliderByIndex:(int)index
470 {
471         switch(index)
472         {
473                 case 0 : return o_slider_band1;
474                 case 1 : return o_slider_band2;
475                 case 2 : return o_slider_band3;
476                 case 3 : return o_slider_band4;
477                 case 4 : return o_slider_band5;
478                 case 5 : return o_slider_band6;
479                 case 6 : return o_slider_band7;
480                 case 7 : return o_slider_band8;
481                 case 8 : return o_slider_band9;
482                 case 9 : return o_slider_band10;
483                 default : return nil;
484         }
485 }
486
487 - (void)setBandSlidersValues:(float *)values
488 {
489         int i = 0;
490         for (i = 0 ; i<= 9 ; i++)
491         {
492                 [self setValue:values[i] forSlider:i];
493         }
494 }
495
496 - (void)initBandSliders
497 {
498         int i = 0;
499         for (i = 0 ; i< 9 ; i++)
500         {
501                 [self setValue:0.0 forSlider:i];
502         }
503 }
504
505 - (void)setValue:(float)value forSlider:(int)index
506 {
507         id slider = [self getSliderByIndex:index];
508         
509         if (slider != nil)
510         {
511                 [slider setFloatValue:value];
512         }
513 }
514
515 @end