From 99a73c9e284a8ffdcccfa4027d013a1776f8a681 Mon Sep 17 00:00:00 2001 From: Thorvald Natvig Date: Wed, 23 May 2007 13:57:43 +0000 Subject: [PATCH] Updating to SVN Speex again. Missing voice detection. git-svn-id: https://mumble.svn.sourceforge.net/svnroot/mumble/trunk@442 05730e5d-ab1b-0410-a4ac-84af385074fa --- AudioInput.cpp | 6 +-- AudioStats.cpp | 123 ++++++++++++++++++++++++++++++++++--------------- mumble_pch.h | 69 --------------------------- 3 files changed, 90 insertions(+), 108 deletions(-) diff --git a/AudioInput.cpp b/AudioInput.cpp index 053b5c0aa..6f4c14074 100644 --- a/AudioInput.cpp +++ b/AudioInput.cpp @@ -287,7 +287,6 @@ void AudioInput::encodeAudioFrame() { max=abs(psSource[i]); dPeakSignal=20.0*log10((max * 1.0L) / 32768.0L); - CloneSpeexPreprocessState *pps=reinterpret_cast(sppPreprocess); // The default is a bit short, increase it if (! iIsSpeech) { @@ -297,14 +296,15 @@ void AudioInput::encodeAudioFrame() { } else { iHoldFrames = 0; } - +/* + CloneSpeexPreprocessState *pps=reinterpret_cast(sppPreprocess); if (pps->loudness2 < g.s.iMinLoudness) pps->loudness2 = g.s.iMinLoudness; if (isnan(pps->loudness2)) { qWarning("AudioInput: loudness is nan"); bResetProcessor = true; } - +*/ if (g.s.atTransmit == Settings::Continous) iIsSpeech = 1; else if (g.s.atTransmit == Settings::PushToTalk) diff --git a/AudioStats.cpp b/AudioStats.cpp index b4ae4e50a..17d54964e 100644 --- a/AudioStats.cpp +++ b/AudioStats.cpp @@ -46,45 +46,109 @@ struct CloneSpeexEchoState { 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 *e; - spx_word16_t *x; - spx_word16_t *X; - spx_word16_t *d; - spx_word16_t *y; + 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_word32_t *Yps; - spx_word16_t *Y; + spx_word16_t *Y; /* scratch */ spx_word16_t *E; - spx_word32_t *PHI; - spx_word32_t *W; - spx_word32_t *power; - spx_float_t *power_1; - spx_word16_t *wtmp; -#ifdef FIXED_POINT - spx_word16_t *wtmp2; -#endif - spx_word32_t *Rf; - spx_word32_t *Yf; - spx_word32_t *Xf; + 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_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]; +}; - /* NOTE: If you only use speex_echo_cancel() and want to save some memory, remove this */ - spx_int16_t *play_buf; - int play_buf_pos; +/** 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) { @@ -450,14 +514,6 @@ void AudioStats::on_Tick_timeout() { txt.sprintf("%06.2f dB",ai->dPeakSignal); qlSignalLevel->setText(txt); - double level = st->loudness2 / 200.0; - - txt.sprintf("%03.0f%%", level); - qlMicVolume->setText(txt); - -#ifdef SPEEX_ANCIENT_PP - txt.sprintf("%06.3f",st->Zlast); -#else float Zframe = 0; int freq_start = static_cast(300.0f*2.f*st->ps_size/st->sampling_rate); int freq_end = static_cast(2000.0f*2.f*st->ps_size/st->sampling_rate); @@ -465,14 +521,9 @@ void AudioStats::on_Tick_timeout() { Zframe += st->zeta[i]; Zframe /= (freq_end-freq_start); txt.sprintf("%06.3f",Zframe); -#endif qlMicSNR->setText(txt); -#ifdef SPEEX_ANCIENT_PP - txt.sprintf("%03.0f%%",st->speech_prob * 100.0); -#else txt.sprintf("%03.0f%%",nTalking ? 100.0 : 0.0); -#endif qlSpeechProb->setText(txt); txt.sprintf("%04.1f kbit/s",ai->iBitrate / 1000.0); diff --git a/mumble_pch.h b/mumble_pch.h index 4f7da70c0..32a76ab4d 100644 --- a/mumble_pch.h +++ b/mumble_pch.h @@ -27,75 +27,6 @@ #include #include -#ifndef JITTER_BUFFER_OK -#define SPEEX_ANCIENT -#endif - -#define SPEEX_ANCIENT_PP -#ifdef SPEEX_ANCIENT_PP -typedef SpeexPreprocessState CloneSpeexPreprocessState; -#else -typedef struct { - /* 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; - - /* Parameters */ - int denoise_enabled; - int agc_enabled; - float agc_level; - int vad_enabled; - int dereverb_enabled; - float reverb_decay; - float reverb_level; - float speech_prob_start; - float speech_prob_continue; - int noise_suppress; - int echo_suppress; - int echo_suppress_active; - - /* DSP-related arrays */ - float *frame; /**< Processing frame (2*ps_size) */ - float *ft; /**< Processing frame in freq domain (2*ps_size) */ - float *ps; /**< Current power spectrum */ - float *gain2; /**< Adjusted gains */ - float *gain_floor; /**< Minimum gain allowed */ - float *window; /**< Analysis/Synthesis window */ - float *noise; /**< Noise estimate */ - float *reverb_estimate; /**< Estimate of reverb energy */ - float *old_ps; /**< Power spectrum for last frame */ - float *gain; /**< Ephraim Malah gain */ - float *prior; /**< A-priori SNR */ - float *post; /**< A-posteriori SNR */ - - float *S; /**< Smoothed power spectrum */ - float *Smin; /**< See Cohen paper */ - float *Stmp; /**< See Cohen paper */ - float *update_prob; /**< Propability of speech presence for noise update */ - - float *zeta; /**< Smoothed a priori SNR */ - - float *loudness_weight; /**< Perceptual loudness curve */ - - float *echo_noise; - - /* Misc */ - float *inbuf; /**< Input buffer (overlapped analysis) */ - float *outbuf; /**< Output buffer (for overlap and add) */ - - int was_speech; - float loudness; /**< loudness estimate */ - float loudness2; /**< loudness estimate */ - int nb_adapt; /**< Number of frames used for adaptation so far */ - int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */ - int min_count; /**< Number of frames processed so far */ - void *fft_lookup; /**< Lookup table for the FFT */ -} CloneSpeexPreprocessState; -#endif - #ifndef WIN32 typedef WId HWND; #endif