From: drowe67 Date: Thu, 28 Feb 2013 07:57:53 +0000 (+0000) Subject: added 1600 bit/s Codec 2 mode with scaler Wo & E quantisers X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=83ce0b51452b94afbfff31b75e001409f06e9e93;p=freetel-svn-tracking.git added 1600 bit/s Codec 2 mode with scaler Wo & E quantisers git-svn-id: https://svn.code.sf.net/p/freetel/code@1180 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/c2dec.c b/codec2-dev/src/c2dec.c index 8b2f2eb6..c1e1f467 100644 --- a/codec2-dev/src/c2dec.c +++ b/codec2-dev/src/c2dec.c @@ -52,10 +52,10 @@ int main(int argc, char *argv[]) float ber, r, burst_length, burst_period, burst_timer; if (argc < 4) { - printf("basic usage.................: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile\n"); - printf("uniform errors usage........: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile uniformBER startBit endBit\n"); - printf("uniform error on range usage: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile uniformBER\n"); - printf("two state fading usage......: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile burstLength burstPeriod\n"); + printf("basic usage.................: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile\n"); + printf("uniform errors usage........: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile uniformBER startBit endBit\n"); + printf("uniform error on range usage: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile uniformBER\n"); + printf("two state fading usage......: c2dec 3200|2400|1600|1400|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"); @@ -66,12 +66,14 @@ int main(int argc, char *argv[]) mode = CODEC2_MODE_3200; else if (strcmp(argv[1],"2400") == 0) mode = CODEC2_MODE_2400; + else if (strcmp(argv[1],"1600") == 0) + mode = CODEC2_MODE_1600; else if (strcmp(argv[1],"1400") == 0) mode = CODEC2_MODE_1400; else if (strcmp(argv[1],"1200") == 0) mode = CODEC2_MODE_1200; else { - fprintf(stderr, "Error in mode: %s. Must be 4800, 3200, 2400, 1400 or 1200\n", argv[1]); + fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400 or 1200\n", argv[1]); exit(1); } bit_rate = atoi(argv[1]); diff --git a/codec2-dev/src/c2enc.c b/codec2-dev/src/c2enc.c index d171c39a..88c20864 100644 --- a/codec2-dev/src/c2enc.c +++ b/codec2-dev/src/c2enc.c @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) int nsam, nbit, nbyte; if (argc != 4) { - printf("usage: c2enc 3200|2400|1400|1200 InputRawspeechFile OutputBitFile\n"); + printf("usage: c2enc 3200|2400|1600|1400|1200 InputRawspeechFile OutputBitFile\n"); printf("e.g c2enc 1400 ../raw/hts1a.raw hts1a.c2\n"); exit(1); } @@ -53,12 +53,14 @@ int main(int argc, char *argv[]) mode = CODEC2_MODE_3200; else if (strcmp(argv[1],"2400") == 0) mode = CODEC2_MODE_2400; + else if (strcmp(argv[1],"1600") == 0) + mode = CODEC2_MODE_1600; else if (strcmp(argv[1],"1400") == 0) mode = CODEC2_MODE_1400; else if (strcmp(argv[1],"1200") == 0) mode = CODEC2_MODE_1200; else { - fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1400 or 1200\n", argv[1]); + fprintf(stderr, "Error in mode: %s. Must be 3200, 2400, 1600, 1400 or 1200\n", argv[1]); exit(1); } diff --git a/codec2-dev/src/codec2.c b/codec2-dev/src/codec2.c index 7bf96b9f..9a64c7e4 100644 --- a/codec2-dev/src/codec2.c +++ b/codec2-dev/src/codec2.c @@ -58,6 +58,8 @@ void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]); @@ -96,6 +98,7 @@ struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode) assert( (mode == CODEC2_MODE_3200) || (mode == CODEC2_MODE_2400) || + (mode == CODEC2_MODE_1600) || (mode == CODEC2_MODE_1400) || (mode == CODEC2_MODE_1200) ); @@ -173,6 +176,8 @@ int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *c2) { return 64; if (c2->mode == CODEC2_MODE_2400) return 48; + if (c2->mode == CODEC2_MODE_1600) + return 64; if (c2->mode == CODEC2_MODE_1400) return 56; if (c2->mode == CODEC2_MODE_1200) @@ -197,6 +202,8 @@ int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *c2) { return 160; if (c2->mode == CODEC2_MODE_2400) return 160; + if (c2->mode == CODEC2_MODE_1600) + return 320; if (c2->mode == CODEC2_MODE_1400) return 320; if (c2->mode == CODEC2_MODE_1200) @@ -211,6 +218,7 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, s assert( (c2->mode == CODEC2_MODE_3200) || (c2->mode == CODEC2_MODE_2400) || + (c2->mode == CODEC2_MODE_1600) || (c2->mode == CODEC2_MODE_1400) || (c2->mode == CODEC2_MODE_1200) ); @@ -219,6 +227,8 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, s codec2_encode_3200(c2, bits, speech); if (c2->mode == CODEC2_MODE_2400) codec2_encode_2400(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1600) + codec2_encode_1600(c2, bits, speech); if (c2->mode == CODEC2_MODE_1400) codec2_encode_1400(c2, bits, speech); if (c2->mode == CODEC2_MODE_1200) @@ -231,6 +241,7 @@ void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const assert( (c2->mode == CODEC2_MODE_3200) || (c2->mode == CODEC2_MODE_2400) || + (c2->mode == CODEC2_MODE_1600) || (c2->mode == CODEC2_MODE_1400) || (c2->mode == CODEC2_MODE_1200) ); @@ -239,6 +250,8 @@ void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const codec2_decode_3200(c2, speech, bits); if (c2->mode == CODEC2_MODE_2400) codec2_decode_2400(c2, speech, bits); + if (c2->mode == CODEC2_MODE_1600) + codec2_decode_1600(c2, speech, bits); if (c2->mode == CODEC2_MODE_1400) codec2_decode_1400(c2, speech, bits); if (c2->mode == CODEC2_MODE_1200) @@ -541,6 +554,193 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * } +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1600 + AUTHOR......: David Rowe + DATE CREATED: Feb 28 2013 + + Encodes 320 speech samples (40ms of speech) into 64 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm 4 times: + + frame 0: voicing bit + frame 1: voicing bit, Wo and E + frame 2: voicing bit + frame 3: voicing bit, Wo and E, scalar LSPs + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 0 36 36 + Pitch (Wo) 7 7 14 + Energy 5 5 10 + Voicing (10ms update) 2 2 4 + TOTAL 14 50 64 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + float lsps[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + int lsp_indexes[LPC_ORD]; + int Wo_index, e_index; + int i; + unsigned int nbit = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, speech); + pack(bits, &nbit, model.voiced, 1); + + /* frame 2: - voicing, scalar Wo & E -------------------------------*/ + + analyse_one_frame(c2, &model, &speech[N]); + pack(bits, &nbit, model.voiced, 1); + + Wo_index = encode_Wo(model.Wo); + pack(bits, &nbit, Wo_index, WO_BITS); + + /* need to run this just to get LPC energy */ + 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); + + /* frame 3: - voicing ---------------------------------------------*/ + + analyse_one_frame(c2, &model, &speech[2*N]); + pack(bits, &nbit, model.voiced, 1); + + /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ + + analyse_one_frame(c2, &model, &speech[3*N]); + pack(bits, &nbit, model.voiced, 1); + + Wo_index = encode_Wo(model.Wo); + pack(bits, &nbit, Wo_index, WO_BITS); + + 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); + + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + for(i=0; iprev_model_dec, &model[1]); + e[0] = interp_energy(c2->prev_e_dec, e[1]); + interp_Wo(&model[2], &model[1], &model[3]); + e[2] = interp_energy(e[1], e[3]); + + /* LSPs are sampled every 40ms so we interpolate the 3 frames in + between, then recover spectral amplitudes */ + + for(i=0, weight=0.25; i<3; i++, weight += 0.25) { + interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight); + } + for(i=0; i<4; i++) { + lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD); + aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, + c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); + apply_lpc_correction(&model[i]); + } + + /* synthesise ------------------------------------------------*/ + + for(i=0; i<4; i++) + synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]); + + /* update memories for next frame ----------------------------*/ + + c2->prev_model_dec = model[3]; + c2->prev_e_dec = e[3]; + for(i=0; iprev_lsps_dec[i] = lsps[3][i]; + +} + /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_1400 diff --git a/codec2-dev/src/codec2.h b/codec2-dev/src/codec2.h index 8baa307e..2c25f661 100644 --- a/codec2-dev/src/codec2.h +++ b/codec2-dev/src/codec2.h @@ -48,8 +48,9 @@ #define CODEC2_MODE_3200 0 #define CODEC2_MODE_2400 1 -#define CODEC2_MODE_1400 2 -#define CODEC2_MODE_1200 3 +#define CODEC2_MODE_1600 2 +#define CODEC2_MODE_1400 3 +#define CODEC2_MODE_1200 4 struct CODEC2; diff --git a/codec2-dev/src/fdmdv_demod.c b/codec2-dev/src/fdmdv_demod.c index 5013ab0b..5414b266 100644 --- a/codec2-dev/src/fdmdv_demod.c +++ b/codec2-dev/src/fdmdv_demod.c @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) Nc = FDMDV_NC; fdmdv = fdmdv_create(Nc); - /* malloc some of the bigger variables to prevent out of stack problems */ + /* malloc some of the larger variables to prevent out of stack problems */ rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES); assert(rx_fdm_log != NULL);