void codec2_encode_1300(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; #ifdef PROFILE unsigned int quant_start; #endif assert(c2 != NULL); memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); /* frame 1: - voicing ---------------------------------------------*/ analyse_one_frame(c2, &model, speech); pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); /* frame 2: - voicing ---------------------------------------------*/ analyse_one_frame(c2, &model, &speech[N]); pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); /* frame 3: - voicing ---------------------------------------------*/ analyse_one_frame(c2, &model, &speech[2*N]); 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_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); Wo_index = encode_Wo(model.Wo); pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray); #ifdef PROFILE quant_start = machdep_profile_sample(); #endif e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); e_index = encode_energy(e); 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_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i), c2->gray); } #ifdef PROFILE machdep_profile_sample_and_log(quant_start, " quant/packing"); #endif assert(nbit == (unsigned)codec2_bits_per_frame(c2)); }
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; i<LSP_SCALAR_INDEXES; i++) { pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); } assert(nbit == (unsigned)codec2_bits_per_frame(c2)); }
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; }
void codec2_encode(void *codec2_state, unsigned char * bits, short speech[]) { CODEC2 *c2; MODEL model; int voiced1, voiced2; int lsp_indexes[LPC_ORD]; int energy_index; int Wo_index; int i; unsigned int nbit = 0; assert(codec2_state != NULL); c2 = (CODEC2*)codec2_state; /* first 10ms analysis frame - we just want voicing */ analyse_one_frame(c2, &model, speech); voiced1 = model.voiced; /* second 10ms analysis frame */ analyse_one_frame(c2, &model, &speech[N]); voiced2 = model.voiced; Wo_index = encode_Wo(model.Wo); encode_amplitudes(lsp_indexes, &energy_index, &model, c2->Sn, c2->w); memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8)); pack(bits, &nbit, Wo_index, WO_BITS); for(i=0; i<LPC_ORD; i++) { pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); } pack(bits, &nbit, energy_index, E_BITS); pack(bits, &nbit, voiced1, 1); pack(bits, &nbit, voiced2, 1); assert(nbit == CODEC2_BITS_PER_FRAME); }
void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) { MODEL model; float ak[LPC_ORD+1]; float lsps[LPC_ORD]; float e; int WoE_index; int lsp_indexes[LPC_ORD]; int i; int spare = 0; unsigned int nbit = 0; assert(c2 != NULL); memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); /* first 10ms analysis frame - we just want voicing */ analyse_one_frame(c2, &model, speech); pack(bits, &nbit, model.voiced, 1); /* second 10ms analysis frame */ analyse_one_frame(c2, &model, &speech[N]); pack(bits, &nbit, model.voiced, 1); e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); WoE_index = encode_WoE(&model, e, c2->xq_enc); pack(bits, &nbit, WoE_index, WO_E_BITS); 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(bits, &nbit, spare, 2); assert(nbit == (unsigned)codec2_bits_per_frame(c2)); }
void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits) { MODEL model[4]; int lsp_indexes[LPC_ORD]; float lsps[4][LPC_ORD]; int WoE_index; float e[4]; float snr; float ak[4][LPC_ORD+1]; int i,j; unsigned int nbit = 0; float weight; assert(c2 != NULL); /* only need to zero these out due to (unused) snr calculation */ for(i=0; i<4; i++) for(j=1; j<=MAX_AMP; j++) model[i].A[j] = 0.0; /* unpack bits from channel ------------------------------------*/ /* 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); WoE_index = unpack(bits, &nbit, WO_E_BITS); decode_WoE(&model[1], &e[1], c2->xq_dec, WoE_index); model[2].voiced = unpack(bits, &nbit, 1); model[3].voiced = unpack(bits, &nbit, 1); WoE_index = unpack(bits, &nbit, WO_E_BITS); decode_WoE(&model[3], &e[3], c2->xq_dec, WoE_index); for(i=0; i<LSP_SCALAR_INDEXES; i++) { lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); } decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD); check_lsp_order(&lsps[3][0], LPC_ORD); bw_expand_lsps(&lsps[3][0], LPC_ORD); /* interpolate ------------------------------------------------*/ /* Wo and energy are sampled every 20ms, so we interpolate just 1 10ms frame between 20ms samples */ interp_Wo(&model[0], &c2->prev_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; i<LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; }
void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est) { MODEL model[4]; int lsp_indexes[LPC_ORD]; float lsps[4][LPC_ORD]; int Wo_index, e_index; float e[4]; float snr; float ak[4][LPC_ORD+1]; int i,j; unsigned int nbit = 0; float weight; COMP Aw[FFT_ENC]; PROFILE_VAR(recover_start); assert(c2 != NULL); /* only need to zero these out due to (unused) snr calculation */ for(i=0; i<4; i++) for(j=1; j<=MAX_AMP; j++) model[i].A[j] = 0.0; /* unpack bits from channel ------------------------------------*/ /* this will partially fill the model params for the 4 x 10ms frames */ 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_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_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_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); bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0); if (ber_est > 0.15) { model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced = 0; e[3] = decode_energy(10); bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0); fprintf(stderr, "soft mute\n"); } /* interpolate ------------------------------------------------*/ /* Wo, energy, and LSPs are sampled every 40ms so we interpolate the 3 frames in between */ PROFILE_SAMPLE(recover_start); 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); interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight); e[i] = interp_energy2(c2->prev_e_dec, e[3],weight); } /* then recover spectral amplitudes */ 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, Aw); apply_lpc_correction(&model[i]); synthesise_one_frame(c2, &speech[N*i], &model[i], Aw); } PROFILE_SAMPLE_AND_LOG2(recover_start, " recover"); #ifdef DUMP dump_lsp_(&lsps[3][0]); dump_ak_(&ak[3][0], LPC_ORD); #endif /* update memories for next frame ----------------------------*/ c2->prev_model_dec = model[3]; c2->prev_e_dec = e[3]; for(i=0; i<LPC_ORD; i++) c2->prev_lsps_dec[i] = lsps[3][i]; }
void codec2_decode(void *codec2_state, short speech[], const unsigned char * bits) { CODEC2 *c2; MODEL model; int voiced1, voiced2; int lsp_indexes[LPC_ORD]; float lsps[LPC_ORD]; int energy_index; float energy; int Wo_index; float ak[LPC_ORD+1]; float ak_interp[LPC_ORD+1]; int i; unsigned int nbit = 0; MODEL model_interp; assert(codec2_state != NULL); c2 = (CODEC2*)codec2_state; /* unpack bit stream to integer codes */ Wo_index = unpack(bits, &nbit, WO_BITS); for(i=0; i<LPC_ORD; i++) { lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); } energy_index = unpack(bits, &nbit, E_BITS); voiced1 = unpack(bits, &nbit, 1); voiced2 = unpack(bits, &nbit, 1); assert(nbit == CODEC2_BITS_PER_FRAME); /* decode integer codes to model parameters */ model.Wo = decode_Wo(Wo_index); model.L = PI/model.Wo; memset(&model.A, 0, (model.L+1)*sizeof(model.A[0])); decode_amplitudes(&model, ak, lsp_indexes, energy_index, lsps, &energy); model.voiced = voiced2; model_interp.voiced = voiced1; model_interp.Wo = P_MAX/2; memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0])); /* interpolate middle frame's model parameters for adjacent frames */ interpolate_lsp(&model_interp, &c2->prev_model, &model, c2->prev_lsps, c2->prev_energy, lsps, energy, ak_interp); apply_lpc_correction(&model_interp); /* synthesis two 10ms frames */ synthesise_one_frame(c2, speech, &model_interp, ak_interp); synthesise_one_frame(c2, &speech[N], &model, ak); /* update memories (decode states) for next time */ memcpy(&c2->prev_model, &model, sizeof(MODEL)); memcpy(c2->prev_lsps, lsps, sizeof(lsps)); c2->prev_energy = energy; }
float run_a_test(char raw_file_name[], int bit_to_corrupt) { FILE *fin; short buf[N]; struct CODEC2 *c2; kiss_fft_cfg fft_fwd_cfg; 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); fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL); 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(fft_fwd_cfg, ak, LPC_ORD, &model, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); snr_sum += snr; frames++; } codec2_destroy(c2); fclose(fin); return snr_sum/frames; }