Remove legacy parameter from add_string()
[vlc/asuraparaju-public.git] / modules / audio_filter / audiobargraph_a.c
blobf8fea543894b5d5aa722ed2d33ff3619855c1e10
1 /*****************************************************************************
2 * audiobargraph_a.c : audiobargraph audio plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2006 the VideoLAN team
5 * $Id$
7 * Authors: Clement CHESNIN <clement.chesnin@gmail.com>
8 * Philippe COENT <philippe.coent@tdf.fr>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_aout.h>
35 #include <vlc_filter.h>
37 #include <vlc_network.h>
38 #include <math.h>
42 #define ADDRESS_TEXT N_("TCP address to use (default localhost)")
43 #define ADDRESS_LONGTEXT N_("TCP address to use to communicate with the video "\
44 "part of the Bar Graph (default localhost)." \
45 "In the case of bargraph incrustation, use localhost." )
46 #define PORT_TEXT N_("TCP port to use (default 12345)")
47 #define PORT_LONGTEXT N_("TCP port to use to communicate with the video "\
48 "part of the Bar Graph (default 12345)." \
49 "Use the same port as the one used in the rc interface." )
50 #define BARGRAPH_TEXT N_("Defines if BarGraph information should be sent (default 1)")
51 #define BARGRAPH_LONGTEXT N_("Defines if BarGraph information should be sent. "\
52 "1 if the information should be sent, 0 otherwise (default 1)." )
53 #define BARGRAPH_REPETITION_TEXT N_("Sends the barGraph information every n audio packets (default 4)")
54 #define BARGRAPH_REPETITION_LONGTEXT N_("Defines how often the barGraph information should be sent. "\
55 "Sends the barGraph information every n audio packets (default 4)." )
56 #define SILENCE_TEXT N_("Defines if silence alarm information should be sent (default 1)")
57 #define SILENCE_LONGTEXT N_("Defines if silence alarm information should be sent. "\
58 "1 if the information should be sent, 0 otherwise (default 1)." )
59 #define TIME_WINDOW_TEXT N_("Time window to use in ms (default 5000)")
60 #define TIME_WINDOW_LONGTEXT N_("Time Window during when the audio level is measured in ms for silence detection. "\
61 "If the audio level is under the threshold during this time, "\
62 "an alarm is sent (default 5000)." )
63 #define ALARM_THRESHOLD_TEXT N_("Minimum Audio level to raise the alarm (default 0.1)")
64 #define ALARM_THRESHOLD_LONGTEXT N_("Threshold to be attained to raise an alarm. "\
65 "If the audio level is under the threshold during this time, "\
66 "an alarm is sent (default 0.1)." )
67 #define REPETITION_TIME_TEXT N_("Time between two alarm messages in ms (default 2000)" )
68 #define REPETITION_TIME_LONGTEXT N_("Time between two alarm messages in ms. "\
69 "This value is used to avoid alarm saturation (default 2000)." )
70 #define CONNECTION_RESET_TEXT N_("Force connection reset regularly (default 1)" )
71 #define CONNECTION_RESET_LONGTEXT N_("Defines if the TCP connection should be reset. "\
72 "This is to be used when using with audiobargraph_v (default 1)." )
74 #define CFG_PREFIX "audiobargraph_a-"
76 /*****************************************************************************
77 * Module descriptor
78 *****************************************************************************/
79 static int Open( vlc_object_t * );
80 static void Close( vlc_object_t * );
81 static block_t *DoWork( filter_t *, block_t * );
83 vlc_module_begin ()
84 set_description( N_("Audio part of the BarGraph function") )
85 set_shortname( N_("audiobargraph_a") )
86 set_capability( "audio filter", 0 )
87 set_category( CAT_AUDIO )
88 set_subcategory( SUBCAT_AUDIO_AFILTER )
90 add_string( CFG_PREFIX "address", "localhost", ADDRESS_TEXT, ADDRESS_LONGTEXT, false )
91 add_integer( CFG_PREFIX "port", 12345, NULL, PORT_TEXT, PORT_LONGTEXT, false )
92 add_integer( CFG_PREFIX "bargraph", 1, NULL, BARGRAPH_TEXT, BARGRAPH_LONGTEXT, false )
93 add_integer( CFG_PREFIX "bargraph_repetition", 4, NULL, BARGRAPH_REPETITION_TEXT, BARGRAPH_REPETITION_LONGTEXT, false )
94 add_integer( CFG_PREFIX "silence", 1, NULL, SILENCE_TEXT, SILENCE_LONGTEXT, false )
95 add_integer( CFG_PREFIX "time_window", 5000, NULL, TIME_WINDOW_TEXT, TIME_WINDOW_LONGTEXT, false )
96 add_float( CFG_PREFIX "alarm_threshold", 0.1, NULL, ALARM_THRESHOLD_TEXT, ALARM_THRESHOLD_LONGTEXT, false )
97 add_integer( CFG_PREFIX "repetition_time", 2000, NULL, REPETITION_TIME_TEXT, REPETITION_TIME_LONGTEXT, false )
98 add_integer( CFG_PREFIX "connection_reset", 1, NULL, CONNECTION_RESET_TEXT, CONNECTION_RESET_LONGTEXT, false )
100 set_callbacks( Open, Close )
101 vlc_module_end ()
103 typedef struct ValueDate_t {
104 float value;
105 mtime_t date;
106 struct ValueDate_t* next;
107 } ValueDate_t;
109 struct filter_sys_t
111 char* address;
112 int port;
113 int bargraph;
114 int bargraph_repetition;
115 int silence;
116 int time_window;
117 float alarm_threshold;
118 int repetition_time;
119 int connection_reset;
120 int TCPconnection;
121 int counter;
122 int nbChannels;
123 ValueDate_t* first;
124 ValueDate_t* last;
125 int started;
126 mtime_t lastAlarm;
129 /*****************************************************************************
130 * Open: open the visualizer
131 *****************************************************************************/
132 static int Open( vlc_object_t *p_this )
134 filter_t *p_filter = (filter_t *)p_this;
135 filter_sys_t *p_sys;
137 if ( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) )
139 msg_Err( p_filter, "input and output formats are not similar" );
140 return VLC_EGENERIC;
143 if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 ||
144 p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 )
146 p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32;
147 p_filter->fmt_out.audio.i_format = VLC_CODEC_FL32;
148 msg_Warn( p_filter, "bad input or output format" );
151 p_filter->pf_audio_filter = DoWork;
153 p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) );
154 if( !p_sys )
155 return VLC_ENOMEM;
157 p_sys->bargraph = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-bargraph" );
158 p_sys->bargraph_repetition = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-bargraph_repetition" );
159 p_sys->silence = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-silence" );
160 p_sys->address = var_CreateGetStringCommand( p_filter, "audiobargraph_a-address" );
161 p_sys->port = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-port" );
162 p_sys->time_window = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-time_window" );
163 p_sys->alarm_threshold = var_CreateGetFloatCommand( p_filter, "audiobargraph_a-alarm_threshold" );
164 p_sys->repetition_time = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-repetition_time" );
165 p_sys->connection_reset = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-connection_reset" );
166 if ((p_sys->TCPconnection = net_ConnectTCP(p_this,p_sys->address,p_sys->port)) == -1) {
167 free(p_sys);
168 return VLC_EGENERIC;
170 p_sys->counter = 0;
171 p_sys->nbChannels = 0;
172 p_sys->first = NULL;
173 p_sys->last = NULL;
174 p_sys->started = 0;
175 p_sys->lastAlarm = 0;
177 return VLC_SUCCESS;
180 /*****************************************************************************
181 * DoWork: treat an audio buffer
182 ****************************************************************************/
183 static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf )
185 filter_sys_t *p_sys = p_filter->p_sys;
186 int i, j;
187 float *p_sample = (float *)p_in_buf->p_buffer;
188 float *i_value = NULL;
189 float ch;
190 float max = 0.0;
191 //char *message = (char*)malloc(255*sizeof(char));
192 char message[255];
193 int nbChannels = 0;
194 ValueDate_t* new = NULL;
195 ValueDate_t* current = NULL;
196 float sum;
197 int count = 0;
198 int i_ret;
200 nbChannels = aout_FormatNbChannels( &p_filter->fmt_in.audio );
201 p_sys->nbChannels = nbChannels;
203 i_value = (float*)malloc(nbChannels * sizeof(float));
205 for (i=0; i<nbChannels; i++) {
206 i_value[i] = 0;
209 /* 1 - Compute the peack values */
210 for ( i = 0 ; i < (int)(p_in_buf->i_nb_samples); i++ )
212 for (j=0; j<nbChannels; j++) {
213 ch = (*p_sample++);
214 if (ch > i_value[j])
215 i_value[j] = ch;
216 if (ch > max)
217 max = ch;
220 max = pow( max, 2 );
222 if (p_sys->silence) {
223 /* 2 - store the new value */
224 new = (ValueDate_t*)malloc(sizeof(ValueDate_t));
225 new->value = max;
226 new->date = p_in_buf->i_pts;
227 new->next = NULL;
228 if (p_sys->last != NULL) {
229 p_sys->last->next = new;
231 p_sys->last = new;
232 if (p_sys->first == NULL) {
233 p_sys->first = new;
236 /* 3 - delete too old values */
237 while (p_sys->first->date < (new->date - (p_sys->time_window*1000))) {
238 p_sys->started = 1; // we have enough values to compute a valid total
239 current = p_sys->first;
240 p_sys->first = p_sys->first->next;
241 free(current);
244 /* If last message was sent enough time ago */
245 if ((p_sys->started) && (p_in_buf->i_pts > p_sys->lastAlarm + (p_sys->repetition_time*1000))) {
247 /* 4 - compute the RMS */
248 current = p_sys->first;
249 sum = 0.0;
250 while (current != NULL) {
251 sum += current->value;
252 count ++;
253 current = current->next;
255 sum = sum / count;
256 sum = sqrt(sum);
258 /* 5 - compare it to the threshold */
259 if (sum < p_sys->alarm_threshold) {
260 i=1;
261 } else {
262 i=0;
264 snprintf(message,255,"@audiobargraph_v audiobargraph_v-alarm %d\n",i);
266 msg_Dbg( p_filter, "message alarm : %s", message );
267 //TCPconnection = net_ConnectTCP(p_filter,p_sys->address,p_sys->port);
268 net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message));
269 //net_Close(TCPconnection);
271 p_sys->lastAlarm = p_in_buf->i_pts;
275 /*for (i=0; i<nbChannels; i++) {
276 value[i] = abs(i_value[i]*100);
277 if ( value[i] > p_sys->value[i] - 6 )
278 p_sys->value[i] = value[i];
279 else
280 p_sys->value[i] = p_sys->value[i] - 6;
283 if (p_sys->bargraph) {
284 /* 6 - sent the message with the values for the BarGraph */
285 if ((nbChannels > 0) && (p_sys->counter%(p_sys->bargraph_repetition) == 0)) {
286 j=snprintf(message,255,"@audiobargraph_v audiobargraph_v-i_values ");
287 for (i=0; i<(nbChannels-1); i++) {
288 j+=snprintf(message+j,255,"%f:", i_value[i]);
290 snprintf(message+j,255,"%f\n", i_value[nbChannels-1]);
291 msg_Dbg( p_filter, "message values : %s", message );
293 //test = send(p_sys->TCPconnection,message,strlen(message),0);
294 //net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message));
296 i_ret= net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message));
301 free(i_value);
303 if (p_sys->counter > p_sys->bargraph_repetition*100) {
304 if (p_sys->connection_reset) {
305 net_Close(p_sys->TCPconnection);
306 p_sys->TCPconnection = net_ConnectTCP(p_filter,p_sys->address,p_sys->port);
308 p_sys->counter = 0;
311 //free(message);
312 p_sys->counter++;
314 return p_in_buf;
317 /*****************************************************************************
318 * Close: close the plugin
319 *****************************************************************************/
320 static void Close( vlc_object_t *p_this )
322 filter_t * p_filter = (filter_t *)p_this;
323 filter_sys_t *p_sys = p_filter->p_sys;
324 ValueDate_t* current;
326 p_sys->last = NULL;
327 while (p_sys->first != NULL) {
328 current = p_sys->first;
329 p_sys->first = p_sys->first->next;
330 free(current);
332 net_Close(p_sys->TCPconnection);
333 free(p_sys->address);
334 //free(p_sys->value);
335 free( p_filter->p_sys );