mirror of https://code.videolan.org/videolan/vlc
Add audiobargraph plugin (audio part)
Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
This commit is contained in:
parent
aa6665a322
commit
8e2f99001d
|
@ -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])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,336 @@
|
|||
/*****************************************************************************
|
||||
* audiobargraph_a.c : audiobargraph audio plugin for vlc
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2002-2006 the VideoLAN team
|
||||
* $Id$
|
||||
*
|
||||
* Authors: Clement CHESNIN <clement.chesnin@gmail.com>
|
||||
* Philippe COENT <philippe.coent@tdf.fr>
|
||||
*
|
||||
* 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 <vlc_common.h>
|
||||
#include <vlc_plugin.h>
|
||||
#include <vlc_aout.h>
|
||||
#include <vlc_filter.h>
|
||||
|
||||
#include <vlc_network.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
#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; i<nbChannels; i++) {
|
||||
i_value[i] = 0;
|
||||
}
|
||||
|
||||
/* 1 - Compute the peack values */
|
||||
for ( i = 0 ; i < (int)(p_in_buf->i_nb_samples); i++ )
|
||||
{
|
||||
for (j=0; j<nbChannels; j++) {
|
||||
ch = (*p_sample++);
|
||||
if (ch > 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<nbChannels; i++) {
|
||||
value[i] = abs(i_value[i]*100);
|
||||
if ( value[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 );
|
||||
}
|
Loading…
Reference in New Issue