[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 01/02: vocoder: merge final codec2 update
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 01/02: vocoder: merge final codec2 update |
Date: |
Tue, 27 May 2014 22:15:31 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch master
in repository gnuradio.
commit 6cda1db8e69db8992d3698cb43b13f2335b0c10d
Author: A. Maitland Bottoms <address@hidden>
Date: Tue May 27 15:07:22 2014 -0700
vocoder: merge final codec2 update
---
gr-vocoder/lib/codec2/c2dec.c | 136 ++++++++++++++++++++++----------
gr-vocoder/lib/codec2/c2demo.c | 3 +-
gr-vocoder/lib/codec2/c2enc.c | 15 +++-
gr-vocoder/lib/codec2/c2sim.c | 8 +-
gr-vocoder/lib/codec2/codec2.c | 48 +++++++----
gr-vocoder/lib/codec2/codec2.h | 4 +-
gr-vocoder/lib/codec2/codec2_internal.h | 1 +
gr-vocoder/lib/codec2/dump.c | 20 +++++
gr-vocoder/lib/codec2/dump.h | 1 +
gr-vocoder/lib/codec2/nlp.c | 2 +-
gr-vocoder/lib/codec2/pack.c | 49 ++++++++++--
gr-vocoder/lib/codec2/quantise.h | 2 +
gr-vocoder/lib/codec2_decode_ps_impl.cc | 2 +-
13 files changed, 218 insertions(+), 73 deletions(-)
diff --git a/gr-vocoder/lib/codec2/c2dec.c b/gr-vocoder/lib/codec2/c2dec.c
index df4e82f..ec44f0a 100644
--- a/gr-vocoder/lib/codec2/c2dec.c
+++ b/gr-vocoder/lib/codec2/c2dec.c
@@ -26,18 +26,22 @@
*/
#include "codec2.h"
+#include "dump.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <getopt.h>
#define NONE 0 /* no bit errors */
#define UNIFORM 1 /* random bit errors */
#define TWO_STATE 2 /* Two state error model */
#define UNIFORM_RANGE 3 /* random bit errors over a certain range */
+void print_help(const struct option *long_options, int num_opts, char* argv[]);
+
int main(int argc, char *argv[])
{
int mode;
@@ -52,18 +56,25 @@ int main(int argc, char *argv[])
int state, next_state;
float ber, r, burst_length, burst_period, burst_timer, ber_est;
unsigned char mask;
-
- if ((argc != 4) && (argc != 5) && (argc != 6) && (argc != 7)) {
- printf("basic usage.................: c2dec
3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile\n");
- printf("uniform errors usage........: c2dec
3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile uniformBER
startBit endBit\n");
- printf("uniform error on range usage: c2dec
3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile uniformBER\n");
- printf("demod BER estimate..........: c2dec
3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile BERfile\n");
- printf("two state fading usage......: c2dec
3200|2400|1600|1400|1300|1200 InputBitFile OutputRawSpeechFile burstLength
burstPeriod\n");
- printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw\n");
- printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw 0.9\n");
- printf("e.g c2dec 1400 hts1a.c2 hts1a_1400.raw 0.99 0.9\n");
- exit(1);
- }
+ int natural, dump;
+
+ char* opt_string = "h:";
+ struct option long_options[] = {
+ { "ber", required_argument, NULL, 0 },
+ { "startbit", required_argument, NULL, 0 },
+ { "endbit", required_argument, NULL, 0 },
+ { "berfile", required_argument, NULL, 0 },
+ { "natural", no_argument, &natural, 1 },
+ #ifdef DUMP
+ { "dump", required_argument, &dump, 1 },
+ #endif
+ { "help", no_argument, NULL, 'h' },
+ { NULL, no_argument, NULL, 0 }
+ };
+ int num_opts=sizeof(long_options)/sizeof(struct option);
+
+ if (argc < 4)
+ print_help(long_options, num_opts, argv);
if (strcmp(argv[1],"3200") == 0)
mode = CODEC2_MODE_3200;
@@ -101,6 +112,7 @@ int main(int argc, char *argv[])
ber = 0.0;
burst_length = burst_period = 0.0;
burst_timer = 0.0;
+ dump = natural = 0;
codec2 = codec2_create(mode);
nsam = codec2_samples_per_frame(codec2);
@@ -113,34 +125,50 @@ int main(int argc, char *argv[])
nstart_bit = 0;
nend_bit = nbit-1;
- if (argc == 5) {
- /* see if 4th argument is a valid file name */
- if ( (fber = fopen(argv[4],"rb")) == NULL ) {
- /* otherwise it must be BER value for uniform errors */
- ber = atof(argv[4]);
- error_mode = UNIFORM;
- }
- }
+ while(1) {
+ int option_index = 0;
+ int opt = getopt_long(argc, argv, opt_string,
+ long_options, &option_index);
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 0:
+ if(strcmp(long_options[option_index].name, "ber") == 0) {
+ ber = atof(optarg);
+ error_mode = UNIFORM;
+ } else if(strcmp(long_options[option_index].name, "startbit") ==
0) {
+ nstart_bit = atoi(optarg);
+ } else if(strcmp(long_options[option_index].name, "endbit") == 0) {
+ nend_bit = atoi(optarg);
+ } else if(strcmp(long_options[option_index].name, "berfile") ==
0) {
+ if ((fber = fopen(optarg,"wt")) == NULL) {
+ fprintf(stderr, "Error opening BER file: %s %s.\n",
+ optarg, strerror(errno));
+ exit(1);
+ }
- if (argc == 6) {
- error_mode = TWO_STATE;
- burst_length = atof(argv[4]);
- burst_period = atof(argv[5]);
- nstart_bit = 0;
- nend_bit = 2;
- state = 0;
- }
+ }
+ #ifdef DUMP
+ else if(strcmp(long_options[option_index].name, "dump") == 0) {
+ if (dump)
+ dump_on(optarg);
+ }
+ #endif
+ break;
- if (argc == 7) {
- error_mode = UNIFORM_RANGE;
- ber = atof(argv[4]);
- nstart_bit = atoi(argv[5]);
- nend_bit = atoi(argv[6]);
- fprintf(stderr, "ber: %f nstart_bit: %d nend_bit: %d\n", ber,
nstart_bit, nend_bit);
- state = 0;
- }
+ case 'h':
+ print_help(long_options, num_opts, argv);
+ break;
+ default:
+ /* This will never be reached */
+ break;
+ }
+ }
assert(nend_bit <= nbit);
+ codec2_set_natural_or_gray(codec2, !natural);
+ //printf("%d %d\n", nstart_bit, nend_bit);
while(fread(bits, sizeof(char), nbyte, fin) == (size_t)nbyte) {
frames++;
@@ -211,13 +239,7 @@ int main(int argc, char *argv[])
else
ber_est = 0.0;
- /* frame repeat logic */
- if (ber_est > 0.15) {
- //memcpy(bits, prev_bits, nbyte);
- // fprintf(stderr, "repeat\n");
- }
-
- codec2_decode(codec2, buf, bits, ber_est);
+ codec2_decode_ber(codec2, buf, bits, ber_est);
fwrite(buf, sizeof(short), nsam, fout);
//if this is in a pipeline, we probably don't want the usual
//buffering to occur
@@ -239,3 +261,31 @@ int main(int argc, char *argv[])
return 0;
}
+
+void print_help(const struct option* long_options, int num_opts, char* argv[])
+{
+ int i;
+ char *option_parameters;
+ fprintf(stderr, "\nc2dec - Codec 2 decoder and bit error simulation
program\n"
+ "usage: %s 3200|2400|1400}1300|1200 InputFile OutputRawFile
[OPTIONS]\n\n"
+ "Options:\n", argv[0]);
+ for(i=0; i<num_opts-1; i++) {
+ if(long_options[i].has_arg == no_argument) {
+ option_parameters="";
+ } else if (strcmp("ber", long_options[i].name) == 0) {
+ option_parameters = " BER";
+ } else if (strcmp("startbit", long_options[i].name) == 0) {
+ option_parameters = " startBit";
+ } else if (strcmp("endbit", long_options[i].name) == 0) {
+ option_parameters = " endBit";
+ } else if (strcmp("berfile", long_options[i].name) == 0) {
+ option_parameters = " berFileName";
+ } else if (strcmp("dump", long_options[i].name) == 0) {
+ option_parameters = " dumpFilePrefix";
+ } else {
+ option_parameters = " <UNDOCUMENTED parameter>";
+ }
+ fprintf(stderr, "\t--%s%s\n", long_options[i].name,
option_parameters);
+ }
+ exit(1);
+}
diff --git a/gr-vocoder/lib/codec2/c2demo.c b/gr-vocoder/lib/codec2/c2demo.c
index 0090069..9cd11d4 100644
--- a/gr-vocoder/lib/codec2/c2demo.c
+++ b/gr-vocoder/lib/codec2/c2demo.c
@@ -33,6 +33,7 @@
#include "codec2.h"
#include "sine.h"
+#include "dump.h"
#include <stdio.h>
#include <stdlib.h>
@@ -85,7 +86,7 @@ int main(int argc, char *argv[])
while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
codec2_encode(codec2, bits, buf);
- codec2_decode(codec2, buf, bits, 0.0);
+ codec2_decode(codec2, buf, bits);
fwrite(buf, sizeof(short), nsam, fout);
}
diff --git a/gr-vocoder/lib/codec2/c2enc.c b/gr-vocoder/lib/codec2/c2enc.c
index ab1ebe4..1e2760a 100644
--- a/gr-vocoder/lib/codec2/c2enc.c
+++ b/gr-vocoder/lib/codec2/c2enc.c
@@ -41,11 +41,12 @@ int main(int argc, char *argv[])
FILE *fout;
short *buf;
unsigned char *bits;
- int nsam, nbit, nbyte;
+ int nsam, nbit, nbyte, gray;
- if (argc != 4) {
- printf("usage: c2enc 3200|2400|1600|1400|1300|1200 InputRawspeechFile
OutputBitFile\n");
+ if (argc < 4) {
+ printf("usage: c2enc 3200|2400|1600|1400|1300|1200 InputRawspeechFile
OutputBitFile [--natural]\n");
printf("e.g c2enc 1400 ../raw/hts1a.raw hts1a.c2\n");
+ printf("e.g c2enc 1300 ../raw/hts1a.raw hts1a.c2 --natural\n");
exit(1);
}
@@ -88,6 +89,14 @@ int main(int argc, char *argv[])
bits = (unsigned char*)malloc(nbyte*sizeof(char));
+ if (argc == 5) {
+ if (strcmp(argv[4], "--natural") == 0)
+ gray = 0;
+ else
+ gray = 1;
+ codec2_set_natural_or_gray(codec2, gray);
+ }
+
while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
codec2_encode(codec2, bits, buf);
fwrite(bits, sizeof(char), nbyte, fout);
diff --git a/gr-vocoder/lib/codec2/c2sim.c b/gr-vocoder/lib/codec2/c2sim.c
index 8f07299..e68f2ac 100644
--- a/gr-vocoder/lib/codec2/c2sim.c
+++ b/gr-vocoder/lib/codec2/c2sim.c
@@ -587,13 +587,19 @@ int main(int argc, char *argv[])
mel[i]++;
}
+ #ifdef DUMP
+ dump_mel(mel);
+ #endif
+
for(i=0; i<LPC_ORD; i++) {
f_ = 700.0*( pow(10.0, (float)mel[i]/100.0) - 1.0);
lsps_[i] = f_*(PI/4000.0);
}
- for(i=5; i<10; i++) {
+ /*
+ for(i=5; i<10; i++) {
lsps_[i] = lsps[i];
}
+ */
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
diff --git a/gr-vocoder/lib/codec2/codec2.c b/gr-vocoder/lib/codec2/codec2.c
index bc4a084..5bf9980 100644
--- a/gr-vocoder/lib/codec2/codec2.c
+++ b/gr-vocoder/lib/codec2/codec2.c
@@ -138,6 +138,8 @@ struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode)
return NULL;
}
+ c2->gray = 1;
+
c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma =
LPCPF_GAMMA;
c2->xq_enc[0] = c2->xq_enc[1] = 0.0;
@@ -248,7 +250,12 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2,
unsigned char *bits, s
codec2_encode_1200(c2, bits, speech);
}
-void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[],
const unsigned char *bits, float ber_est)
+void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[],
const unsigned char *bits)
+{
+ codec2_decode_ber(c2, speech, bits, 0.0);
+}
+
+void CODEC2_WIN32SUPPORT codec2_decode_ber(struct CODEC2 *c2, short speech[],
const unsigned char *bits, float ber_est)
{
assert(c2 != NULL);
assert(
@@ -978,36 +985,36 @@ void codec2_encode_1300(struct CODEC2 *c2, unsigned char
* bits, short speech[])
/* frame 1: - voicing ---------------------------------------------*/
analyse_one_frame(c2, &model, speech);
- pack(bits, &nbit, model.voiced, 1);
+ pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 2: - voicing ---------------------------------------------*/
analyse_one_frame(c2, &model, &speech[N]);
- pack(bits, &nbit, model.voiced, 1);
+ pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 3: - voicing ---------------------------------------------*/
analyse_one_frame(c2, &model, &speech[2*N]);
- pack(bits, &nbit, model.voiced, 1);
+ pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
/* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
analyse_one_frame(c2, &model, &speech[3*N]);
- pack(bits, &nbit, model.voiced, 1);
+ pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
Wo_index = encode_Wo(model.Wo);
- pack(bits, &nbit, Wo_index, WO_BITS);
+ pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray);
#ifdef TIMER
quant_start = machdep_timer_sample();
#endif
e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
e_index = encode_energy(e);
- pack(bits, &nbit, e_index, E_BITS);
+ pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray);
encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
for(i=0; i<LSP_SCALAR_INDEXES; i++) {
- pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+ pack_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i),
c2->gray);
}
#ifdef TIMER
machdep_timer_sample_and_log(quant_start, " quant/packing");
@@ -1054,20 +1061,20 @@ void codec2_decode_1300(struct CODEC2 *c2, short
speech[], const unsigned char *
/* this will partially fill the model params for the 4 x 10ms
frames */
- model[0].voiced = unpack(bits, &nbit, 1);
- model[1].voiced = unpack(bits, &nbit, 1);
- model[2].voiced = unpack(bits, &nbit, 1);
- model[3].voiced = unpack(bits, &nbit, 1);
+ model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+ model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+ model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+ model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
- Wo_index = unpack(bits, &nbit, WO_BITS);
+ Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray);
model[3].Wo = decode_Wo(Wo_index);
model[3].L = PI/model[3].Wo;
- e_index = unpack(bits, &nbit, E_BITS);
+ e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray);
e[3] = decode_energy(e_index);
for(i=0; i<LSP_SCALAR_INDEXES; i++) {
- lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+ lsp_indexes[i] = unpack_natural_or_gray(bits, &nbit, lsp_bits(i),
c2->gray);
}
decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD);
check_lsp_order(&lsps[3][0], LPC_ORD);
@@ -1101,6 +1108,10 @@ void codec2_decode_1300(struct CODEC2 *c2, short
speech[], const unsigned char *
apply_lpc_correction(&model[i]);
}
TIMER_SAMPLE_AND_LOG2(recover_start, " recover");
+ #ifdef DUMP
+ dump_lsp_(&lsps[3][0]);
+ dump_ak_(&ak[3][0], LPC_ORD);
+ #endif
/* synthesise ------------------------------------------------*/
@@ -1519,3 +1530,10 @@ int CODEC2_WIN32SUPPORT codec2_rebuild_spare_bit(struct
CODEC2 *c2, int unpacked
return -1;
}
+
+void CODEC2_WIN32SUPPORT codec2_set_natural_or_gray(struct CODEC2 *c2, int
gray)
+{
+ assert(c2 != NULL);
+ c2->gray = gray;
+}
+
diff --git a/gr-vocoder/lib/codec2/codec2.h b/gr-vocoder/lib/codec2/codec2.h
index 2f0c2b1..1e870db 100644
--- a/gr-vocoder/lib/codec2/codec2.h
+++ b/gr-vocoder/lib/codec2/codec2.h
@@ -58,13 +58,15 @@ struct CODEC2;
struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode);
void CODEC2_WIN32SUPPORT codec2_destroy(struct CODEC2 *codec2_state);
void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *codec2_state, unsigned
char * bits, short speech_in[]);
- void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state,
short speech_out[], const unsigned char *bits, float ber_est);
+void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short
speech_out[], const unsigned char *bits);
+void CODEC2_WIN32SUPPORT codec2_decode_ber(struct CODEC2 *codec2_state, short
speech_out[], const unsigned char *bits, float ber_est);
int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state);
int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state);
void CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2
*codec2_state, int enable, int bass_boost, float beta, float gamma);
int CODEC2_WIN32SUPPORT codec2_get_spare_bit_index(struct CODEC2
*codec2_state);
int CODEC2_WIN32SUPPORT codec2_rebuild_spare_bit(struct CODEC2 *codec2_state,
int unpacked_bits[]);
+void CODEC2_WIN32SUPPORT codec2_set_natural_or_gray(struct CODEC2
*codec2_state, int gray);
#endif
diff --git a/gr-vocoder/lib/codec2/codec2_internal.h
b/gr-vocoder/lib/codec2/codec2_internal.h
index 246d1ae..c4bb1fc 100644
--- a/gr-vocoder/lib/codec2/codec2_internal.h
+++ b/gr-vocoder/lib/codec2/codec2_internal.h
@@ -38,6 +38,7 @@ struct CODEC2 {
float Sn[M]; /* input speech
*/
float hpf_states[2]; /* high pass filter states
*/
void *nlp; /* pitch predictor states
*/
+ int gray; /* non-zero for gray encoding
*/
kiss_fft_cfg fft_inv_cfg; /* inverse FFT config
*/
float Sn_[2*N]; /* synthesised output speech
*/
diff --git a/gr-vocoder/lib/codec2/dump.c b/gr-vocoder/lib/codec2/dump.c
index cc935d7..af966e5 100644
--- a/gr-vocoder/lib/codec2/dump.c
+++ b/gr-vocoder/lib/codec2/dump.c
@@ -54,6 +54,7 @@ static FILE *frw = NULL;
static FILE *flsp = NULL;
static FILE *fweights = NULL;
static FILE *flsp_ = NULL;
+static FILE *fmel = NULL;
static FILE *fphase = NULL;
static FILE *fphase_ = NULL;
static FILE *ffw = NULL;
@@ -101,6 +102,8 @@ void dump_off(){
fclose(fweights);
if (flsp_ != NULL)
fclose(flsp_);
+ if (fmel != NULL)
+ fclose(fmel);
if (fphase != NULL)
fclose(fphase);
if (fphase_ != NULL)
@@ -453,6 +456,23 @@ void dump_lsp_(float lsp_[]) {
fprintf(flsp_,"\n");
}
+void dump_mel(int mel[]) {
+ int i;
+ char s[MAX_STR];
+
+ if (!dumpon) return;
+
+ if (fmel == NULL) {
+ sprintf(s,"%s_mel.txt", prefix);
+ fmel = fopen(s, "wt");
+ assert(fmel != NULL);
+ }
+
+ for(i=0; i<10; i++)
+ fprintf(fmel,"%d\t",mel[i]);
+ fprintf(fmel,"\n");
+}
+
void dump_ak(float ak[], int order) {
int i;
char s[MAX_STR];
diff --git a/gr-vocoder/lib/codec2/dump.h b/gr-vocoder/lib/codec2/dump.h
index a61fdaa..dd95f5a 100644
--- a/gr-vocoder/lib/codec2/dump.h
+++ b/gr-vocoder/lib/codec2/dump.h
@@ -49,6 +49,7 @@ void dump_Rw(float Rw[]);
void dump_lsp(float lsp[]);
void dump_weights(float w[], int ndim);
void dump_lsp_(float lsp_[]);
+void dump_mel(int mel[]);
void dump_ak(float ak[], int order);
void dump_ak_(float ak[], int order);
void dump_E(float E);
diff --git a/gr-vocoder/lib/codec2/nlp.c b/gr-vocoder/lib/codec2/nlp.c
index cca835b..83375dc 100644
--- a/gr-vocoder/lib/codec2/nlp.c
+++ b/gr-vocoder/lib/codec2/nlp.c
@@ -53,7 +53,7 @@
#define CNLP 0.3 /* post processor constant
*/
#define NLP_NTAP 48 /* Decimation LPF order */
-#undef DUMP
+//#undef DUMP
/*---------------------------------------------------------------------------*\
diff --git a/gr-vocoder/lib/codec2/pack.c b/gr-vocoder/lib/codec2/pack.c
index 3f8f93e..1c07230 100644
--- a/gr-vocoder/lib/codec2/pack.c
+++ b/gr-vocoder/lib/codec2/pack.c
@@ -52,8 +52,22 @@ pack(
unsigned int fieldWidth/* Width of the field in BITS, not bytes. */
)
{
- /* Convert the field to Gray code */
- field = (field >> 1) ^ field;
+ pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1);
+}
+
+void
+pack_natural_or_gray(
+ unsigned char * bitArray, /* The output bit string. */
+ unsigned int * bitIndex, /* Index into the string in BITS,
not bytes.*/
+ int field, /* The bit field to be packed. */
+ unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */
+ unsigned int gray /* non-zero for gray coding */
+ )
+{
+ if (gray) {
+ /* Convert the field to Gray code */
+ field = (field >> 1) ^ field;
+ }
do {
unsigned int bI = *bitIndex;
@@ -81,6 +95,21 @@ unpack(
unsigned int fieldWidth/* Width of the field in BITS, not bytes. */
)
{
+ return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1);
+}
+
+/** Unpack a field from a bit string, to binary, optionally using
+ * natural or Gray code.
+ *
+ */
+int
+unpack_natural_or_gray(
+ const unsigned char * bitArray, /* The input bit string. */
+ unsigned int * bitIndex, /* Index into the string in BITS,
not bytes.*/
+ unsigned int fieldWidth,/* Width of the field in BITS, not bytes. */
+ unsigned int gray /* non-zero for Gray coding */
+ )
+{
unsigned int field = 0;
unsigned int t;
@@ -96,10 +125,16 @@ unpack(
fieldWidth -= sliceWidth;
} while ( fieldWidth != 0 );
- /* Convert from Gray code to binary. Works for maximum 8-bit fields. */
- t = field ^ (field >> 8);
- t ^= (t >> 4);
- t ^= (t >> 2);
- t ^= (t >> 1);
+ if (gray) {
+ /* Convert from Gray code to binary. Works for maximum 8-bit fields. */
+ t = field ^ (field >> 8);
+ t ^= (t >> 4);
+ t ^= (t >> 2);
+ t ^= (t >> 1);
+ }
+ else {
+ t = field;
+ }
+
return t;
}
diff --git a/gr-vocoder/lib/codec2/quantise.h b/gr-vocoder/lib/codec2/quantise.h
index 0932d9d..cb9dd07 100644
--- a/gr-vocoder/lib/codec2/quantise.h
+++ b/gr-vocoder/lib/codec2/quantise.h
@@ -96,7 +96,9 @@ int encode_energy(float e);
float decode_energy(int index);
void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int
index_bits);
+void pack_natural_or_gray(unsigned char * bits, unsigned int *nbit, int index,
unsigned int index_bits, unsigned int gray);
int unpack(const unsigned char * bits, unsigned int *nbit, unsigned int
index_bits);
+int unpack_natural_or_gray(const unsigned char * bits, unsigned int *nbit,
unsigned int index_bits, unsigned int gray);
int lsp_bits(int i);
int lspd_bits(int i);
diff --git a/gr-vocoder/lib/codec2_decode_ps_impl.cc
b/gr-vocoder/lib/codec2_decode_ps_impl.cc
index fa4c183..c3c682b 100644
--- a/gr-vocoder/lib/codec2_decode_ps_impl.cc
+++ b/gr-vocoder/lib/codec2_decode_ps_impl.cc
@@ -85,7 +85,7 @@ namespace gr {
for(int i = 0; i < noutput_items; i += d_samples_per_frame) {
pack_frame(in, &d_frame_buf[0]);
- codec2_decode (d_codec2, out, const_cast<unsigned
char*>(&d_frame_buf[0]), 0.0);
+ codec2_decode (d_codec2, out, const_cast<unsigned
char*>(&d_frame_buf[0]));
in += d_bits_per_frame * sizeof (char);
out += d_samples_per_frame;
}