From 8e2f99001d213405faea981a76a7ff32a5334591 Mon Sep 17 00:00:00 2001 From: Clement Chesnin Date: Sat, 21 Nov 2009 12:45:12 +0200 Subject: [PATCH] Add audiobargraph plugin (audio part) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont --- configure.ac | 4 +- modules/audio_filter/Modules.am | 1 + modules/audio_filter/audiobargraph_a.c | 336 +++++++++++++++++++++++++ 3 files changed, 340 insertions(+), 1 deletion(-) create mode 100755 modules/audio_filter/audiobargraph_a.c diff --git a/configure.ac b/configure.ac index ae392fbfbe..e4b7155fb3 100644 --- a/configure.ac +++ b/configure.ac @@ -733,7 +733,7 @@ AC_CHECK_LIB(m,pow,[ VLC_ADD_LIBS([avcodec avformat swscale postproc ffmpegaltivec i420_rgb faad twolame equalizer spatializer param_eq libvlccore freetype mod mpc dmo quicktime realaudio realvideo opengl],[-lm]) ]) AC_CHECK_LIB(m,sqrt,[ - VLC_ADD_LIBS([headphone_channel_mixer normvol speex mono colorthres extract],[-lm]) + VLC_ADD_LIBS([headphone_channel_mixer normvol audiobargraph_a speex mono colorthres extract],[-lm]) ]) AC_CHECK_LIB(m,ceil,[ VLC_ADD_LIBS([hotkeys mosaic swscale_omap],[-lm]) @@ -1272,6 +1272,7 @@ if test "${SYS}" != "mingwce"; then VLC_ADD_PLUGIN([dolby_surround_decoder]) VLC_ADD_PLUGIN([headphone_channel_mixer]) VLC_ADD_PLUGIN([normvol]) + VLC_ADD_PLUGIN([audiobargraph_a]) VLC_ADD_PLUGIN([equalizer]) VLC_ADD_PLUGIN([param_eq]) VLC_ADD_PLUGIN([scaletempo]) @@ -1290,6 +1291,7 @@ if test "${SYS}" = "mingwce"; then VLC_ADD_PLUGIN([simple_channel_mixer]) VLC_ADD_PLUGIN([headphone_channel_mixer]) VLC_ADD_PLUGIN([normvol]) + VLC_ADD_PLUGIN([audiobargraph_a]) VLC_ADD_PLUGIN([a52tospdif]) VLC_ADD_PLUGIN([dtstospdif]) VLC_ADD_PLUGIN([i420_yuy2]) diff --git a/modules/audio_filter/Modules.am b/modules/audio_filter/Modules.am index 25a830f562..69303b9fb7 100644 --- a/modules/audio_filter/Modules.am +++ b/modules/audio_filter/Modules.am @@ -1,6 +1,7 @@ SUBDIRS = channel_mixer converter resampler spatializer SOURCES_equalizer = equalizer.c equalizer_presets.h SOURCES_normvol = normvol.c +SOURCES_audiobargraph_a = audiobargraph_a.c SOURCES_param_eq = param_eq.c SOURCES_scaletempo = scaletempo.c SOURCES_chorus_flanger = chorus_flanger.c diff --git a/modules/audio_filter/audiobargraph_a.c b/modules/audio_filter/audiobargraph_a.c new file mode 100755 index 0000000000..4973ded76d --- /dev/null +++ b/modules/audio_filter/audiobargraph_a.c @@ -0,0 +1,336 @@ +/***************************************************************************** + * audiobargraph_a.c : audiobargraph audio plugin for vlc + ***************************************************************************** + * Copyright (C) 2002-2006 the VideoLAN team + * $Id$ + * + * Authors: Clement CHESNIN + * Philippe COENT + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include +#include + + + +#define ADDRESS_TEXT N_("TCP address to use (default localhost)") +#define ADDRESS_LONGTEXT N_("TCP address to use to communicate with the video "\ + "part of the Bar Graph (default localhost)." \ + "In the case of bargraph incrustation, use localhost." ) +#define PORT_TEXT N_("TCP port to use (default 12345)") +#define PORT_LONGTEXT N_("TCP port to use to communicate with the video "\ + "part of the Bar Graph (default 12345)." \ + "Use the same port as the one used in the rc interface." ) +#define BARGRAPH_TEXT N_("Defines if BarGraph information should be send (default 1)") +#define BARGRAPH_LONGTEXT N_("Defines if BarGraph information should be send. "\ + "1 if the information should be sent, 0 otherwise (default 1)." ) +#define BARGRAPH_REPETITION_TEXT N_("Sends the barGraph information every n audio packets (default 4)") +#define BARGRAPH_REPETITION_LONGTEXT N_("Defines how often the barGraph information should be sent. "\ + "Sends the barGraph information every n audio packets (default 4)." ) +#define SILENCE_TEXT N_("Defines if silence alarm information should be send (default 1)") +#define SILENCE_LONGTEXT N_("Defines if silence alarm information should be send. "\ + "1 if the information should be sent, 0 otherwise (default 1)." ) +#define TIME_WINDOW_TEXT N_("Time window to use in ms (default 5000)") +#define TIME_WINDOW_LONGTEXT N_("Time Window during when the audio level is measured in ms for silence detection. "\ + "If the audio level is under the threshold during this time, "\ + "an alarm is sent (default 5000)." ) +#define ALARM_THRESHOLD_TEXT N_("Minimum Audio level to raise the alarm (default 0.1)") +#define ALARM_THRESHOLD_LONGTEXT N_("Threshold to be attained to raise an alarm. "\ + "If the audio level is under the threshold during this time, "\ + "an alarm is sent (default 0.1)." ) +#define REPETITION_TIME_TEXT N_("Time between two alamr messages in ms (default 2000)" ) +#define REPETITION_TIME_LONGTEXT N_("Time between two alarm messages in ms. "\ + "This value is used to avoid alarm saturation (default 2000)." ) +#define CONNECTION_RESET_TEXT N_("Force connection reset regularly (default 1)" ) +#define CONNECTION_RESET_LONGTEXT N_("Defines if the TCP connection should be reset. "\ + "This is to be used when using with audiobargraph_v (default 1)." ) + +#define CFG_PREFIX "audiobargraph_a-" + +/***************************************************************************** + * Module descriptor + *****************************************************************************/ +static int Open( vlc_object_t * ); +static void Close( vlc_object_t * ); +static block_t *DoWork( filter_t *, block_t * ); + +vlc_module_begin () + set_description( N_("Audio part of the BarGraph function") ) + set_shortname( N_("audiobargraph_a") ) + set_capability( "audio filter", 0 ) + set_category( CAT_AUDIO ) + set_subcategory( SUBCAT_AUDIO_AFILTER ) + + add_string( CFG_PREFIX "address", "localhost", NULL, ADDRESS_TEXT, ADDRESS_LONGTEXT, false ) + add_integer( CFG_PREFIX "port", 12345, NULL, PORT_TEXT, PORT_LONGTEXT, false ) + add_integer( CFG_PREFIX "bargraph", 1, NULL, BARGRAPH_TEXT, BARGRAPH_LONGTEXT, false ) + add_integer( CFG_PREFIX "bargraph_repetition", 4, NULL, BARGRAPH_REPETITION_TEXT, BARGRAPH_REPETITION_LONGTEXT, false ) + add_integer( CFG_PREFIX "silence", 1, NULL, SILENCE_TEXT, SILENCE_LONGTEXT, false ) + add_integer( CFG_PREFIX "time_window", 5000, NULL, TIME_WINDOW_TEXT, TIME_WINDOW_LONGTEXT, false ) + add_float( CFG_PREFIX "alarm_threshold", 0.1, NULL, ALARM_THRESHOLD_TEXT, ALARM_THRESHOLD_LONGTEXT, false ) + add_integer( CFG_PREFIX "repetition_time", 2000, NULL, REPETITION_TIME_TEXT, REPETITION_TIME_LONGTEXT, false ) + add_integer( CFG_PREFIX "connection_reset", 1, NULL, CONNECTION_RESET_TEXT, CONNECTION_RESET_LONGTEXT, false ) + + set_callbacks( Open, Close ) +vlc_module_end () + +typedef struct ValueDate_t { + float value; + mtime_t date; + struct ValueDate_t* next; +} ValueDate_t; + +struct filter_sys_t +{ + char* address; + int port; + int bargraph; + int bargraph_repetition; + int silence; + int time_window; + float alarm_threshold; + int repetition_time; + int connection_reset; + int TCPconnection; + int counter; + int nbChannels; + ValueDate_t* first; + ValueDate_t* last; + int started; + mtime_t lastAlarm; +}; + +/***************************************************************************** + * Open: open the visualizer + *****************************************************************************/ +static int Open( vlc_object_t *p_this ) +{ + filter_t *p_filter = (filter_t *)p_this; + filter_sys_t *p_sys; + + if ( !AOUT_FMTS_SIMILAR( &p_filter->fmt_in.audio, &p_filter->fmt_out.audio ) ) + { + msg_Err( p_filter, "input and output formats are not similar" ); + return VLC_EGENERIC; + } + + if( p_filter->fmt_in.audio.i_format != VLC_CODEC_FL32 || + p_filter->fmt_out.audio.i_format != VLC_CODEC_FL32 ) + { + p_filter->fmt_in.audio.i_format = VLC_CODEC_FL32; + p_filter->fmt_out.audio.i_format = VLC_CODEC_FL32; + msg_Warn( p_filter, "bad input or output format" ); + } + + p_filter->pf_audio_filter = DoWork; + + p_sys = p_filter->p_sys = malloc( sizeof( *p_sys ) ); + if( !p_sys ) + return VLC_ENOMEM; + + p_sys->bargraph = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-bargraph" ); + p_sys->bargraph_repetition = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-bargraph_repetition" ); + p_sys->silence = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-silence" ); + p_sys->address = var_CreateGetStringCommand( p_filter, "audiobargraph_a-address" ); + p_sys->port = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-port" ); + p_sys->time_window = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-time_window" ); + p_sys->alarm_threshold = var_CreateGetFloatCommand( p_filter, "audiobargraph_a-alarm_threshold" ); + p_sys->repetition_time = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-repetition_time" ); + p_sys->connection_reset = var_CreateGetIntegerCommand( p_filter, "audiobargraph_a-connection_reset" ); + if ((p_sys->TCPconnection = net_ConnectTCP(p_this,p_sys->address,p_sys->port)) == -1) { + free(p_sys); + return VLC_EGENERIC; + } + p_sys->counter = 0; + p_sys->nbChannels = 0; + p_sys->first = NULL; + p_sys->last = NULL; + p_sys->started = 0; + p_sys->lastAlarm = 0; + + return VLC_SUCCESS; +} + +/***************************************************************************** + * DoWork: treat an audio buffer + ****************************************************************************/ +static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf ) +{ + filter_sys_t *p_sys = p_filter->p_sys; + int i, j; + float *p_sample = (float *)p_in_buf->p_buffer; + float *i_value = NULL; + float ch; + float max = 0.0; + //char *message = (char*)malloc(255*sizeof(char)); + char message[255]; + int nbChannels = 0; + ValueDate_t* new = NULL; + ValueDate_t* current = NULL; + float sum; + int count = 0; + int i_ret; + + nbChannels = aout_FormatNbChannels( &p_filter->fmt_in.audio ); + p_sys->nbChannels = nbChannels; + + i_value = (float*)malloc(nbChannels * sizeof(float)); + + for (i=0; ii_nb_samples); i++ ) + { + for (j=0; j i_value[j]) + i_value[j] = ch; + if (ch > max) + max = ch; + } + } + max = pow( max, 2 ); + + if (p_sys->silence) { + /* 2 - store the new value */ + new = (ValueDate_t*)malloc(sizeof(ValueDate_t)); + new->value = max; + new->date = p_in_buf->i_pts; + new->next = NULL; + if (p_sys->last != NULL) { + p_sys->last->next = new; + } + p_sys->last = new; + if (p_sys->first == NULL) { + p_sys->first = new; + } + + /* 3 - delete too old values */ + while (p_sys->first->date < (new->date - (p_sys->time_window*1000))) { + p_sys->started = 1; // we have enough values to compute a valid total + current = p_sys->first; + p_sys->first = p_sys->first->next; + free(current); + } + + /* If last message was sent enough time ago */ + if ((p_sys->started) && (p_in_buf->i_pts > p_sys->lastAlarm + (p_sys->repetition_time*1000))) { + + /* 4 - compute the RMS */ + current = p_sys->first; + sum = 0.0; + while (current != NULL) { + sum += current->value; + count ++; + current = current->next; + } + sum = sum / count; + sum = sqrt(sum); + + /* 5 - compare it to the threshold */ + if (sum < p_sys->alarm_threshold) { + i=1; + } else { + i=0; + } + snprintf(message,255,"@audiobargraph_v audiobargraph_v-alarm %d\n",i); + + msg_Dbg( p_filter, "message alarm : %s", message ); + //TCPconnection = net_ConnectTCP(p_filter,p_sys->address,p_sys->port); + net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message)); + //net_Close(TCPconnection); + + p_sys->lastAlarm = p_in_buf->i_pts; + } + } + + /*for (i=0; i p_sys->value[i] - 6 ) + p_sys->value[i] = value[i]; + else + p_sys->value[i] = p_sys->value[i] - 6; + }*/ + + if (p_sys->bargraph) { + /* 6 - sent the message with the values for the BarGraph */ + if ((nbChannels > 0) && (p_sys->counter%(p_sys->bargraph_repetition) == 0)) { + j=snprintf(message,255,"@audiobargraph_v audiobargraph_v-i_values "); + for (i=0; i<(nbChannels-1); i++) { + j+=snprintf(message+j,255,"%f:", i_value[i]); + } + snprintf(message+j,255,"%f\n", i_value[nbChannels-1]); + msg_Dbg( p_filter, "message values : %s", message ); + + //test = send(p_sys->TCPconnection,message,strlen(message),0); + //net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message)); + + i_ret= net_Write(p_filter, p_sys->TCPconnection, NULL, message, strlen(message)); + + } + } + + free(i_value); + + if (p_sys->counter > p_sys->bargraph_repetition*100) { + if (p_sys->connection_reset) { + net_Close(p_sys->TCPconnection); + p_sys->TCPconnection = net_ConnectTCP(p_filter,p_sys->address,p_sys->port); + } + p_sys->counter = 0; + } + + //free(message); + p_sys->counter++; + + return p_in_buf; +} + +/***************************************************************************** + * Close: close the plugin + *****************************************************************************/ +static void Close( vlc_object_t *p_this ) +{ + filter_t * p_filter = (filter_t *)p_this; + filter_sys_t *p_sys = p_filter->p_sys; + ValueDate_t* current; + + p_sys->last = NULL; + while (p_sys->first != NULL) { + current = p_sys->first; + p_sys->first = p_sys->first->next; + free(current); + } + net_Close(p_sys->TCPconnection); + free(p_sys->address); + //free(p_sys->value); + free( p_filter->p_sys ); +} -- 2.39.2