moved codec2 states to a separate file to make unit testing easier
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 8 Jun 2012 23:44:53 +0000 (23:44 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 8 Jun 2012 23:44:53 +0000 (23:44 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@534 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/codec2.c
codec2-dev/src/codec2_internal.h [new file with mode: 0644]
codec2-dev/unittest/Makefile.am
codec2-dev/unittest/Makefile.in
codec2-dev/unittest/tlspsens.c [new file with mode: 0644]

index 82d185573f0d79d8b3616dae244b491361261a21..a5ff1f974fbbec2e2b8da29b44fedb8914e48c50 100644 (file)
 #include "postfilter.h"
 #include "codec2.h"
 #include "lsp.h"
-
-struct CODEC2 {
-    int    mode;
-    float  w[M];                   /* time domain hamming window                */
-    COMP   W[FFT_ENC];             /* DFT of w[]                                */
-    float  Pn[2*N];                /* trapezoidal synthesis window              */
-    float  Sn[M];                   /* input speech                              */
-    float  hpf_states[2];           /* high pass filter states                   */
-    void  *nlp;                     /* pitch predictor states                    */
-    float  Sn_[2*N];               /* synthesised output speech                 */
-    float  ex_phase;                /* excitation model phase track              */
-    float  bg_est;                  /* background noise estimate for post filter */
-    float  prev_Wo_enc;             /* previous frame's pitch estimate           */
-    MODEL  prev_model_dec;          /* previous frame's model parameters         */
-    float  prev_lsps_dec[LPC_ORD];  /* previous frame's LSPs                     */
-    float  prev_e_dec;              /* previous frame's LPC energy               */
-
-    float  xq_enc[2];               /* joint pitch and energy VQ states          */
-    float  xq_dec[2];
-};
+#include "codec2_internal.h"
 
 /*---------------------------------------------------------------------------*\
                                                        
diff --git a/codec2-dev/src/codec2_internal.h b/codec2-dev/src/codec2_internal.h
new file mode 100644 (file)
index 0000000..9aa1855
--- /dev/null
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: fdmdv_internal.h
+  AUTHOR......: David Rowe                                                          
+  DATE CREATED: April 16 2012
+                                                                             
+  Header file for Codec2 internal states, exposed via this header
+  file to assist in testing.
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  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 Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CODEC2_INTERNAL__
+#define __CODEC2_INTERNAL__
+
+struct CODEC2 {
+    int    mode;
+    float  w[M];                   /* time domain hamming window                */
+    COMP   W[FFT_ENC];             /* DFT of w[]                                */
+    float  Pn[2*N];                /* trapezoidal synthesis window              */
+    float  Sn[M];                   /* input speech                              */
+    float  hpf_states[2];           /* high pass filter states                   */
+    void  *nlp;                     /* pitch predictor states                    */
+    float  Sn_[2*N];               /* synthesised output speech                 */
+    float  ex_phase;                /* excitation model phase track              */
+    float  bg_est;                  /* background noise estimate for post filter */
+    float  prev_Wo_enc;             /* previous frame's pitch estimate           */
+    MODEL  prev_model_dec;          /* previous frame's model parameters         */
+    float  prev_lsps_dec[LPC_ORD];  /* previous frame's LSPs                     */
+    float  prev_e_dec;              /* previous frame's LPC energy               */
+
+    float  xq_enc[2];               /* joint pitch and energy VQ states          */
+    float  xq_dec[2];
+};
+
+#endif
index 70f81abd2069e9c256e860bcad97111f59418b28..58e68d775968fb2d76959d14ffbd17eab33eb909 100644 (file)
@@ -3,7 +3,7 @@ AUTOMAKE_OPTS = gnu
 NAME = libcodec2
 AM_CPPFLAGS = $(AM_CFLAGS)
 
-noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant tcodec2 vq_train_jvm scalarlsptest tfdmdv t48_8 lspsync create_interleaver
+noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant tcodec2 vq_train_jvm scalarlsptest tfdmdv t48_8 lspsync create_interleaver tlspsens
 
 genres_SOURCES = genres.c ../src/lpc.c
 genres_LDADD = $(lib_LTLIBRARIES) 
@@ -69,3 +69,7 @@ create_interleaver_SOURCES = create_interleaver.c
 create_interleaver_LDADD = $(lib_LTLIBRARIES) 
 create_interleaver_LDFLAGS = $(LIBS)
 
+tlspsens_SOURCES = tlspsens.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/fft.c ../src/kiss_fft.c ../src/codec2.c ../src/sine.c ../src/nlp.c ../src/pack.c ../src/interp.c ../src/postfilter.c ../src/phase.c $(CODEBOOKS)
+tlspsens_LDADD = $(lib_LTLIBRARIES) 
+tlspsens_LDFLAGS = $(LIBS)
+
index 979352bc92b1712fe19a598b6ba3fd28c00b2742..f912b00f7d53801e1ad317494fea69a53368a69e 100644 (file)
@@ -40,7 +40,8 @@ noinst_PROGRAMS = genres$(EXEEXT) genlsp$(EXEEXT) extract$(EXEEXT) \
        vqtrain$(EXEEXT) vqtrainjnd$(EXEEXT) tnlp$(EXEEXT) \
        tinterp$(EXEEXT) tquant$(EXEEXT) tcodec2$(EXEEXT) \
        vq_train_jvm$(EXEEXT) scalarlsptest$(EXEEXT) tfdmdv$(EXEEXT) \
-       t48_8$(EXEEXT) lspsync$(EXEEXT) create_interleaver$(EXEEXT)
+       t48_8$(EXEEXT) lspsync$(EXEEXT) create_interleaver$(EXEEXT) \
+       tlspsens$(EXEEXT)
 subdir = unittest
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -99,6 +100,13 @@ am_tinterp_OBJECTS = tinterp.$(OBJEXT) sine.$(OBJEXT) fft.$(OBJEXT) \
        dump.$(OBJEXT)
 tinterp_OBJECTS = $(am_tinterp_OBJECTS)
 tinterp_DEPENDENCIES =
+am_tlspsens_OBJECTS = tlspsens.$(OBJEXT) quantise.$(OBJEXT) \
+       lpc.$(OBJEXT) lsp.$(OBJEXT) dump.$(OBJEXT) fft.$(OBJEXT) \
+       kiss_fft.$(OBJEXT) codec2.$(OBJEXT) sine.$(OBJEXT) \
+       nlp.$(OBJEXT) pack.$(OBJEXT) interp.$(OBJEXT) \
+       postfilter.$(OBJEXT) phase.$(OBJEXT) $(am__objects_1)
+tlspsens_OBJECTS = $(am_tlspsens_OBJECTS)
+tlspsens_DEPENDENCIES =
 am_tnlp_OBJECTS = tnlp.$(OBJEXT) sine.$(OBJEXT) nlp.$(OBJEXT) \
        fft.$(OBJEXT) kiss_fft.$(OBJEXT) dump.$(OBJEXT)
 tnlp_OBJECTS = $(am_tnlp_OBJECTS)
@@ -131,15 +139,15 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 SOURCES = $(create_interleaver_SOURCES) $(extract_SOURCES) \
        $(genlsp_SOURCES) $(genres_SOURCES) $(lspsync_SOURCES) \
        $(scalarlsptest_SOURCES) $(t48_8_SOURCES) $(tcodec2_SOURCES) \
-       $(tfdmdv_SOURCES) $(tinterp_SOURCES) $(tnlp_SOURCES) \
-       $(tquant_SOURCES) $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
-       $(vqtrainjnd_SOURCES)
+       $(tfdmdv_SOURCES) $(tinterp_SOURCES) $(tlspsens_SOURCES) \
+       $(tnlp_SOURCES) $(tquant_SOURCES) $(vq_train_jvm_SOURCES) \
+       $(vqtrain_SOURCES) $(vqtrainjnd_SOURCES)
 DIST_SOURCES = $(create_interleaver_SOURCES) $(extract_SOURCES) \
        $(genlsp_SOURCES) $(genres_SOURCES) $(lspsync_SOURCES) \
        $(scalarlsptest_SOURCES) $(t48_8_SOURCES) $(tcodec2_SOURCES) \
-       $(tfdmdv_SOURCES) $(tinterp_SOURCES) $(tnlp_SOURCES) \
-       $(tquant_SOURCES) $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
-       $(vqtrainjnd_SOURCES)
+       $(tfdmdv_SOURCES) $(tinterp_SOURCES) $(tlspsens_SOURCES) \
+       $(tnlp_SOURCES) $(tquant_SOURCES) $(vq_train_jvm_SOURCES) \
+       $(vqtrain_SOURCES) $(vqtrainjnd_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -301,6 +309,9 @@ lspsync_LDFLAGS = $(LIBS)
 create_interleaver_SOURCES = create_interleaver.c 
 create_interleaver_LDADD = $(lib_LTLIBRARIES) 
 create_interleaver_LDFLAGS = $(LIBS)
+tlspsens_SOURCES = tlspsens.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/fft.c ../src/kiss_fft.c ../src/codec2.c ../src/sine.c ../src/nlp.c ../src/pack.c ../src/interp.c ../src/postfilter.c ../src/phase.c $(CODEBOOKS)
+tlspsens_LDADD = $(lib_LTLIBRARIES) 
+tlspsens_LDFLAGS = $(LIBS)
 all: all-am
 
 .SUFFIXES:
@@ -371,6 +382,9 @@ tfdmdv$(EXEEXT): $(tfdmdv_OBJECTS) $(tfdmdv_DEPENDENCIES)
 tinterp$(EXEEXT): $(tinterp_OBJECTS) $(tinterp_DEPENDENCIES) 
        @rm -f tinterp$(EXEEXT)
        $(LINK) $(tinterp_LDFLAGS) $(tinterp_OBJECTS) $(tinterp_LDADD) $(LIBS)
+tlspsens$(EXEEXT): $(tlspsens_OBJECTS) $(tlspsens_DEPENDENCIES) 
+       @rm -f tlspsens$(EXEEXT)
+       $(LINK) $(tlspsens_LDFLAGS) $(tlspsens_OBJECTS) $(tlspsens_LDADD) $(LIBS)
 tnlp$(EXEEXT): $(tnlp_OBJECTS) $(tnlp_DEPENDENCIES) 
        @rm -f tnlp$(EXEEXT)
        $(LINK) $(tnlp_LDFLAGS) $(tnlp_OBJECTS) $(tnlp_LDADD) $(LIBS)
@@ -425,6 +439,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcodec2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfdmdv.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinterp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlspsens.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnlp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tquant.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vq_train_jvm.Po@am__quote@
diff --git a/codec2-dev/unittest/tlspsens.c b/codec2-dev/unittest/tlspsens.c
new file mode 100644 (file)
index 0000000..bc1c17a
--- /dev/null
@@ -0,0 +1,126 @@
+/*---------------------------------------------------------------------------*\
+                                                                          
+  FILE........: tlspsens.c                                                  
+  AUTHOR......: David Rowe                                            
+  DATE CREATED: 31 May 2012
+                                                               
+  Testing bit error sensitivity of LSP bits, first step in devising an unequal
+  error protection scheme.
+                                                              
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  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 Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "defines.h"
+#include "comp.h"
+#include "codec2.h"
+#include "quantise.h"
+#include "interp.h"
+#include "codec2_internal.h"
+
+float run_a_test(char raw_file_name[], int bit_to_corrupt)
+{
+    FILE   *fin;
+    short   buf[N];
+    struct  CODEC2 *c2;
+    MODEL   model;
+    float   ak[LPC_ORD+1];
+    float   lsps[LPC_ORD], e;
+    int     lsp_indexes[LPC_ORD], found_bit;
+    float   snr, snr_sum;
+    int     frames, i, mask, index;
+
+    c2 = codec2_create(CODEC2_MODE_2400);
+
+    fin = fopen(raw_file_name, "rb");
+    assert(fin != NULL);
+
+    /* find bit we are corrupting */
+
+    found_bit = 0;
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       if (!found_bit) {
+           if (bit_to_corrupt > lsp_bits(i))
+               bit_to_corrupt -= lsp_bits(i);
+           else {
+               index = i;
+               mask = (1 << bit_to_corrupt);
+               printf(" index: %d bit: %d mask: 0x%x ", index, bit_to_corrupt, mask);
+               found_bit = 1;
+           }
+       }
+    }
+    assert(found_bit == 1);
+
+    /* OK test a sample file, flipping bit */
+
+    snr_sum = 0.0;
+    frames = 0;
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       analyse_one_frame(c2, &model, buf);
+       e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+       encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+
+       /* find and flip bit we are testing */
+
+       lsp_indexes[index] ^= mask;
+
+       /* decode LSPs and measure SNR */
+
+       decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD);
+       check_lsp_order(lsps, LPC_ORD);
+       bw_expand_lsps(lsps, LPC_ORD);
+       lsp_to_lpc(lsps, ak, LPC_ORD);
+       aks_to_M2(ak, LPC_ORD, &model, e, &snr, 1); 
+
+       snr_sum += snr;
+       frames++;
+    }
+
+    codec2_destroy(c2);
+
+    fclose(fin);
+
+    return snr_sum/frames;
+}
+int main(int argc, char *argv[]) {
+    int   i;
+    int   total_lsp_bits = 0;
+    float snr;
+
+    if (argc != 2) {
+       printf("usage: %s RawFile\n", argv[0]);
+       exit(1);
+    }
+
+    for(i=0; i<LPC_ORD; i++)
+       total_lsp_bits += lsp_bits(i);
+
+    for(i=0; i<total_lsp_bits; i++) {
+       snr = run_a_test(argv[1], i);
+       printf("%d %5.2f\n", i, snr);
+    }
+
+    return 0;
+}