SNR based voice detect

git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@452 05730e5d-ab1b-0410-a4ac-84af385074fa
This commit is contained in:
Thorvald Natvig 2007-05-28 12:40:01 +00:00
parent 060701b535
commit 19fdb33eef
4 changed files with 138 additions and 127 deletions

View File

@ -236,6 +236,11 @@ void AudioInput::encodeAudioFrame() {
double v = 20000.0 / g.s.iMinLoudness;
iArg = floor(20.0 * log10(v));
speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &iArg);
iArg = -45;
speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &iArg);
if (bHasSpeaker) {
if (sesEcho)
speex_echo_state_destroy(sesEcho);
@ -291,7 +296,17 @@ void AudioInput::encodeAudioFrame() {
max=abs(psSource[i]);
dPeakSignal=20.0*log10((max * 1.0L) / 32768.0L);
if (dPeakSignal > -20)
CloneSpeexPreprocessState *st=reinterpret_cast<CloneSpeexPreprocessState *>(sppPreprocess);
float Zframe = 0;
int freq_start = static_cast<int>(300.0f*2.f*st->ps_size/st->sampling_rate);
int freq_end = static_cast<int>(2000.0f*2.f*st->ps_size/st->sampling_rate);
for (int i=freq_start;i<freq_end;i++)
Zframe += st->zeta[i];
Zframe /= (freq_end-freq_start);
dSNR = Zframe;
if (dSNR > 1.0)
iIsSpeech = 1;
else
iIsSpeech = 0;

View File

@ -84,6 +84,7 @@ class AudioInput : public QThread {
int iBitrate;
double dPeakMic, dPeakSpeaker, dPeakSignal;
double dSNR;
bool isTransmitting() { return bPreviousVoice; };

View File

@ -32,125 +32,6 @@
#include "AudioInput.h"
#include "Global.h"
/** Speex echo cancellation state; sync from mdf.c in Speex distribution.
*/
typedef float spx_word16_t;
typedef float spx_word32_t;
typedef float spx_float_t;
typedef spx_word32_t spx_mem_t;
/** Speex echo cancellation state. */
struct CloneSpeexEchoState {
int frame_size; /**< Number of samples processed each time */
int window_size;
int M;
int cancel_count;
int adapted;
int saturated;
int screwed_up;
spx_int32_t sampling_rate;
spx_word16_t spec_average;
spx_word16_t beta0;
spx_word16_t beta_max;
spx_word32_t sum_adapt;
spx_word16_t leak_estimate;
spx_word16_t *e; /* scratch */
spx_word16_t *x; /* Far-end input buffer (2N) */
spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */
spx_word16_t *input; /* scratch */
spx_word16_t *y; /* scratch */
spx_word16_t *last_y;
spx_word16_t *Y; /* scratch */
spx_word16_t *E;
spx_word32_t *PHI; /* scratch */
spx_word32_t *W; /* (Background) filter weights */
spx_word16_t *foreground; /* Foreground filter weights */
spx_word32_t Davg1; /* 1st recursive average of the residual power difference */
spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */
spx_float_t Dvar1; /* Estimated variance of 1st estimator */
spx_float_t Dvar2; /* Estimated variance of 2nd estimator */
spx_word32_t *power; /* Power of the far-end signal */
spx_float_t *power_1;/* Inverse power of far-end */
spx_word16_t *wtmp; /* scratch */
spx_word32_t *Rf; /* scratch */
spx_word32_t *Yf; /* scratch */
spx_word32_t *Xf; /* scratch */
spx_word32_t *Eh;
spx_word32_t *Yh;
spx_float_t Pey;
spx_float_t Pyy;
spx_word16_t *window;
spx_word16_t *prop;
void *fft_table;
spx_word16_t memX, memD, memE;
spx_word16_t preemph;
spx_word16_t notch_radius;
spx_mem_t notch_mem[2];
};
/** Speex pre-processor state. */
struct CloneSpeexPreprocessState {
/* Basic info */
int frame_size; /**< Number of samples processed each time */
int ps_size; /**< Number of points in the power spectrum */
int sampling_rate; /**< Sampling rate of the input/output */
int nbands;
void *bank;
int denoise_enabled;
int vad_enabled;
int dereverb_enabled;
spx_word16_t reverb_decay;
spx_word16_t reverb_level;
spx_word16_t speech_prob_start;
spx_word16_t speech_prob_continue;
int noise_suppress;
int echo_suppress;
int echo_suppress_active;
CloneSpeexEchoState *echo_state;
spx_word16_t *frame; /**< Processing frame (2*ps_size) */
spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */
spx_word32_t *ps; /**< Current power spectrum */
spx_word16_t *gain2; /**< Adjusted gains */
spx_word16_t *gain_floor; /**< Minimum gain allowed */
spx_word16_t *window; /**< Analysis/Synthesis window */
spx_word32_t *noise; /**< Noise estimate */
spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */
spx_word32_t *old_ps; /**< Power spectrum for last frame */
spx_word16_t *gain; /**< Ephraim Malah gain */
spx_word16_t *prior; /**< A-priori SNR */
spx_word16_t *post; /**< A-posteriori SNR */
spx_word32_t *S; /**< Smoothed power spectrum */
spx_word32_t *Smin; /**< See Cohen paper */
spx_word32_t *Stmp; /**< See Cohen paper */
int *update_prob; /**< Propability of speech presence for noise update */
spx_word16_t *zeta; /**< Smoothed a priori SNR */
spx_word32_t *echo_noise;
spx_word32_t *residual_echo;
spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */
spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */
int agc_enabled;
float agc_level;
float loudness_accum;
float *loudness_weight; /**< Perceptual loudness curve */
float loudness; /**< Loudness estimate */
float agc_gain; /**< Current AGC gain */
int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */
float max_gain; /**< Maximum gain allowed */
float max_increase_step; /**< Maximum increase in gain from one frame to another */
float max_decrease_step; /**< Maximum decrease in gain from one frame to another */
float prev_loudness; /**< Loudness of previous frame */
float init_max; /**< Current gain limit during initialisation */
int nb_adapt; /**< Number of frames used for adaptation so far */
int was_speech;
int min_count; /**< Number of frames processed so far */
void *fft_lookup; /**< Lookup table for the FFT */
};
AudioEchoWidget::AudioEchoWidget(QWidget *p) : QGLWidget(p) {
setMinimumSize(100, 60);
mode = MODULUS;
@ -514,13 +395,7 @@ void AudioStats::on_Tick_timeout() {
txt.sprintf("%06.2f dB",ai->dPeakSignal);
qlSignalLevel->setText(txt);
float Zframe = 0;
int freq_start = static_cast<int>(300.0f*2.f*st->ps_size/st->sampling_rate);
int freq_end = static_cast<int>(2000.0f*2.f*st->ps_size/st->sampling_rate);
for (int i=freq_start;i<freq_end;i++)
Zframe += st->zeta[i];
Zframe /= (freq_end-freq_start);
txt.sprintf("%06.3f",Zframe);
txt.sprintf("%06.3f",ai->dSNR);
qlMicSNR->setText(txt);
txt.sprintf("%03.0f%%",nTalking ? 100.0 : 0.0);

View File

@ -27,6 +27,126 @@
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
/** Speex echo cancellation state; sync from mdf.c in Speex distribution.
*/
typedef float spx_word16_t;
typedef float spx_word32_t;
typedef float spx_float_t;
typedef spx_word32_t spx_mem_t;
/** Speex echo cancellation state. */
struct CloneSpeexEchoState {
int frame_size; /**< Number of samples processed each time */
int window_size;
int M;
int cancel_count;
int adapted;
int saturated;
int screwed_up;
spx_int32_t sampling_rate;
spx_word16_t spec_average;
spx_word16_t beta0;
spx_word16_t beta_max;
spx_word32_t sum_adapt;
spx_word16_t leak_estimate;
spx_word16_t *e; /* scratch */
spx_word16_t *x; /* Far-end input buffer (2N) */
spx_word16_t *X; /* Far-end buffer (M+1 frames) in frequency domain */
spx_word16_t *input; /* scratch */
spx_word16_t *y; /* scratch */
spx_word16_t *last_y;
spx_word16_t *Y; /* scratch */
spx_word16_t *E;
spx_word32_t *PHI; /* scratch */
spx_word32_t *W; /* (Background) filter weights */
spx_word16_t *foreground; /* Foreground filter weights */
spx_word32_t Davg1; /* 1st recursive average of the residual power difference */
spx_word32_t Davg2; /* 2nd recursive average of the residual power difference */
spx_float_t Dvar1; /* Estimated variance of 1st estimator */
spx_float_t Dvar2; /* Estimated variance of 2nd estimator */
spx_word32_t *power; /* Power of the far-end signal */
spx_float_t *power_1;/* Inverse power of far-end */
spx_word16_t *wtmp; /* scratch */
spx_word32_t *Rf; /* scratch */
spx_word32_t *Yf; /* scratch */
spx_word32_t *Xf; /* scratch */
spx_word32_t *Eh;
spx_word32_t *Yh;
spx_float_t Pey;
spx_float_t Pyy;
spx_word16_t *window;
spx_word16_t *prop;
void *fft_table;
spx_word16_t memX, memD, memE;
spx_word16_t preemph;
spx_word16_t notch_radius;
spx_mem_t notch_mem[2];
};
/** Speex pre-processor state. */
struct CloneSpeexPreprocessState {
/* Basic info */
int frame_size; /**< Number of samples processed each time */
int ps_size; /**< Number of points in the power spectrum */
int sampling_rate; /**< Sampling rate of the input/output */
int nbands;
void *bank;
int denoise_enabled;
int vad_enabled;
int dereverb_enabled;
spx_word16_t reverb_decay;
spx_word16_t reverb_level;
spx_word16_t speech_prob_start;
spx_word16_t speech_prob_continue;
int noise_suppress;
int echo_suppress;
int echo_suppress_active;
CloneSpeexEchoState *echo_state;
spx_word16_t *frame; /**< Processing frame (2*ps_size) */
spx_word16_t *ft; /**< Processing frame in freq domain (2*ps_size) */
spx_word32_t *ps; /**< Current power spectrum */
spx_word16_t *gain2; /**< Adjusted gains */
spx_word16_t *gain_floor; /**< Minimum gain allowed */
spx_word16_t *window; /**< Analysis/Synthesis window */
spx_word32_t *noise; /**< Noise estimate */
spx_word32_t *reverb_estimate; /**< Estimate of reverb energy */
spx_word32_t *old_ps; /**< Power spectrum for last frame */
spx_word16_t *gain; /**< Ephraim Malah gain */
spx_word16_t *prior; /**< A-priori SNR */
spx_word16_t *post; /**< A-posteriori SNR */
spx_word32_t *S; /**< Smoothed power spectrum */
spx_word32_t *Smin; /**< See Cohen paper */
spx_word32_t *Stmp; /**< See Cohen paper */
int *update_prob; /**< Propability of speech presence for noise update */
spx_word16_t *zeta; /**< Smoothed a priori SNR */
spx_word32_t *echo_noise;
spx_word32_t *residual_echo;
spx_word16_t *inbuf; /**< Input buffer (overlapped analysis) */
spx_word16_t *outbuf; /**< Output buffer (for overlap and add) */
int agc_enabled;
float agc_level;
float loudness_accum;
float *loudness_weight; /**< Perceptual loudness curve */
float loudness; /**< Loudness estimate */
float agc_gain; /**< Current AGC gain */
int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */
float max_gain; /**< Maximum gain allowed */
float max_increase_step; /**< Maximum increase in gain from one frame to another */
float max_decrease_step; /**< Maximum decrease in gain from one frame to another */
float prev_loudness; /**< Loudness of previous frame */
float init_max; /**< Current gain limit during initialisation */
int nb_adapt; /**< Number of frames used for adaptation so far */
int was_speech;
int min_count; /**< Number of frames processed so far */
void *fft_lookup; /**< Lookup table for the FFT */
};
#ifndef WIN32
typedef WId HWND;
#endif