[Speex-dev] Patch to make analysis data available.
Thorvald Natvig
speex at natvig.com
Sat Feb 2 11:25:13 PST 2008
Hi,
Ref the disucussion on IRC yesterday; here's a patch which makes a bit
more data from the analysis of the preprocessor and the echo canceller
available.
For the preprocessor:
- Size of power spectrum.
- Power spectrum and noise estimate of the previous frame.
These are given as squared values, so sqrt() to get values in the
0->32767 range.
- Current amplification level used by AGC (in percent).
- Estimated SNR in the 300-2000Hz range (which is just a cut&paste from
an earlier speex release) (also in percent -- should have been a
float).
For the echo canceller:
- Size of the weights.
- The modulus of the weights, in percent of power seen per frequency
bank per timeslot.
These allow some very usefull (and impressive) visualizations of the
current audio path, and also give users much more detailed information on
what part of their audio system they should improve.
It also adds a #define SPEEX_API_VERSION, which allows compile-time
checking and #ifdef'ing for whether these (and other new) functions are
available.
Last time I programmed fixedpoint was on a 68000, and that was democode
where speed>>>correctness.
I've compiled the library with both FIXED_POINT and FLOATING_POINT, and
verified that both give approximately the same results, but my conversion
of the weights in fixed-point desperately need some work.
-------------- next part --------------
Index: include/speex/speex_preprocess.h
===================================================================
--- include/speex/speex_preprocess.h (revision 14443)
+++ include/speex/speex_preprocess.h (working copy)
@@ -182,6 +182,26 @@
/** Get loudness */
#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33
+/* Can't get gain */
+/** Get current gain (int32 percent) */
+#define SPEEX_PREPROCESS_GET_AGC_GAIN 35
+
+/* Can't set spectrum size */
+/** Get spectrum size for power and noise spectrum (int32) */
+#define SPEEX_PREPROCESS_GET_SPECTRUM_SIZE 37
+
+/* Can't set power spectrum */
+/** Get power spectrum (int32[] of squared values) */
+#define SPEEX_PREPROCESS_GET_POWER_SPECTRUM 39
+
+/* Can't set noise estimate */
+/** Get noise estimate (int32[] of squared values) */
+#define SPEEX_PREPROCESS_GET_NOISE_ESTIMATE 41
+
+/* Can't set SNR */
+/** Get signal to noise ratio estimate for 300hz-2000hz range (int32 (scaled by 100)) */
+#define SPEEX_PREPROCESS_GET_SNR 43
+
#ifdef __cplusplus
}
#endif
Index: include/speex/speex_echo.h
===================================================================
--- include/speex/speex_echo.h (revision 14443)
+++ include/speex/speex_echo.h (working copy)
@@ -51,6 +51,14 @@
/** Get sampling rate */
#define SPEEX_ECHO_GET_SAMPLING_RATE 25
+/* Can't set window sizes */
+/** Get weight sizes (int32[2]) */
+#define SPEEX_ECHO_GET_WEIGHT_SIZES 27
+
+/* Can't set window content */
+/** Get weights (int32[]) */
+#define SPEEX_ECHO_GET_WEIGHTS 29
+
/** Internal echo canceller state. Should never be accessed directly. */
struct SpeexEchoState_;
Index: include/speex/speex.h
===================================================================
--- include/speex/speex.h (revision 14443)
+++ include/speex/speex.h (working copy)
@@ -47,6 +47,9 @@
extern "C" {
#endif
+/* Speex version this headers belongs to */
+#define SPEEX_API_VERSION 0x01010d
+
/* Values allowed for *ctl() requests */
/** Set enhancement on/off (decoder only) */
Index: libspeex/mdf.c
===================================================================
--- libspeex/mdf.c (revision 14443)
+++ libspeex/mdf.c (working copy)
@@ -1169,6 +1169,30 @@
case SPEEX_ECHO_GET_SAMPLING_RATE:
(*(int*)ptr) = st->sampling_rate;
break;
+ case SPEEX_ECHO_GET_WEIGHT_SIZES:
+ ((spx_int32_t *)ptr)[0] = st->M;
+ ((spx_int32_t *)ptr)[1] = st->frame_size;
+ break;
+ case SPEEX_ECHO_GET_WEIGHTS:
+ {
+ spx_int32_t *w = (spx_int32_t *)ptr;
+ int N = st->window_size;
+ int n = st->frame_size;
+ int M = st->M;
+ int i, j;
+ spx_word32_t t1, t2, t3;
+ for(i=0;i<M;i++) {
+ w[i*n] = 0;
+ w[(i+1)*n-1] = 0;
+ for(j=1;j<n-1;j++) {
+ t1 = MULT16_16(SHR32(st->W[i*N+j*2],16), SHR32(st->W[i*N+j*2],15));
+ t2 = MULT16_16(SHR32(st->W[i*N+j*2-1],16), SHR32(st->W[i*N+j*2-1],15));
+ t3 = MULT16_16(100,spx_sqrt(ADD32(t1,t2)));
+ w[i*n+j] = SHR32(t3, WEIGHT_SHIFT);
+ }
+ }
+ }
+ break;
default:
speex_warning_int("Unknown speex_echo_ctl request: ", request);
return -1;
Index: libspeex/preprocess.c
===================================================================
--- libspeex/preprocess.c (revision 14443)
+++ libspeex/preprocess.c (working copy)
@@ -1175,8 +1175,31 @@
case SPEEX_PREPROCESS_GET_AGC_LOUDNESS:
(*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP);
break;
+ case SPEEX_PREPROCESS_GET_AGC_GAIN:
+ (*(spx_int32_t*)ptr) = (spx_int32_t) (st->agc_gain * 100.f);
+ break;
#endif
-
+ case SPEEX_PREPROCESS_GET_SPECTRUM_SIZE:
+ (*(spx_int32_t*)ptr) = st->ps_size;
+ break;
+ case SPEEX_PREPROCESS_GET_POWER_SPECTRUM:
+ for(i=0;i<st->ps_size;i++)
+ ((spx_int32_t *)ptr)[i] = (spx_int32_t) st->ps[i];
+ break;
+ case SPEEX_PREPROCESS_GET_NOISE_ESTIMATE:
+ for(i=0;i<st->ps_size;i++)
+ ((spx_int32_t *)ptr)[i] = (spx_int32_t) PSHR32(st->noise[i], NOISE_SHIFT);
+ break;
+ case SPEEX_PREPROCESS_GET_SNR:
+ {
+ spx_int32_t fstart = (spx_int32_t) DIV32(MULT16_16(300 * 2, st->ps_size), st->sampling_rate);
+ spx_int32_t fend = (spx_int32_t) DIV32(MULT16_16(2000 * 2, st->ps_size), st->sampling_rate);
+ spx_word32_t Z = 0;
+ for(i = fstart; i<= fend; i++)
+ Z = ADD32(Z, EXTEND32(st->zeta[i]));
+ (*(spx_int32_t*)ptr) = (spx_int32_t) DIV32_16(MULT16_16(PSHR32(Z, SNR_SHIFT), 100), SUB16(fend, fstart));
+ }
+ break;
default:
speex_warning_int("Unknown speex_preprocess_ctl request: ", request);
return -1;
More information about the Speex-dev
mailing list