cvsd_plc: update PLC params

This commit is contained in:
Milanka Ringwald 2018-12-19 10:46:11 +01:00
parent d28a35d955
commit de95d3c928
3 changed files with 119 additions and 100 deletions

View File

@ -50,11 +50,17 @@
#include "btstack_cvsd_plc.h"
#include "btstack_debug.h"
// static float rcos[CVSD_OLAL] = {
// 0.99148655f,0.96623611f,0.92510857f,0.86950446f,
// 0.80131732f,0.72286918f,0.63683150f,0.54613418f,
// 0.45386582f,0.36316850f,0.27713082f,0.19868268f,
// 0.13049554f,0.07489143f,0.03376389f,0.00851345f};
static float rcos[CVSD_OLAL] = {
0.99148655f,0.96623611f,0.92510857f,0.86950446f,
0.80131732f,0.72286918f,0.63683150f,0.54613418f,
0.45386582f,0.36316850f,0.27713082f,0.19868268f,
0.13049554f,0.07489143f,0.03376389f,0.00851345f};
0.99148655f,0.92510857f,
0.80131732f,0.63683150f,
0.45386582f,0.27713082f,
0.13049554f,0.03376389f};
float btstack_cvsd_plc_rcos(int index){
if (index > CVSD_OLAL) return 0;

View File

@ -53,10 +53,10 @@ extern "C" {
#define CVSD_FS_MAX 60 /* CVSD Frame Size */
#define CVSD_N 256 /* Window Length for pattern matching */
#define CVSD_M 10 /* Template for matching */
#define CVSD_M 32 /* Template for matching */
#define CVSD_LHIST (CVSD_N+CVSD_FS_MAX-1) /* Length of history buffer required */
#define CVSD_RT 5 /* Reconvergence Time (samples) */
#define CVSD_OLAL 16 /* OverLap-Add Length (samples) */
#define CVSD_RT 18 /* Reconvergence Time (samples) */
#define CVSD_OLAL 8 /* OverLap-Add Length (samples) */
/* PLC State Information */
typedef struct cvsd_plc_state {

View File

@ -123,21 +123,34 @@ void create_sine_wav(const char * out_filename){
wav_writer_close();
}
void introduce_bad_frames_to_wav_file(const char * in_filename, const char * out_filename, int corruption_step){
int introduce_bad_frames_to_wav_file(const char * in_filename, const char * out_filename, int corruption_step){
btstack_cvsd_plc_init(&plc_state);
wav_writer_open(out_filename, 1, 8000);
wav_reader_open(in_filename);
int total_corruption_times = 0;
int fc = 0;
int start_corruption = 0;
while (wav_reader_read_int16(audio_samples_per_frame, audio_frame_in) == 0){
if (corruption_step > 0 && fc >= corruption_step && fc%corruption_step == 0){
memset(audio_frame_in, 50, audio_samples_per_frame * 2);
printf("corrupt fc %d, corruption_step %d\n", fc, corruption_step);
start_corruption = 1;
}
if (start_corruption > 0 && start_corruption < 4){
memset(audio_frame_in, 50, audio_samples_per_frame * 2);
start_corruption++;
}
if (start_corruption > 4){
start_corruption = 0;
total_corruption_times++;
// printf("corupted 3 frames\n");
}
wav_writer_write_int16(audio_samples_per_frame, audio_frame_in);
fc++;
}
wav_reader_close();
wav_writer_close();
return total_corruption_times;
}
void process_wav_file_with_plc(const char * in_filename, const char * out_filename){
@ -233,88 +246,88 @@ static void fprintf_plot_history(FILE * oct_file, char * name, int data_len, int
fprintf(oct_file, "plot(pattern_window_x, y, 'g'); \n");
}
TEST(CVSD_PLC, CountEqBytes){
// init cvsd_fs in plc_state
float val, sf;
int i, x0, x1;
// TEST(CVSD_PLC, CountEqBytes){
// // init cvsd_fs in plc_state
// float val, sf;
// int i, x0, x1;
char * name;
BTSTACK_CVSD_PLC_SAMPLE_FORMAT out[CVSD_FS_MAX];
BTSTACK_CVSD_PLC_SAMPLE_FORMAT hist[CVSD_LHIST+CVSD_FS_MAX+CVSD_RT+CVSD_OLAL];
FILE * oct_file = fopen("/Users/mringwal/octave/plc.m", "wb");
if (!oct_file) return;
fprintf(oct_file, "%s", "1;\n\n");
// char * name;
// BTSTACK_CVSD_PLC_SAMPLE_FORMAT out[CVSD_FS_MAX];
// BTSTACK_CVSD_PLC_SAMPLE_FORMAT hist[CVSD_LHIST+CVSD_FS_MAX+CVSD_RT+CVSD_OLAL];
// FILE * oct_file = fopen("/Users/mringwal/octave/plc.m", "wb");
// if (!oct_file) return;
// fprintf(oct_file, "%s", "1;\n\n");
int hist_len = sizeof(plc_state.hist)/2;
create_sine_wave_int16_data(CVSD_LHIST, hist);
memset(plc_state.hist, hist[CVSD_LHIST-1], sizeof(plc_state.hist));
memcpy(plc_state.hist, hist, CVSD_LHIST*2);
// int hist_len = sizeof(plc_state.hist)/2;
// create_sine_wave_int16_data(CVSD_LHIST, hist);
// memset(plc_state.hist, hist[CVSD_LHIST-1], sizeof(plc_state.hist));
// memcpy(plc_state.hist, hist, CVSD_LHIST*2);
// Perform pattern matching to find where to replicate
plc_state.bestlag = btstack_cvsd_plc_pattern_match(plc_state.hist);
name = (char *) "hist0";
fprintf_plot_history(oct_file, name, hist_len, plc_state.hist);
// // Perform pattern matching to find where to replicate
// plc_state.bestlag = btstack_cvsd_plc_pattern_match(plc_state.hist);
// name = (char *) "hist0";
// fprintf_plot_history(oct_file, name, hist_len, plc_state.hist);
plc_state.bestlag += CVSD_M;
sf = btstack_cvsd_plc_amplitude_match(&plc_state, audio_samples_per_frame, plc_state.hist, plc_state.bestlag);
// plc_state.bestlag += CVSD_M;
// sf = btstack_cvsd_plc_amplitude_match(&plc_state, audio_samples_per_frame, plc_state.hist, plc_state.bestlag);
for (i=0;i<CVSD_OLAL;i++){
val = sf*plc_state.hist[plc_state.bestlag+i];
plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
}
name = (char *) "olal1";
x0 = CVSD_LHIST;
x1 = x0 + CVSD_OLAL - 1;
fprintf_array_int16(oct_file, name, CVSD_OLAL, plc_state.hist+x0);
fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
// for (i=0;i<CVSD_OLAL;i++){
// val = sf*plc_state.hist[plc_state.bestlag+i];
// plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
// }
// name = (char *) "olal1";
// x0 = CVSD_LHIST;
// x1 = x0 + CVSD_OLAL - 1;
// fprintf_array_int16(oct_file, name, CVSD_OLAL, plc_state.hist+x0);
// fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
for (;i<CVSD_FS_MAX;i++){
val = sf*plc_state.hist[plc_state.bestlag+i];
plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
}
name = (char *)"fs_minus_olal";
x0 = x1 + 1;
x1 = x0 + CVSD_FS_MAX - CVSD_OLAL - 1;
fprintf_array_int16(oct_file, name, CVSD_FS_MAX - CVSD_OLAL, plc_state.hist+x0);
fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
// for (;i<CVSD_FS_MAX;i++){
// val = sf*plc_state.hist[plc_state.bestlag+i];
// plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
// }
// name = (char *)"fs_minus_olal";
// x0 = x1 + 1;
// x1 = x0 + CVSD_FS_MAX - CVSD_OLAL - 1;
// fprintf_array_int16(oct_file, name, CVSD_FS_MAX - CVSD_OLAL, plc_state.hist+x0);
// fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
for (;i<CVSD_FS_MAX+CVSD_OLAL;i++){
float left = sf*plc_state.hist[plc_state.bestlag+i];
float right = plc_state.hist[plc_state.bestlag+i];
val = left*btstack_cvsd_plc_rcos(i-CVSD_FS_MAX) + right*btstack_cvsd_plc_rcos(CVSD_OLAL-1-i+CVSD_FS_MAX);
plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
}
name = (char *)"olal2";
x0 = x1 + 1;
x1 = x0 + CVSD_OLAL - 1;
fprintf_array_int16(oct_file, name, CVSD_OLAL, plc_state.hist+x0);
fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
// for (;i<CVSD_FS_MAX+CVSD_OLAL;i++){
// float left = sf*plc_state.hist[plc_state.bestlag+i];
// float right = plc_state.hist[plc_state.bestlag+i];
// val = left*btstack_cvsd_plc_rcos(i-CVSD_FS_MAX) + right*btstack_cvsd_plc_rcos(CVSD_OLAL-1-i+CVSD_FS_MAX);
// plc_state.hist[CVSD_LHIST+i] = btstack_cvsd_plc_crop_sample(val);
// }
// name = (char *)"olal2";
// x0 = x1 + 1;
// x1 = x0 + CVSD_OLAL - 1;
// fprintf_array_int16(oct_file, name, CVSD_OLAL, plc_state.hist+x0);
// fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
for (;i<CVSD_FS_MAX+CVSD_RT+CVSD_OLAL;i++){
plc_state.hist[CVSD_LHIST+i] = plc_state.hist[plc_state.bestlag+i];
}
name = (char *)"rt";
x0 = x1 + 1;
x1 = x0 + CVSD_RT - 1;
fprintf_array_int16(oct_file, name, CVSD_RT, plc_state.hist+x0);
fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
// for (;i<CVSD_FS_MAX+CVSD_RT+CVSD_OLAL;i++){
// plc_state.hist[CVSD_LHIST+i] = plc_state.hist[plc_state.bestlag+i];
// }
// name = (char *)"rt";
// x0 = x1 + 1;
// x1 = x0 + CVSD_RT - 1;
// fprintf_array_int16(oct_file, name, CVSD_RT, plc_state.hist+x0);
// fprintf(oct_file, "plot(b(%d:%d), %s, 'b.'); \n", x0, x1, name);
for (i=0;i<CVSD_FS_MAX;i++){
out[i] = plc_state.hist[CVSD_LHIST+i];
}
name = (char *)"out";
x0 = CVSD_LHIST;
x1 = x0 + CVSD_FS_MAX - 1;
fprintf_array_int16(oct_file, name, CVSD_FS_MAX, plc_state.hist+x0);
fprintf(oct_file, "plot(b(%d:%d), %s, 'cd'); \n", x0, x1, name);
// for (i=0;i<CVSD_FS_MAX;i++){
// out[i] = plc_state.hist[CVSD_LHIST+i];
// }
// name = (char *)"out";
// x0 = CVSD_LHIST;
// x1 = x0 + CVSD_FS_MAX - 1;
// fprintf_array_int16(oct_file, name, CVSD_FS_MAX, plc_state.hist+x0);
// fprintf(oct_file, "plot(b(%d:%d), %s, 'cd'); \n", x0, x1, name);
// shift the history buffer
for (i=0;i<CVSD_LHIST+CVSD_RT+CVSD_OLAL;i++){
plc_state.hist[i] = plc_state.hist[i+CVSD_FS_MAX];
}
fclose(oct_file);
}
// // shift the history buffer
// for (i=0;i<CVSD_LHIST+CVSD_RT+CVSD_OLAL;i++){
// plc_state.hist[i] = plc_state.hist[i+CVSD_FS_MAX];
// }
// fclose(oct_file);
// }
// TEST(CVSD_PLC, CountEqBytes){
@ -324,31 +337,31 @@ TEST(CVSD_PLC, CountEqBytes){
// CHECK_EQUAL(23, count_equal_bytes(test_data[3],24));
// }
TEST(CVSD_PLC, TestLiveWavFile){
int corruption_step = 10;
introduce_bad_frames_to_wav_file("data/sco_input-16bit.wav", "results/sco_input.wav", 0);
introduce_bad_frames_to_wav_file("data/sco_input-16bit.wav", "results/sco_input_with_bad_frames.wav", corruption_step);
// TEST(CVSD_PLC, TestLiveWavFile){
// int corruption_step = 10;
// introduce_bad_frames_to_wav_file("data/sco_input-16bit.wav", "results/sco_input.wav", 0);
// introduce_bad_frames_to_wav_file("data/sco_input-16bit.wav", "results/sco_input_with_bad_frames.wav", corruption_step);
mark_bad_frames_wav_file("results/sco_input.wav", "results/sco_input_detected_frames.wav");
process_wav_file_with_plc("results/sco_input.wav", "results/sco_input_after_plc.wav");
process_wav_file_with_plc("results/sco_input_with_bad_frames.wav", "results/sco_input_with_bad_frames_after_plc.wav");
}
// mark_bad_frames_wav_file("results/sco_input.wav", "results/sco_input_detected_frames.wav");
// process_wav_file_with_plc("results/sco_input.wav", "results/sco_input_after_plc.wav");
// process_wav_file_with_plc("results/sco_input_with_bad_frames.wav", "results/sco_input_with_bad_frames_after_plc.wav");
// }
TEST(CVSD_PLC, TestFanfareFile){
int corruption_step = 10;
introduce_bad_frames_to_wav_file("data/fanfare_mono.wav", "results/fanfare_mono.wav", 0);
introduce_bad_frames_to_wav_file("results/fanfare_mono.wav", "results/fanfare_mono_with_bad_frames.wav", corruption_step);
// TEST(CVSD_PLC, TestFanfareFile){
// int corruption_step = 10;
// introduce_bad_frames_to_wav_file("data/fanfare_mono.wav", "results/fanfare_mono.wav", 0);
// introduce_bad_frames_to_wav_file("results/fanfare_mono.wav", "results/fanfare_mono_with_bad_frames.wav", corruption_step);
mark_bad_frames_wav_file("results/fanfare_mono.wav", "results/fanfare_mono_detected_frames.wav");
process_wav_file_with_plc("results/fanfare_mono.wav", "results/fanfare_mono_after_plc.wav");
process_wav_file_with_plc("results/fanfare_mono_with_bad_frames.wav", "results/fanfare_mono_with_bad_frames_after_plc.wav");
}
// mark_bad_frames_wav_file("results/fanfare_mono.wav", "results/fanfare_mono_detected_frames.wav");
// process_wav_file_with_plc("results/fanfare_mono.wav", "results/fanfare_mono_after_plc.wav");
// process_wav_file_with_plc("results/fanfare_mono_with_bad_frames.wav", "results/fanfare_mono_with_bad_frames_after_plc.wav");
// }
TEST(CVSD_PLC, TestSineWave){
int corruption_step = 25;
int corruption_step = 600;
create_sine_wav("results/sine_test.wav");
introduce_bad_frames_to_wav_file("results/sine_test.wav", "results/sine_test_with_bad_frames.wav", corruption_step);
int total_corruption_times = introduce_bad_frames_to_wav_file("results/sine_test.wav", "results/sine_test_with_bad_frames.wav", corruption_step);
printf("corruptions %d\n", total_corruption_times);
process_wav_file_with_plc("results/sine_test.wav", "results/sine_test_after_plc.wav");
process_wav_file_with_plc("results/sine_test_with_bad_frames.wav", "results/sine_test_with_bad_frames_after_plc.wav");
}