void *codec2;
FILE *fin;
FILE *fout;
+ FILE *fber = NULL;
short *buf;
- unsigned char *bits;
+ unsigned char *bits, *prev_bits;
int nsam, nbit, nbyte, i, byte, frames, bits_proc, bit_errors, error_mode;
int nstart_bit, nend_bit, bit_rate;
int state, next_state;
- float ber, r, burst_length, burst_period, burst_timer;
+ 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 smoothingFlag\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");
buf = (short*)malloc(nsam*sizeof(short));
nbyte = (nbit + 7) / 8;
bits = (unsigned char*)malloc(nbyte*sizeof(char));
+ prev_bits = (unsigned char*)malloc(nbyte*sizeof(char));
frames = bit_errors = bits_proc = 0;
nstart_bit = 0;
nend_bit = nbit-1;
if (argc == 5) {
- error_mode = UNIFORM;
- ber = atof(argv[4]);
+ /* 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;
+ }
}
if (argc == 6) {
state = next_state;
}
- codec2_decode(codec2, buf, bits);
+ if (fber != NULL) {
+ if (fread(&ber_est, sizeof(float), 1, fber) != 1) {
+ fprintf(stderr, "ran out of BER estimates!\n");
+ exit(1);
+ }
+ //fprintf(stderr, "ber_est: %f\n", ber_est);
+ }
+ 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);
fwrite(buf, sizeof(short), nsam, fout);
//if this is in a pipeline, we probably don't want the usual
//buffering to occur
if (fout == stdout) fflush(stdout);
if (fin == stdin) fflush(stdin);
+
+ memcpy(prev_bits, bits, nbyte);
}
if (error_mode)
while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
codec2_encode(codec2, bits, buf);
- codec2_decode(codec2, buf, bits);
+ codec2_decode(codec2, buf, bits, 0.0);
fwrite(buf, sizeof(short), nsam, fout);
}
if (lsp) {
encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
- bw_expand_lsps(lsps_, LPC_ORD);
+ bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
#ifdef __EXPERIMENTAL__
if (lspvq) {
lspvq_quantise(lsps, lsps_, LPC_ORD);
- bw_expand_lsps(lsps_, LPC_ORD);
+ bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
#endif
{
float lsps_bw[LPC_ORD];
memcpy(lsps_bw, lsps_, sizeof(float)*LPC_ORD);
- bw_expand_lsps(lsps_bw, LPC_ORD);
+ bw_expand_lsps(lsps_bw, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_bw, ak, LPC_ORD);
}
}
/* multi-stage VQ from Anssi Ramo OH3GDD */
lspanssi_quantise(lsps, lsps_, LPC_ORD, 5);
- bw_expand_lsps(lsps_, LPC_ORD);
+ bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
#endif
if (lspdt && !decimate) {
if (frames%2) {
lspdt_quantise(lsps, lsps_, lsps__prev, lspdt_mode);
- bw_expand_lsps(lsps_, LPC_ORD);
+ bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
for(i=0; i<LPC_ORD; i++)
for(i=0; i<LPC_ORD; i++)
lsps_[i] = lsps__prev2[i];
#endif
- bw_expand_lsps(lsps_, LPC_ORD);
+ bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
lsp_to_lpc(lsps_, ak, LPC_ORD);
}
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_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]);
-void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est);
void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]);
void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
static void ear_protection(float in_out[], int n);
codec2_encode_1200(c2, bits, speech);
}
-void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
+void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est)
{
assert(c2 != NULL);
assert(
if (c2->mode == CODEC2_MODE_1400)
codec2_decode_1400(c2, speech, bits);
if (c2->mode == CODEC2_MODE_1300)
- codec2_decode_1300(c2, speech, bits);
+ codec2_decode_1300(c2, speech, bits, ber_est);
if (c2->mode == CODEC2_MODE_1200)
codec2_decode_1200(c2, speech, bits);
}
}
decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD);
check_lsp_order(&lsps[1][0], LPC_ORD);
- bw_expand_lsps(&lsps[1][0], LPC_ORD);
+ bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0);
/* interpolate ------------------------------------------------*/
}
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);
+ bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
/* interpolate ------------------------------------------------*/
}
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);
+ bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
/* interpolate ------------------------------------------------*/
\*---------------------------------------------------------------------------*/
-void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est)
{
MODEL model[4];
int lsp_indexes[LPC_ORD];
}
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);
+ 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
}
decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD);
check_lsp_order(&lsps[3][0], LPC_ORD);
- bw_expand_lsps(&lsps[3][0], LPC_ORD);
+ bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
/* interpolate ------------------------------------------------*/
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);
+ void CODEC2_WIN32SUPPORT codec2_decode(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 bw_expand_lsps(float lsp[],
- int order
-)
+void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high)
{
int i;
for(i=1; i<4; i++) {
- if ((lsp[i] - lsp[i-1]) < 50.0*(PI/4000.0))
- lsp[i] = lsp[i-1] + 50.0*(PI/4000.0);
+ if ((lsp[i] - lsp[i-1]) < min_sep_low*(PI/4000.0))
+ lsp[i] = lsp[i-1] + min_sep_low*(PI/4000.0);
}
*/
for(i=4; i<order; i++) {
- if (lsp[i] - lsp[i-1] < 100.0*(PI/4000.0))
- lsp[i] = lsp[i-1] + 100.0*(PI/4000.0);
+ if (lsp[i] - lsp[i-1] < min_sep_high*(PI/4000.0))
+ lsp[i] = lsp[i-1] + min_sep_high*(PI/4000.0);
}
}
int order
);
int check_lsp_order(float lsp[], int lpc_order);
-void bw_expand_lsps(float lsp[], int order);
+void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high);
void bw_expand_lsps2(float lsp[], int order);
void locate_lsps_jnd_steps(float lsp[], int order);
float decode_amplitudes(MODEL *model,