]> git.sesse.net Git - vlc/blob - modules/lua/libs/equalizer.c
lua: fix equalizer setting code
[vlc] / modules / lua / libs / equalizer.c
1 /*****************************************************************************
2  * equalizer.c
3  *****************************************************************************
4  * Copyright (C) 2011 VideoLAN and VLC authors
5  * $Id$
6  *
7  * Authors: Akash Mehrotra < mehrotra <dot> akash <at> gmail <dot> com >
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 #ifndef  _GNU_SOURCE
28 #   define  _GNU_SOURCE
29 #endif
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc_common.h>
36 #include <vlc_aout.h>
37 #include <vlc_aout_intf.h>
38 #include <vlc_input.h>
39 #include <vlc_charset.h>
40
41 #include "input.h"
42 #include "../libs.h"
43 #include "../vlc.h"
44 #include "playlist.h"
45 #include "../../audio_filter/equalizer_presets.h"
46
47 #if !defined WIN32
48 # include <locale.h>
49 #else
50 # include <windows.h>
51 #endif
52
53 #ifdef __APPLE__
54 #   include <string.h>
55 #   include <xlocale.h>
56 #endif
57
58
59 /*****************************************************************************
60 * Get the preamp level
61 *****************************************************************************/
62 static int vlclua_preamp_get( lua_State *L )
63 {
64     input_thread_t *p_input = vlclua_get_input_internal( L );
65     if( !p_input )
66         return 0;
67
68     audio_output_t *p_aout = input_GetAout( p_input );
69     vlc_object_release( p_input );
70
71     if( !p_aout)
72         return 0;
73
74     char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
75     if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL )
76     {
77         free( psz_af );
78         vlc_object_release( p_aout );
79         return 0;
80     }
81     free( psz_af );
82
83     lua_pushnumber( L, var_GetFloat( p_aout, "equalizer-preamp") );
84     vlc_object_release( p_aout );
85     return 1;
86 }
87
88
89 /*****************************************************************************
90 * Set the preamp level
91 *****************************************************************************/
92 static int vlclua_preamp_set( lua_State *L )
93 {
94     input_thread_t *p_input = vlclua_get_input_internal( L );
95     if( !p_input )
96         return 0;
97
98     audio_output_t *p_aout = input_GetAout( p_input );
99     vlc_object_release( p_input );
100     if( !p_aout )
101         return 0;
102
103     char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
104     if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL )
105     {
106         free( psz_af );
107         vlc_object_release( p_aout );
108         return 0;
109     }
110     free( psz_af );
111
112     var_SetFloat( p_aout, "equalizer-preamp", luaL_checknumber( L, 1 ) );
113     vlc_object_release( p_aout );
114     return 1;
115 }
116
117
118 /*****************************************************************************
119 Bands:
120 Band 0:  60 Hz
121 Band 1: 170 Hz
122 Band 2: 310 Hz
123 Band 3: 600 Hz
124 Band 4:  1 kHz
125 Band 5:  3 kHz
126 Band 6:  6 kHz
127 Band 7: 12 kHz
128 Band 8: 14 kHz
129 Band 9: 16 kHz
130 *****************************************************************************/
131 /*****************************************************************************
132 * Return EQ level for all bands as a Table
133 *****************************************************************************/
134 static int vlclua_equalizer_get( lua_State *L )
135 {
136     const unsigned bands = 10;
137     input_thread_t *p_input = vlclua_get_input_internal( L );
138     if( !p_input )
139         return 0;
140     audio_output_t *p_aout = input_GetAout( p_input );
141     vlc_object_release( p_input );
142     if( !p_aout )
143         return 0;
144
145     char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
146     if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL )
147     {
148         free( psz_af );
149         vlc_object_release( p_aout );
150         return 0;
151     }
152     free( psz_af );
153
154     char *psz_bands_origin, *psz_bands;
155     psz_bands_origin = psz_bands = var_GetNonEmptyString( p_aout, "equalizer-bands" );
156     if( !psz_bands )
157     {
158         vlc_object_release( p_aout );
159         return 0;
160     }
161
162     bool error = false;
163     locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
164     locale_t oldloc = uselocale (loc);
165     lua_newtable( L );
166     for( unsigned i = 0; i < bands; i++ )
167     {
168         float level = strtof( psz_bands, &psz_bands );
169         char *str;
170         if( asprintf( &str , "%f" , level ) == -1 )
171         {
172             error = true;
173             break;
174         }
175         lua_pushstring( L, str );
176         free(str);
177         if( asprintf( &str , "band id=\"%u\"", i ) == -1 )
178         {
179             error = true;
180             break;
181         }
182         lua_setfield( L , -2 , str );
183         free( str );
184     }
185
186     free( psz_bands_origin );
187     if( loc != (locale_t)0 )
188     {
189         uselocale (oldloc);
190         freelocale (loc);
191     }
192     vlc_object_release( p_aout );
193     return error ? 0 : 1;
194 }
195
196
197 /*****************************************************************************
198 * Set the equalizer level for the specified band
199 *****************************************************************************/
200 static int vlclua_equalizer_set( lua_State *L )
201 {
202     int bandid = luaL_checknumber( L, 1 );
203     if( bandid < 0 || bandid > 9)
204         return 0;
205     input_thread_t *p_input = vlclua_get_input_internal( L );
206     if( !p_input )
207         return 0;
208
209     audio_output_t *p_aout = input_GetAout( p_input );
210     vlc_object_release( p_input );
211     if( !p_aout )
212         return 0;
213
214     char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
215     if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL )
216     {
217         free( psz_af );
218         vlc_object_release( p_aout );
219         return 0;
220     }
221     free( psz_af );
222
223     float level = luaL_checknumber( L, 2 );
224     char *bands = var_GetString( p_aout, "equalizer-bands" );
225
226     locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
227     locale_t oldloc = uselocale (loc);
228     char *b = bands;
229     while( bandid > 0 )
230     {
231         float dummy = strtof( b, &b );
232         (void)dummy;
233         bandid--;
234     }
235     if( *b != '\0' )
236         *b++ = '\0';
237     float dummy = strtof( b, &b );
238     (void)dummy;
239
240     char *newstr;
241     if( asprintf( &newstr, "%s %.1f%s", bands, level, b ) != -1 )
242     {
243         var_SetString( p_aout, "equalizer-bands", newstr );
244         free( newstr );
245     }
246
247     if( loc != (locale_t)0 )
248     {
249         uselocale (oldloc);
250         freelocale (loc);
251     }
252     free( bands );
253     vlc_object_release( p_aout );
254     return 0;
255 }
256
257 /*****************************************************************************
258 * Set the preset specified by preset id
259 *****************************************************************************/
260 static int vlclua_equalizer_setpreset( lua_State *L )
261 {
262     int presetid = luaL_checknumber( L, 1 );
263     if( presetid >= NB_PRESETS || presetid < 0 )
264         return 0;
265     input_thread_t *p_input = vlclua_get_input_internal( L );
266     if( p_input )
267     {
268         audio_output_t *p_aout = input_GetAout( p_input );
269         vlc_object_release( p_input );
270         if( !p_aout )
271         {
272             return 0;
273         }
274         char *psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
275         if( !psz_af || strstr ( psz_af, "equalizer" ) == NULL )
276         {
277             free( psz_af );
278             vlc_object_release( p_aout );
279             return 0;
280         }
281         free( psz_af );
282         var_SetString( p_aout , "equalizer-preset" , preset_list[presetid] );
283         vlc_object_release( p_aout );
284         return 1;
285     }
286     return 0;
287 }
288  
289 /****************************************************************************
290 * Enable/disable Equalizer
291 *****************************************************************************/
292 static int vlclua_equalizer_enable ( lua_State *L )
293 {
294     playlist_t *p_playlist = vlclua_get_playlist_internal( L );
295     bool state = luaL_checkboolean ( L , 1 );
296     aout_EnableFilter( p_playlist, "equalizer", state );
297     return 0;
298 }
299 /*****************************************************************************
300 * Get preset names
301 *****************************************************************************/
302 static int vlclua_equalizer_get_presets( lua_State *L )
303 {
304     lua_newtable( L );
305     char *str;
306     for( int i = 0 ; i < NB_PRESETS ; i++ )
307     {
308         lua_pushstring( L, preset_list_text[i] );
309         if( asprintf( &str , "preset id=\"%d\"",i ) == -1 )
310             return 0;
311         lua_setfield( L , -2 , str );
312         free(str);
313     }
314     return 1;
315 }
316 static const luaL_Reg vlclua_equalizer_reg[] = {
317     { "preampget", vlclua_preamp_get },
318     { "preampset", vlclua_preamp_set },
319     { "equalizerget", vlclua_equalizer_get },
320     { "equalizerset", vlclua_equalizer_set },
321     { "enable", vlclua_equalizer_enable },
322     { "presets",vlclua_equalizer_get_presets },
323     { "setpreset", vlclua_equalizer_setpreset },
324     { NULL, NULL }
325 };
326
327
328 void luaopen_equalizer( lua_State *L )
329 {
330     lua_newtable( L );
331     luaL_register( L, NULL, vlclua_equalizer_reg );
332     lua_setfield( L, -2, "equalizer" );
333 }