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