1 /*****************************************************************************
2 * audiobargraph_a.c : audiobargraph audio plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
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 it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
35 #include <vlc_filter.h>
39 #define BARGRAPH_TEXT N_("Defines if BarGraph information should be sent")
40 #define BARGRAPH_LONGTEXT N_("Defines if BarGraph information should be sent. "\
41 "1 if the information should be sent, 0 otherwise (default 1)." )
42 #define BARGRAPH_REPETITION_TEXT N_("Sends the barGraph information every n audio packets")
43 #define BARGRAPH_REPETITION_LONGTEXT N_("Defines how often the barGraph information should be sent. "\
44 "Sends the barGraph information every n audio packets (default 4)." )
45 #define SILENCE_TEXT N_("Defines if silence alarm information should be sent")
46 #define SILENCE_LONGTEXT N_("Defines if silence alarm information should be sent. "\
47 "1 if the information should be sent, 0 otherwise (default 1)." )
48 #define TIME_WINDOW_TEXT N_("Time window to use in ms")
49 #define TIME_WINDOW_LONGTEXT N_("Time Window during when the audio level is measured in ms for silence detection. "\
50 "If the audio level is under the threshold during this time, "\
51 "an alarm is sent (default 5000)." )
52 #define ALARM_THRESHOLD_TEXT N_("Minimum Audio level to raise the alarm")
53 #define ALARM_THRESHOLD_LONGTEXT N_("Threshold to be attained to raise an alarm. "\
54 "If the audio level is under the threshold during this time, "\
55 "an alarm is sent (default 0.1)." )
56 #define REPETITION_TIME_TEXT N_("Time between two alarm messages in ms" )
57 #define REPETITION_TIME_LONGTEXT N_("Time between two alarm messages in ms. "\
58 "This value is used to avoid alarm saturation (default 2000)." )
60 #define CFG_PREFIX "audiobargraph_a-"
62 /*****************************************************************************
64 *****************************************************************************/
65 static int Open( vlc_object_t
* );
66 static void Close( vlc_object_t
* );
67 static block_t
*DoWork( filter_t
*, block_t
* );
70 set_description( N_("Audio part of the BarGraph function") )
71 set_shortname( N_("Audiobar Graph") )
72 set_capability( "audio filter", 0 )
73 set_category( CAT_AUDIO
)
74 set_subcategory( SUBCAT_AUDIO_AFILTER
)
76 add_obsolete_string( CFG_PREFIX
"address" )
77 add_obsolete_integer( CFG_PREFIX
"port" )
78 add_integer( CFG_PREFIX
"bargraph", 1, BARGRAPH_TEXT
, BARGRAPH_LONGTEXT
, false )
79 add_integer( CFG_PREFIX
"bargraph_repetition", 4, BARGRAPH_REPETITION_TEXT
, BARGRAPH_REPETITION_LONGTEXT
, false )
80 add_integer( CFG_PREFIX
"silence", 1, SILENCE_TEXT
, SILENCE_LONGTEXT
, false )
81 add_integer( CFG_PREFIX
"time_window", 5000, TIME_WINDOW_TEXT
, TIME_WINDOW_LONGTEXT
, false )
82 add_float( CFG_PREFIX
"alarm_threshold", 0.1, ALARM_THRESHOLD_TEXT
, ALARM_THRESHOLD_LONGTEXT
, false )
83 add_integer( CFG_PREFIX
"repetition_time", 2000, REPETITION_TIME_TEXT
, REPETITION_TIME_LONGTEXT
, false )
84 add_obsolete_integer( CFG_PREFIX
"connection_reset" )
86 set_callbacks( Open
, Close
)
89 typedef struct ValueDate_t
{
92 struct ValueDate_t
* next
;
98 int bargraph_repetition
;
101 float alarm_threshold
;
110 /*****************************************************************************
111 * Open: open the visualizer
112 *****************************************************************************/
113 static int Open( vlc_object_t
*p_this
)
115 filter_t
*p_filter
= (filter_t
*)p_this
;
116 filter_sys_t
*p_sys
= p_filter
->p_sys
= malloc( sizeof( *p_sys
) );
120 p_sys
->bargraph
= var_CreateGetInteger( p_filter
, CFG_PREFIX
"bargraph" );
121 p_sys
->bargraph_repetition
= var_CreateGetInteger( p_filter
, CFG_PREFIX
"bargraph_repetition" );
122 p_sys
->silence
= var_CreateGetInteger( p_filter
, CFG_PREFIX
"silence" );
123 p_sys
->time_window
= var_CreateGetInteger( p_filter
, CFG_PREFIX
"time_window" );
124 p_sys
->alarm_threshold
= var_CreateGetFloat( p_filter
, CFG_PREFIX
"alarm_threshold" );
125 p_sys
->repetition_time
= var_CreateGetInteger( p_filter
, CFG_PREFIX
"repetition_time" );
130 p_sys
->lastAlarm
= 0;
132 p_filter
->fmt_in
.audio
.i_format
= VLC_CODEC_FL32
;
133 p_filter
->fmt_out
.audio
= p_filter
->fmt_in
.audio
;
134 p_filter
->pf_audio_filter
= DoWork
;
136 var_Create( p_filter
->p_libvlc
, "audiobargraph_v-alarm", VLC_VAR_BOOL
);
137 var_Create( p_filter
->p_libvlc
, "audiobargraph_v-i_values", VLC_VAR_STRING
);
142 /*****************************************************************************
143 * DoWork: treat an audio buffer
144 ****************************************************************************/
145 static block_t
*DoWork( filter_t
*p_filter
, block_t
*p_in_buf
)
147 filter_sys_t
*p_sys
= p_filter
->p_sys
;
149 float *p_sample
= (float *)p_in_buf
->p_buffer
;
150 float i_value
[AOUT_CHAN_MAX
];
153 ValueDate_t
* current
= NULL
;
157 int nbChannels
= aout_FormatNbChannels( &p_filter
->fmt_in
.audio
);
159 for (i
=0; i
<nbChannels
; i
++) {
163 /* 1 - Compute the peack values */
164 for ( i
= 0 ; i
< (int)(p_in_buf
->i_nb_samples
); i
++ )
166 for (int j
= 0; j
<nbChannels
; j
++) {
174 max
= powf( max
, 2 );
176 if (p_sys
->silence
) {
177 /* 2 - store the new value */
178 ValueDate_t
*new = xmalloc(sizeof(*new));
180 new->date
= p_in_buf
->i_pts
;
182 if (p_sys
->last
!= NULL
) {
183 p_sys
->last
->next
= new;
186 if (p_sys
->first
== NULL
) {
190 /* 3 - delete too old values */
191 while (p_sys
->first
->date
< (new->date
- (p_sys
->time_window
*1000))) {
192 p_sys
->started
= 1; // we have enough values to compute a valid total
193 current
= p_sys
->first
;
194 p_sys
->first
= p_sys
->first
->next
;
198 /* If last message was sent enough time ago */
199 if ((p_sys
->started
) && (p_in_buf
->i_pts
> p_sys
->lastAlarm
+ (p_sys
->repetition_time
*1000))) {
201 /* 4 - compute the RMS */
202 current
= p_sys
->first
;
204 while (current
!= NULL
) {
205 sum
+= current
->value
;
207 current
= current
->next
;
212 /* 5 - compare it to the threshold */
213 var_SetBool(p_filter
->p_libvlc
, "audiobargraph_v-alarm",
214 sum
< p_sys
->alarm_threshold
);
216 p_sys
->lastAlarm
= p_in_buf
->i_pts
;
220 /*for (i=0; i<nbChannels; i++) {
221 value[i] = abs(i_value[i]*100);
222 if ( value[i] > p_sys->value[i] - 6 )
223 p_sys->value[i] = value[i];
225 p_sys->value[i] = p_sys->value[i] - 6;
228 if (p_sys
->bargraph
) {
229 /* 6 - sent the message with the values for the BarGraph */
230 if ((nbChannels
> 0) && (p_sys
->counter
%(p_sys
->bargraph_repetition
) == 0)) {
234 for (i
= 0; i
< nbChannels
; i
++) {
235 if (j
>= sizeof (message
))
237 j
+= snprintf(message
+ j
, sizeof (message
),"%f:", i_value
[i
]);
241 msg_Dbg( p_filter
, "values: %s", message
);
243 var_SetString(p_filter
->p_libvlc
, "audiobargraph_v-i_values",
248 if (++p_sys
->counter
> p_sys
->bargraph_repetition
*100)
254 /*****************************************************************************
255 * Close: close the plugin
256 *****************************************************************************/
257 static void Close( vlc_object_t
*p_this
)
259 filter_t
* p_filter
= (filter_t
*)p_this
;
260 filter_sys_t
*p_sys
= p_filter
->p_sys
;
262 var_Destroy( p_filter
->p_libvlc
, "audiobargraph_v-i_values" );
263 var_Destroy( p_filter
->p_libvlc
, "audiobargraph_v-alarm" );
265 while (p_sys
->first
!= NULL
) {
266 ValueDate_t
*current
= p_sys
->first
;
267 p_sys
->first
= p_sys
->first
->next
;