int r2_mf_tx(r2_mf_tx_state_t *s, int16_t amp[], int samples, int fwd, char digit) { int len; char *cp; len = 0; if ((digit & 0x80)) { /* Continue generating the tone we started earlier. */ len = tone_gen(&s->tone, amp, samples); } else if (digit == 0) { len = samples; memset(amp, 0, len*sizeof(int16_t)); } else { if ((cp = strchr(r2_mf_tone_codes, digit))) { if (fwd) tone_gen_init(&s->tone, &r2_mf_fwd_digit_tones[cp - r2_mf_tone_codes]); else tone_gen_init(&s->tone, &r2_mf_back_digit_tones[cp - r2_mf_tone_codes]); len = tone_gen(&s->tone, amp, samples); } else { len = samples; memset(amp, 0, len*sizeof(int16_t)); } } return len; }
void both_ways_line_model_set_mains_pickup(both_ways_line_model_state_t *s, int f, float level1, float level2) { tone_gen_descriptor_t mains_tone_desc; if (f) { make_tone_gen_descriptor(&mains_tone_desc, f, (int) (level1 - 10.0f), f*3, (int) level1, 1, 0, 0, 0, TRUE); tone_gen_init(&s->line1.mains_tone, &mains_tone_desc); make_tone_gen_descriptor(&mains_tone_desc, f, (int) (level2 - 10.0f), f*3, (int) level2, 1, 0, 0, 0, TRUE); tone_gen_init(&s->line2.mains_tone, &mains_tone_desc); } s->line1.mains_interference = f; s->line2.mains_interference = f; }
int bell_mf_tx(bell_mf_tx_state_t *s, int16_t amp[], int max_samples) { int len; size_t dig; char *cp; len = 0; if (s->tones.current_section >= 0) { /* Deal with the fragment left over from last time */ len = tone_gen(&(s->tones), amp, max_samples); } dig = 0; while (dig < s->current_digits && len < max_samples) { /* Step to the next digit */ if ((cp = strchr(bell_mf_tone_codes, s->digits[dig++])) == NULL) continue; tone_gen_init(&(s->tones), &(s->tone_descriptors[cp - bell_mf_tone_codes])); len += tone_gen(&(s->tones), amp + len, max_samples - len); } if (dig) { /* Shift out the consumed digits */ s->current_digits -= dig; memmove(s->digits, s->digits + dig, s->current_digits); } return len; }
SPAN_DECLARE(int) dtmf_tx(dtmf_tx_state_t *s, int16_t amp[], int max_samples) { int len; const char *cp; int digit; len = 0; if (s->tones.current_section >= 0) { /* Deal with the fragment left over from last time */ len = tone_gen(&(s->tones), amp, max_samples); } while (len < max_samples && (digit = queue_read_byte(&s->queue.queue)) >= 0) { /* Step to the next digit */ if (digit == 0) continue; if ((cp = strchr(dtmf_positions, digit)) == NULL) continue; tone_gen_init(&(s->tones), &dtmf_digit_tones[cp - dtmf_positions]); s->tones.tone[0].gain = s->low_level; s->tones.tone[1].gain = s->high_level; s->tones.duration[0] = s->on_time; s->tones.duration[1] = s->off_time; len += tone_gen(&(s->tones), amp + len, max_samples - len); } return len; }
SPAN_DECLARE(int) r2_mf_tx_put(r2_mf_tx_state_t *s, char digit) { char *cp; if (digit && (cp = strchr(r2_mf_tone_codes, digit))) { if (s->fwd) tone_gen_init(&s->tone, &r2_mf_fwd_digit_tones[cp - r2_mf_tone_codes]); else tone_gen_init(&s->tone, &r2_mf_back_digit_tones[cp - r2_mf_tone_codes]); s->digit = digit; } else { s->digit = 0; } return 0; }
void one_way_line_model_set_mains_pickup(one_way_line_model_state_t *s, int f, float level) { tone_gen_descriptor_t mains_tone_desc; if (f) { make_tone_gen_descriptor(&mains_tone_desc, f, (int) (level - 10.0f), f*3, (int) level, 1, 0, 0, 0, TRUE); tone_gen_init(&s->mains_tone, &mains_tone_desc); } s->mains_interference = f; }
bell_mf_tx_state_t *bell_mf_tx_init(bell_mf_tx_state_t *s) { if (!bell_mf_gen_inited) bell_mf_gen_init(); s->tone_descriptors = bell_mf_digit_tones; tone_gen_init(&(s->tones), &bell_mf_digit_tones[0]); s->current_sample = 0; s->current_digits = 0; s->tones.current_section = -1; return s; }
static int my_mf_generate(int16_t amp[], char digit) { int len; char *cp; tone_gen_state_t tone; len = 0; if ((cp = strchr(r2_mf_tone_codes, digit))) { tone_gen_init(&tone, &my_mf_digit_tones[cp - r2_mf_tone_codes]); len += tone_gen(&tone, amp + len, 9999); } return len; }
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s) { if (s == NULL) { if ((s = (dtmf_tx_state_t *) malloc(sizeof (*s))) == NULL) return NULL; } if (!dtmf_tx_inited) dtmf_tx_initialise(); tone_gen_init(&(s->tones), &dtmf_digit_tones[0]); dtmf_tx_set_level(s, DEFAULT_DTMF_TX_LEVEL, 0); dtmf_tx_set_timing(s, -1, -1); queue_init(&s->queue.queue, MAX_DTMF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC); s->tones.current_section = -1; return s; }
SPAN_DECLARE(bell_mf_tx_state_t *) bell_mf_tx_init(bell_mf_tx_state_t *s) { if (s == NULL) { if ((s = (bell_mf_tx_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); if (!bell_mf_gen_inited) bell_mf_gen_init(); tone_gen_init(&(s->tones), &bell_mf_digit_tones[0]); s->current_sample = 0; queue_init(&s->queue.queue, MAX_BELL_MF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC); s->tones.current_section = -1; return s; }
static void tone_setup(struct playtones_state *ps, struct playtones_item *pi) { uint16_t carrier_freq; uint16_t modulat_freq; if (pi->modulate) { /* Make sure carrier frequency higher then modulating frequency */ if (pi->freq1 > pi->freq2) { carrier_freq = pi->freq1; modulat_freq = pi->freq2; } else { carrier_freq = pi->freq2; modulat_freq = pi->freq1; } make_tone_gen_descriptor(&ps->tone_desc, carrier_freq, ps->vol, -modulat_freq, pi->modulation_depth, 1, 0, 0, 0, 1); } else { make_tone_gen_descriptor(&ps->tone_desc, pi->freq1, ps->vol, pi->freq2, ps->vol, 1, 0, 0, 0, 1); } tone_gen_init(&ps->tone_state, &ps->tone_desc); }
static int my_mf_generate(int16_t amp[], const char *digits) { int len; char *cp; tone_gen_state_t tone; len = 0; while (*digits) { if ((cp = strchr(bell_mf_tone_codes, *digits))) { tone_gen_init(&tone, &my_mf_digit_tones[cp - bell_mf_tone_codes]); len += tone_gen(&tone, amp + len, 9999); } digits++; } return len; }
SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s, digits_tx_callback_t callback, void *user_data) { if (s == NULL) { if ((s = (dtmf_tx_state_t *) malloc(sizeof (*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); if (!dtmf_tx_inited) dtmf_tx_initialise(); s->callback = callback; s->callback_data = user_data; tone_gen_init(&s->tones, &dtmf_digit_tones[0]); dtmf_tx_set_level(s, DEFAULT_DTMF_TX_LEVEL, 0); dtmf_tx_set_timing(s, -1, -1); queue_init(&s->queue.queue, MAX_DTMF_DIGITS, QUEUE_READ_ATOMIC | QUEUE_WRITE_ATOMIC); s->tones.current_section = -1; return s; }
SPAN_DECLARE(int) bell_mf_tx(bell_mf_tx_state_t *s, int16_t amp[], int max_samples) { int len; const char *cp; int digit; len = 0; if (s->tones.current_section >= 0) { /* Deal with the fragment left over from last time */ len = tone_gen(&(s->tones), amp, max_samples); } while (len < max_samples && (digit = queue_read_byte(&s->queue.queue)) >= 0) { /* Step to the next digit */ if ((cp = strchr(bell_mf_tone_codes, digit)) == NULL) continue; tone_gen_init(&(s->tones), &bell_mf_digit_tones[cp - bell_mf_tone_codes]); len += tone_gen(&(s->tones), amp + len, max_samples - len); } return len; }
int main(int argc, char *argv[]) { echo_can_state_t *ctx; awgn_state_t local_noise_source; awgn_state_t far_noise_source; int i; int clean; int residue; int16_t rx; int16_t tx; int j; int k; tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_state; int16_t local_sound[40000]; int local_max; int local_cur; int16_t hoth_noise; //int16_t far_sound[SAMPLE_RATE]; //int16_t result_sound[64000]; //int32_t coeffs[200][128]; //int coeff_index; int far_cur; int result_cur; //int far_tx; AFfilehandle resulthandle; AFfilesetup filesetup; AFfilesetup filesetup2; //int outframes; time_t now; int tone_burst_step; level_measurement_device_t *power_meter_1; level_measurement_device_t *power_meter_2; float pp1; float pp2; int model_number; int use_gui; power_meter_1 = NULL; power_meter_2 = NULL; /* Check which tests we should run */ if (argc < 2) fprintf(stderr, "Usage: echo tests <list of test numbers>\n"); test_list = 0; model_number = 0; use_gui = FALSE; for (i = 1; i < argc; i++) { if (strcasecmp(argv[i], "2a") == 0) test_list |= PERFORM_TEST_2A; else if (strcasecmp(argv[i], "2b") == 0) test_list |= PERFORM_TEST_2B; else if (strcasecmp(argv[i], "2c") == 0) test_list |= PERFORM_TEST_2C; else if (strcasecmp(argv[i], "3a") == 0) test_list |= PERFORM_TEST_3A; else if (strcasecmp(argv[i], "3b") == 0) test_list |= PERFORM_TEST_3B; else if (strcasecmp(argv[i], "3c") == 0) test_list |= PERFORM_TEST_3C; else if (strcasecmp(argv[i], "4") == 0) test_list |= PERFORM_TEST_4; else if (strcasecmp(argv[i], "5") == 0) test_list |= PERFORM_TEST_5; else if (strcasecmp(argv[i], "6") == 0) test_list |= PERFORM_TEST_6; else if (strcasecmp(argv[i], "7") == 0) test_list |= PERFORM_TEST_7; else if (strcasecmp(argv[i], "8") == 0) test_list |= PERFORM_TEST_8; else if (strcasecmp(argv[i], "9") == 0) test_list |= PERFORM_TEST_9; else if (strcasecmp(argv[i], "10a") == 0) test_list |= PERFORM_TEST_10A; else if (strcasecmp(argv[i], "10b") == 0) test_list |= PERFORM_TEST_10B; else if (strcasecmp(argv[i], "10c") == 0) test_list |= PERFORM_TEST_10C; else if (strcasecmp(argv[i], "11") == 0) test_list |= PERFORM_TEST_11; else if (strcasecmp(argv[i], "12") == 0) test_list |= PERFORM_TEST_12; else if (strcasecmp(argv[i], "13") == 0) test_list |= PERFORM_TEST_13; else if (strcasecmp(argv[i], "14") == 0) test_list |= PERFORM_TEST_14; else if (strcasecmp(argv[i], "15") == 0) test_list |= PERFORM_TEST_15; else if (strcmp(argv[i], "-m") == 0) { if (++i < argc) model_number = atoi(argv[i]); } else if (strcmp(argv[i], "-g") == 0) { use_gui = TRUE; } else { fprintf(stderr, "Unknown test '%s' specified\n", argv[i]); exit(2); } } if (test_list == 0) { fprintf(stderr, "No tests have been selected\n"); exit(2); } time(&now); tone_burst_step = 0; ctx = echo_can_create(TEST_EC_TAPS, 0); awgn_init_dbm0(&far_noise_source, 7162534, -50.0f); signal_load(&local_css, "sound_c1_8k.wav"); signal_load(&far_css, "sound_c3_8k.wav"); filesetup = afNewFileSetup(); if (filesetup == AF_NULL_FILESETUP) { fprintf(stderr, " Failed to create file setup\n"); exit(2); } afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); afInitFileFormat(filesetup, AF_FILE_WAVE); afInitChannels(filesetup, AF_DEFAULT_TRACK, 6); filesetup2 = afNewFileSetup(); if (filesetup2 == AF_NULL_FILESETUP) { fprintf(stderr, " Failed to create file setup\n"); exit(2); } afInitSampleFormat(filesetup2, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); afInitRate(filesetup2, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); afInitFileFormat(filesetup2, AF_FILE_WAVE); afInitChannels(filesetup2, AF_DEFAULT_TRACK, 1); resulthandle = afOpenFile("result_sound.wav", "w", filesetup); if (resulthandle == AF_NULL_FILEHANDLE) { fprintf(stderr, " Failed to open result file\n"); exit(2); } residuehandle = afOpenFile("residue_sound.wav", "w", filesetup2); if (residuehandle == AF_NULL_FILEHANDLE) { fprintf(stderr, " Failed to open residue file\n"); exit(2); } local_cur = 0; far_cur = 0; result_cur = 0; if (channel_model_create(model_number)) { fprintf(stderr, " Failed to create line model\n"); exit(2); } #if defined(ENABLE_GUI) if (use_gui) { start_echo_can_monitor(TEST_EC_TAPS); echo_can_monitor_line_model_update(line_model.coeffs, line_model.taps); } #endif power_meter_1 = level_measurement_device_create(0); power_meter_2 = level_measurement_device_create(0); level_measurement_device(power_meter_1, 0); #if 0 echo_can_flush(ctx); /* Converge the canceller */ signal_restart(&local_css); for (i = 0; i < 800*2; i++) { clean = echo_can_update(ctx, 0, 0); put_residue(clean); } for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); for (i = 0; i < SAMPLE_RATE*10; i++) { tx = signal_amp(&local_css); #if 0 if ((i/10000)%10 == 9) { /* Inject a burst of far sound */ if (far_cur >= far_max) { far_max = afReadFrames(farhandle, AF_DEFAULT_TRACK, far_sound, SAMPLE_RATE); if (far_max < 0) { fprintf(stderr, " Error reading far sound\n"); exit(2); } if (far_max == 0) break; far_cur = 0; } far_tx = far_sound[far_cur++]; } else { far_tx = 0; } #else far_sound[0] = 0; far_tx = 0; #endif channel_model(&tx, &rx, tx, far_tx); //rx += awgn(&far_noise_source); //tx += awgn(&far_noise_source); clean = echo_can_update(ctx, tx, rx); #if defined(XYZZY) if (i%SAMPLE_RATE == 0) { if (coeff_index < 200) { for (j = 0; j < ctx->taps; j++) coeffs[coeff_index][j] = ctx->fir_taps32[j]; coeff_index++; } } #endif result_sound[result_cur++] = tx; result_sound[result_cur++] = rx; result_sound[result_cur++] = clean - far_tx; //result_sound[result_cur++] = ctx->tx_power[2]; //result_sound[result_cur++] = ctx->tx_power[1]; result_sound[result_cur++] = (ctx->tx_power[1] > 64) ? SAMPLE_RATE : -SAMPLE_RATE; //result_sound[result_cur++] = ctx->tap_set*SAMPLE_RATE; //result_sound[result_cur++] = (ctx->nonupdate_dwell > 0) ? SAMPLE_RATE : -SAMPLE_RATE; //result_sound[result_cur++] = ctx->latest_correction >> 8; //result_sound[result_cur++] = level_measurement_device(tx)/(16.0*65536.0); //result_sound[result_cur++] = level_measurement_device(tx)/4096.0; result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0]) ? SAMPLE_RATE : -SAMPLE_RATE; //result_sound[result_cur++] = (ctx->tx_power[1] > ctx->rx_power[0]) ? SAMPLE_RATE : -SAMPLE_RATE; //result_sound[result_cur++] = (ctx->narrowband_score)*5; // ? SAMPLE_RATE : -SAMPLE_RATE; //result_sound[result_cur++] = ctx->tap_rotate_counter*10; result_sound[result_cur++] = ctx->vad; put_residue(clean - far_tx); if (result_cur >= 6*SAMPLE_RATE) { outframes = afWriteFrames(resulthandle, AF_DEFAULT_TRACK, result_sound, result_cur/6); if (outframes != result_cur/6) { fprintf(stderr, " Error writing result sound\n"); exit(2); } result_cur = 0; } } if (result_cur > 0) { outframes = afWriteFrames(resulthandle, AF_DEFAULT_TRACK, result_sound, result_cur/6); if (outframes != result_cur/4) { fprintf(stderr, " Error writing result sound\n"); exit(2); } } #endif /* Test 1 - Steady state residual and returned echo level test */ /* This functionality has been merged with test 2 in newer versions of G.168, so test 1 no longer exists. */ /* Test 2 - Convergence and steady state residual and returned echo level test */ if ((test_list & PERFORM_TEST_2A)) { printf("Performing test 2A - Convergence with NLP enabled\n"); /* Test 2A - Convergence with NLP enabled */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP); /* Converge the canceller */ signal_restart(&local_css); for (i = 0; i < 800*2; i++) { clean = echo_can_update(ctx, 0, 0); put_residue(clean); } for (i = 0; i < SAMPLE_RATE*50; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); pp1 = level_measurement_device(power_meter_1, rx); pp2 = level_measurement_device(power_meter_2, clean); residue = 100.0*pp1/pp2; put_residue(residue); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_2B)) { printf("Performing test 2B - Convergence with NLP disabled\n"); /* Test 2B - Convergence with NLP disabled */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge a canceller */ signal_restart(&local_css); for (i = 0; i < 800*2; i++) { clean = echo_can_update(ctx, 0, 0); put_residue(clean); } for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_2C)) { printf("Performing test 2C - Convergence with background noise present\n"); /* Test 2C - Convergence with background noise present */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge a canceller */ signal_restart(&local_css); for (i = 0; i < 800*2; i++) { clean = echo_can_update(ctx, 0, 0); put_residue(clean); } /* TODO: This uses a crude approx. to Hoth noise. We need the real thing. */ awgn_init_dbm0(&far_noise_source, 7162534, -40.0f); hoth_noise = 0; for (i = 0; i < SAMPLE_RATE*5; i++) { hoth_noise = hoth_noise*0.625 + awgn(&far_noise_source)*0.375; tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, hoth_noise); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Now freeze adaption, and measure the echo. */ echo_can_adaption_mode(ctx, 0); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } /* Test 3 - Performance under double talk conditions */ if ((test_list & PERFORM_TEST_3A)) { printf("Performing test 3A - Double talk test with low cancelled-end levels\n"); /* Test 3A - Double talk test with low cancelled-end levels */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); signal_restart(&local_css); signal_restart(&far_css); /* Apply double talk, with a weak far end signal */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); rx = signal_amp(&far_css)/20; channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean - rx); } /* Now freeze adaption. */ echo_can_adaption_mode(ctx, 0); for (i = 0; i < 800*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Now measure the echo */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_3B)) { printf("Performing test 3B - Double talk test with high cancelled-end levels\n"); /* Test 3B - Double talk test with high cancelled-end levels */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); signal_restart(&local_css); signal_restart(&far_css); /* Converge the canceller */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Apply double talk */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); rx = signal_amp(&far_css); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean - rx); } /* Now freeze adaption. */ echo_can_adaption_mode(ctx, 0); for (i = 0; i < 800*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Now measure the echo */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_3C)) { printf("Performing test 3C - Double talk test with simulated conversation\n"); /* Test 3C - Double talk test with simulated conversation */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); signal_restart(&local_css); signal_restart(&far_css); /* Apply double talk */ for (i = 0; i < 800*56; i++) { tx = signal_amp(&local_css); rx = signal_amp(&far_css); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean - rx); } /* Stop the far signal */ for (i = 0; i < 800*14; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Continue measuring the resulting echo */ for (i = 0; i < 800*50; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Reapply double talk */ signal_restart(&far_css); for (i = 0; i < 800*56; i++) { tx = signal_amp(&local_css); rx = signal_amp(&far_css); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean - rx); } /* Now the far signal only */ for (i = 0; i < 800*56; i++) { tx = 0; rx = signal_amp(&far_css); channel_model(&tx, &rx, 0, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean - rx); } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_4)) { printf("Performing test 4 - Leak rate test\n"); /* Test 4 - Leak rate test */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge a canceller */ signal_restart(&local_css); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Put 2 minutes of silence through it */ for (i = 0; i < SAMPLE_RATE*120; i++) { clean = echo_can_update(ctx, 0, 0); put_residue(clean); } /* Now freeze it, and check if it is still well adapted. */ echo_can_adaption_mode(ctx, 0); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_5)) { printf("Performing test 5 - Infinite return loss convergence test\n"); /* Test 5 - Infinite return loss convergence test */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge the canceller */ signal_restart(&local_css); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Now stop echoing, and see we don't do anything unpleasant as the echo path is open looped. */ for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); rx = 0; tx = codec_munge(tx); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_6)) { printf("Performing test 6 - Non-divergence on narrow-band signals\n"); /* Test 6 - Non-divergence on narrow-band signals */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge the canceller */ signal_restart(&local_css); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Now put 5s bursts of a list of tones through the converged canceller, and check that bothing unpleasant happens. */ for (k = 0; tones_6_4_2_7[k][0]; k++) { make_tone_gen_descriptor(&tone_desc, tones_6_4_2_7[k][0], -11, tones_6_4_2_7[k][1], -9, 1, 0, 0, 0, 1); tone_gen_init(&tone_state, &tone_desc); j = 0; for (i = 0; i < 5; i++) { local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE); for (j = 0; j < SAMPLE_RATE; j++) { tx = local_sound[j]; channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } #if defined(ENABLE_GUI) if (use_gui) { echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); echo_can_monitor_update_display(); usleep(100000); } #endif } } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_7)) { printf("Performing test 7 - Stability\n"); /* Test 7 - Stability */ /* Put tones through an unconverged canceller, and check nothing unpleasant happens. */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); make_tone_gen_descriptor(&tone_desc, tones_6_4_2_7[0][0], -11, tones_6_4_2_7[0][1], -9, 1, 0, 0, 0, 1); tone_gen_init(&tone_state, &tone_desc); j = 0; for (i = 0; i < 120; i++) { local_max = tone_gen(&tone_state, local_sound, SAMPLE_RATE); for (j = 0; j < SAMPLE_RATE; j++) { tx = local_sound[j]; channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } #if defined(ENABLE_GUI) if (use_gui) { echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); echo_can_monitor_update_display(); usleep(100000); } #endif } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } if ((test_list & PERFORM_TEST_8)) { printf("Performing test 8 - Non-convergence on No 5, 6, and 7 in-band signalling\n"); /* Test 8 - Non-convergence on No 5, 6, and 7 in-band signalling */ fprintf(stderr, "Test 8 not yet implemented\n"); } if ((test_list & PERFORM_TEST_9)) { printf("Performing test 9 - Comfort noise test\n"); /* Test 9 - Comfort noise test */ /* Test 9 part 1 - matching */ echo_can_flush(ctx); echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION); /* Converge the canceller */ signal_restart(&local_css); for (i = 0; i < SAMPLE_RATE*5; i++) { tx = signal_amp(&local_css); channel_model(&tx, &rx, tx, 0); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } echo_can_adaption_mode(ctx, ECHO_CAN_USE_ADAPTION | ECHO_CAN_USE_NLP | ECHO_CAN_USE_CNG); awgn_init_dbm0(&far_noise_source, 7162534, -45.0f); for (i = 0; i < SAMPLE_RATE*30; i++) { tx = 0; rx = awgn(&far_noise_source); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } awgn_init_dbm0(&local_noise_source, 1234567, -10.0f); for (i = 0; i < SAMPLE_RATE*2; i++) { tx = awgn(&local_noise_source); rx = awgn(&far_noise_source); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } /* Test 9 part 2 - adjust down */ awgn_init_dbm0(&far_noise_source, 7162534, -55.0f); for (i = 0; i < SAMPLE_RATE*10; i++) { tx = 0; rx = awgn(&far_noise_source); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } for (i = 0; i < SAMPLE_RATE*2; i++) { tx = awgn(&local_noise_source); rx = awgn(&far_noise_source); channel_model(&tx, &rx, tx, rx); clean = echo_can_update(ctx, tx, rx); put_residue(clean); } #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_can_update(ctx->fir_taps16[ctx->tap_set], TEST_EC_TAPS); #endif } /* Test 10 - FAX test during call establishment phase */ if ((test_list & PERFORM_TEST_10A)) { printf("Performing test 10A - Canceller operation on the calling station side\n"); /* Test 10A - Canceller operation on the calling station side */ fprintf(stderr, "Test 10A not yet implemented\n"); } if ((test_list & PERFORM_TEST_10B)) { printf("Performing test 10B - Canceller operation on the called station side\n"); /* Test 10B - Canceller operation on the called station side */ fprintf(stderr, "Test 10B not yet implemented\n"); } if ((test_list & PERFORM_TEST_10C)) { printf("Performing test 10C - Canceller operation on the calling station side during page\n" "transmission and page breaks (for further study)\n"); /* Test 10C - Canceller operation on the calling station side during page transmission and page breaks (for further study) */ fprintf(stderr, "Test 10C not yet implemented\n"); } if ((test_list & PERFORM_TEST_11)) { printf("Performing test 11 - Tandem echo canceller test (for further study)\n"); /* Test 11 - Tandem echo canceller test (for further study) */ fprintf(stderr, "Test 11 not yet implemented\n"); } if ((test_list & PERFORM_TEST_12)) { printf("Performing test 12 - Residual acoustic echo test (for further study)\n"); /* Test 12 - Residual acoustic echo test (for further study) */ fprintf(stderr, "Test 12 not yet implemented\n"); } if ((test_list & PERFORM_TEST_13)) { printf("Performing test 13 - Performance with ITU-T low-bit rate coders in echo path (Optional, under study)\n"); /* Test 13 - Performance with ITU-T low-bit rate coders in echo path (Optional, under study) */ fprintf(stderr, "Test 13 not yet implemented\n"); } if ((test_list & PERFORM_TEST_14)) { printf("Performing test 14 - Performance with V-series low-speed data modems\n"); /* Test 14 - Performance with V-series low-speed data modems */ fprintf(stderr, "Test 14 not yet implemented\n"); } if ((test_list & PERFORM_TEST_15)) { printf("Performing test 15 - PCM offset test (Optional)\n"); /* Test 15 - PCM offset test (Optional) */ fprintf(stderr, "Test 15 not yet implemented\n"); } echo_can_free(ctx); signal_free(&local_css); signal_free(&far_css); if (afCloseFile(resulthandle) != 0) { fprintf(stderr, " Cannot close speech file '%s'\n", "result_sound.wav"); exit(2); } if (afCloseFile(residuehandle) != 0) { fprintf(stderr, " Cannot close speech file '%s'\n", "residue_sound.wav"); exit(2); } afFreeFileSetup(filesetup); afFreeFileSetup(filesetup2); #if defined(XYZZY) for (j = 0; j < ctx->taps; j++) { for (i = 0; i < coeff_index; i++) fprintf(stderr, "%d ", coeffs[i][j]); fprintf(stderr, "\n"); } #endif printf("Run time %lds\n", time(NULL) - now); #if defined(ENABLE_GUI) if (use_gui) echo_can_monitor_wait_to_end(); #endif if (power_meter_1) level_measurement_device_release(power_meter_1); if (power_meter_2) level_measurement_device_release(power_meter_2); printf("Tests passed.\n"); return 0; }
int main(int argc, char *argv[]) { tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_state; int i; int16_t amp[16384]; int len; SNDFILE *outhandle; int outframes; if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL) { fprintf(stderr, " Cannot open audio file '%s'\n", OUTPUT_FILE_NAME); exit(2); } /* Try a tone pair */ tone_gen_descriptor_init(&tone_desc, 440, -10, 620, -15, 100, 200, 300, 400, FALSE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try a different tone pair */ tone_gen_descriptor_init(&tone_desc, 350, -10, 440, -15, 400, 300, 200, 100, TRUE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try a different tone pair */ tone_gen_descriptor_init(&tone_desc, 400, -10, 450, -10, 100, 200, 300, 400, TRUE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try a single tone */ tone_gen_descriptor_init(&tone_desc, 400, -10, 0, 0, 100, 200, 300, 400, TRUE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try a single non-repeating tone */ tone_gen_descriptor_init(&tone_desc, 820, -10, 0, 0, 2000, 0, 0, 0, FALSE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try a single non-repeating tone at 0dBm0 */ tone_gen_descriptor_init(&tone_desc, 820, 0, 0, 0, 2000, 0, 0, 0, FALSE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try an AM modulated tone at a modest modulation level (25%) */ tone_gen_descriptor_init(&tone_desc, 425, -10, -50, 25, 100, 200, 300, 400, TRUE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } /* Try an AM modulated tone at maximum modulation level (100%) */ tone_gen_descriptor_init(&tone_desc, 425, -10, -50, 100, 100, 200, 300, 400, TRUE); tone_gen_init(&tone_state, &tone_desc); for (i = 0; i < 1000; i++) { len = tone_gen(&tone_state, amp, 160); printf("Generated %d samples\n", len); if (len <= 0) break; outframes = sf_writef_short(outhandle, amp, len); } if (sf_close(outhandle) != 0) { fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME); exit (2); } return 0; }
int main(int argc, char *argv[]) { fsk_tx_state_t *caller_tx; fsk_rx_state_t *caller_rx; fsk_tx_state_t *answerer_tx; fsk_rx_state_t *answerer_rx; bert_state_t caller_bert; bert_state_t answerer_bert; bert_results_t bert_results; power_meter_t caller_meter; power_meter_t answerer_meter; int16_t caller_amp[BLOCK_LEN]; int16_t answerer_amp[BLOCK_LEN]; int16_t caller_model_amp[BLOCK_LEN]; int16_t answerer_model_amp[BLOCK_LEN]; int16_t out_amp[2*BLOCK_LEN]; AFfilehandle inhandle; AFfilehandle outhandle; int outframes; int i; int j; int samples; int test_bps; int noise_level; int noise_sweep; int bits_per_test; int line_model_no; int modem_under_test_1; int modem_under_test_2; int modems_set; int log_audio; int channel_codec; int rbs_pattern; int on_at; int off_at; tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_tx; int opt; channel_codec = MUNGE_CODEC_NONE; rbs_pattern = 0; line_model_no = 0; decode_test_file = NULL; noise_sweep = FALSE; modem_under_test_1 = FSK_V21CH1; modem_under_test_2 = FSK_V21CH2; log_audio = FALSE; modems_set = 0; while ((opt = getopt(argc, argv, "c:dlm:nr:s:")) != -1) { switch (opt) { case 'c': channel_codec = atoi(optarg); break; case 'd': decode_test_file = optarg; break; case 'l': log_audio = TRUE; break; case 'm': line_model_no = atoi(optarg); break; case 'n': noise_sweep = TRUE; break; case 'r': rbs_pattern = atoi(optarg); break; case 's': switch (modems_set++) { case 0: modem_under_test_1 = atoi(optarg); break; case 1: modem_under_test_2 = atoi(optarg); break; } break; default: //usage(); exit(2); break; } } if (modem_under_test_1 >= 0) printf("Modem channel 1 is '%s'\n", preset_fsk_specs[modem_under_test_1].name); if (modem_under_test_2 >= 0) printf("Modem channel 2 is '%s'\n", preset_fsk_specs[modem_under_test_2].name); outhandle = AF_NULL_FILEHANDLE; if (log_audio) { if ((outhandle = afOpenFile_telephony_write(OUTPUT_FILE_NAME, 2)) == AF_NULL_FILEHANDLE) { fprintf(stderr, " Cannot create wave file '%s'\n", OUTPUT_FILE_NAME); exit(2); } } noise_level = -200; bits_per_test = 0; inhandle = NULL; memset(caller_amp, 0, sizeof(*caller_amp)); memset(answerer_amp, 0, sizeof(*answerer_amp)); memset(caller_model_amp, 0, sizeof(*caller_model_amp)); memset(answerer_model_amp, 0, sizeof(*answerer_model_amp)); power_meter_init(&caller_meter, 7); power_meter_init(&answerer_meter, 7); if (decode_test_file) { if ((inhandle = afOpenFile_telephony_read(decode_test_file, 1)) == AF_NULL_FILEHANDLE) { fprintf(stderr, " Cannot open wave file '%s'\n", decode_test_file); exit(2); } caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, put_bit, NULL); fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; for (;;) { samples = afReadFrames(inhandle, AF_DEFAULT_TRACK, caller_model_amp, BLOCK_LEN); if (samples < BLOCK_LEN) break; for (i = 0; i < samples; i++) power_meter_update(&caller_meter, caller_model_amp[i]); fsk_rx(caller_rx, caller_model_amp, samples); } if (afCloseFile(inhandle) != 0) { fprintf(stderr, " Cannot close wave file '%s'\n", decode_test_file); exit(2); } } else { printf("Test cutoff level\n"); caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, cutoff_test_put_bit, NULL); fsk_rx_signal_cutoff(caller_rx, -30.0f); fsk_rx_set_modem_status_handler(caller_rx, cutoff_test_rx_status, (void *) &caller_rx); on_at = 0; for (i = -40; i < -25; i++) { make_tone_gen_descriptor(&tone_desc, 1500, i, 0, 0, 1, 0, 0, 0, TRUE); tone_gen_init(&tone_tx, &tone_desc); for (j = 0; j < 10; j++) { samples = tone_gen(&tone_tx, caller_model_amp, 160); fsk_rx(caller_rx, caller_model_amp, samples); } if (cutoff_test_carrier) break; } on_at = i; off_at = 0; for ( ; i > -40; i--) { make_tone_gen_descriptor(&tone_desc, 1500, i, 0, 0, 1, 0, 0, 0, TRUE); tone_gen_init(&tone_tx, &tone_desc); for (j = 0; j < 10; j++) { samples = tone_gen(&tone_tx, caller_model_amp, 160); fsk_rx(caller_rx, caller_model_amp, samples); } if (!cutoff_test_carrier) break; } off_at = i; printf("Carrier on at %d, off at %d\n", on_at, off_at); if (on_at < -29 || on_at > -26 || off_at < -35 || off_at > -31) { printf("Tests failed.\n"); exit(2); } printf("Test with BERT\n"); test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; if (modem_under_test_1 >= 0) { caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert); fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx); answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, (put_bit_func_t) bert_put_bit, &answerer_bert); fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx); } if (modem_under_test_2 >= 0) { answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert); fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx); caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], TRUE, (put_bit_func_t) bert_put_bit, &caller_bert); fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); } test_bps = preset_fsk_specs[modem_under_test_1].baud_rate; bits_per_test = 500000; noise_level = -24; bert_init(&caller_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); bert_set_report(&caller_bert, 100000, reporter, (void *) (intptr_t) 1); bert_init(&answerer_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); bert_set_report(&answerer_bert, 100000, reporter, (void *) (intptr_t) 2); if ((model = both_ways_line_model_init(line_model_no, (float) noise_level, line_model_no, (float) noise_level, channel_codec, rbs_pattern)) == NULL) { fprintf(stderr, " Failed to create line model\n"); exit(2); } for (;;) { samples = fsk_tx(caller_tx, caller_amp, BLOCK_LEN); for (i = 0; i < samples; i++) power_meter_update(&caller_meter, caller_amp[i]); samples = fsk_tx(answerer_tx, answerer_amp, BLOCK_LEN); for (i = 0; i < samples; i++) power_meter_update(&answerer_meter, answerer_amp[i]); both_ways_line_model(model, caller_model_amp, caller_amp, answerer_model_amp, answerer_amp, samples); //printf("Powers %10.5fdBm0 %10.5fdBm0\n", power_meter_current_dbm0(&caller_meter), power_meter_current_dbm0(&answerer_meter)); fsk_rx(answerer_rx, caller_model_amp, samples); for (i = 0; i < samples; i++) out_amp[2*i] = caller_model_amp[i]; for ( ; i < BLOCK_LEN; i++) out_amp[2*i] = 0; fsk_rx(caller_rx, answerer_model_amp, samples); for (i = 0; i < samples; i++) out_amp[2*i + 1] = answerer_model_amp[i]; for ( ; i < BLOCK_LEN; i++) out_amp[2*i + 1] = 0; if (log_audio) { outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, out_amp, BLOCK_LEN); if (outframes != BLOCK_LEN) { fprintf(stderr, " Error writing wave file\n"); exit(2); } } if (samples < BLOCK_LEN) { bert_result(&caller_bert, &bert_results); fprintf(stderr, "%ddB AWGN, %d bits, %d bad bits, %d resyncs\n", noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); if (!noise_sweep) { if (bert_results.total_bits != bits_per_test - 43 || bert_results.bad_bits != 0 || bert_results.resyncs != 0) { printf("Tests failed.\n"); exit(2); } } bert_result(&answerer_bert, &bert_results); fprintf(stderr, "%ddB AWGN, %d bits, %d bad bits, %d resyncs\n", noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs); if (!noise_sweep) { if (bert_results.total_bits != bits_per_test - 43 || bert_results.bad_bits != 0 || bert_results.resyncs != 0) { printf("Tests failed.\n"); exit(2); } break; } /* Put a little silence between the chunks in the file. */ memset(out_amp, 0, sizeof(out_amp)); if (log_audio) { for (i = 0; i < 200; i++) { outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, out_amp, BLOCK_LEN); } } if (modem_under_test_1 >= 0) { caller_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_1], (get_bit_func_t) bert_get_bit, &caller_bert); fsk_tx_set_modem_status_handler(caller_tx, tx_status, (void *) &caller_tx); answerer_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_1], TRUE, (put_bit_func_t) bert_put_bit, &answerer_bert); fsk_rx_set_modem_status_handler(answerer_rx, rx_status, (void *) &answerer_rx); } if (modem_under_test_2 >= 0) { answerer_tx = fsk_tx_init(NULL, &preset_fsk_specs[modem_under_test_2], (get_bit_func_t) bert_get_bit, &answerer_bert); fsk_tx_set_modem_status_handler(answerer_tx, tx_status, (void *) &answerer_tx); caller_rx = fsk_rx_init(NULL, &preset_fsk_specs[modem_under_test_2], TRUE, (put_bit_func_t) bert_put_bit, &caller_bert); fsk_rx_set_modem_status_handler(caller_rx, rx_status, (void *) &caller_rx); } noise_level++; if ((model = both_ways_line_model_init(line_model_no, (float) noise_level, line_model_no, noise_level, channel_codec, 0)) == NULL) { fprintf(stderr, " Failed to create line model\n"); exit(2); } bert_init(&caller_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); bert_set_report(&caller_bert, 100000, reporter, (void *) (intptr_t) 1); bert_init(&answerer_bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20); bert_set_report(&answerer_bert, 100000, reporter, (void *) (intptr_t) 2); } } printf("Tests passed.\n"); } if (log_audio) { if (afCloseFile(outhandle) != 0) { fprintf(stderr, " Cannot close wave file '%s'\n", OUTPUT_FILE_NAME); exit(2); } } return 0; }
static void fax_set_tx_type(void *user_data, int type, int short_train, int use_hdlc) { fax_state_t *s; tone_gen_descriptor_t tone_desc; get_bit_func_t get_bit_func; void *get_bit_user_data; s = (fax_state_t *) user_data; span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type); if (s->current_tx_type == type) return; s->first_tx_hdlc_frame = TRUE; if (use_hdlc) { get_bit_func = (get_bit_func_t) hdlc_tx_get_bit; get_bit_user_data = (void *) &(s->hdlctx); } else { get_bit_func = t30_non_ecm_get_bit; get_bit_user_data = (void *) &(s->t30_state); } switch (type) { case T30_MODEM_PAUSE: silence_gen_alter(&(s->silence_gen), ms_to_samples(short_train)); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = NULL; s->transmit = TRUE; break; case T30_MODEM_CNG: /* 0.5s of 1100Hz+-38Hz + 3.0s of silence repeating. Timing +-15% */ make_tone_gen_descriptor(&tone_desc, 1100, -11, 0, 0, 500, 3000, 0, 0, TRUE); tone_gen_init(&(s->tone_gen), &tone_desc); s->tx_handler = (span_tx_handler_t *) &tone_gen; s->tx_user_data = &(s->tone_gen); s->next_tx_handler = NULL; s->transmit = TRUE; break; case T30_MODEM_CED: /* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. The 75ms of silence will be inserted by the pre V.21 pause we use for any switch to V.21. */ silence_gen_alter(&(s->silence_gen), ms_to_samples(200)); make_tone_gen_descriptor(&tone_desc, 2100, -11, 0, 0, 2600, 0, 0, 0, FALSE); tone_gen_init(&(s->tone_gen), &tone_desc); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &tone_gen; s->next_tx_user_data = &(s->tone_gen); s->transmit = TRUE; break; case T30_MODEM_V21: fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], get_bit_func, get_bit_user_data); /* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */ hdlc_tx_flags(&(s->hdlctx), 32); /* Pause before switching from phase C, as per T.30 5.3.2.2. If we omit this, the receiver might not see the carrier fall between the high speed and low speed sections. In practice, a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of a call, and ensures the receiving end is ready. */ silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &fsk_tx; s->next_tx_user_data = &(s->v21tx); s->transmit = TRUE; break; case T30_MODEM_V27TER_2400: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v27ter_tx_restart(&(s->v27ter_tx), 2400, s->use_tep); v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx; s->next_tx_user_data = &(s->v27ter_tx); hdlc_tx_flags(&(s->hdlctx), 60); s->transmit = TRUE; break; case T30_MODEM_V27TER_4800: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v27ter_tx_restart(&(s->v27ter_tx), 4800, s->use_tep); v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx; s->next_tx_user_data = &(s->v27ter_tx); hdlc_tx_flags(&(s->hdlctx), 120); s->transmit = TRUE; break; case T30_MODEM_V29_7200: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v29_tx_restart(&(s->v29tx), 7200, s->use_tep); v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v29_tx; s->next_tx_user_data = &(s->v29tx); hdlc_tx_flags(&(s->hdlctx), 180); s->transmit = TRUE; break; case T30_MODEM_V29_9600: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v29_tx_restart(&(s->v29tx), 9600, s->use_tep); v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v29_tx; s->next_tx_user_data = &(s->v29tx); hdlc_tx_flags(&(s->hdlctx), 240); s->transmit = TRUE; break; case T30_MODEM_V17_7200: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v17_tx_restart(&(s->v17tx), 7200, s->use_tep, short_train); v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v17_tx; s->next_tx_user_data = &(s->v17tx); hdlc_tx_flags(&(s->hdlctx), 180); s->transmit = TRUE; break; case T30_MODEM_V17_9600: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v17_tx_restart(&(s->v17tx), 9600, s->use_tep, short_train); v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v17_tx; s->next_tx_user_data = &(s->v17tx); hdlc_tx_flags(&(s->hdlctx), 240); s->transmit = TRUE; break; case T30_MODEM_V17_12000: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v17_tx_restart(&(s->v17tx), 12000, s->use_tep, short_train); v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v17_tx; s->next_tx_user_data = &(s->v17tx); hdlc_tx_flags(&(s->hdlctx), 300); s->transmit = TRUE; break; case T30_MODEM_V17_14400: silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); v17_tx_restart(&(s->v17tx), 14400, s->use_tep, short_train); v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = (span_tx_handler_t *) &v17_tx; s->next_tx_user_data = &(s->v17tx); hdlc_tx_flags(&(s->hdlctx), 360); s->transmit = TRUE; break; case T30_MODEM_DONE: span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); /* Fall through */ default: silence_gen_alter(&(s->silence_gen), 0); s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &(s->silence_gen); s->next_tx_handler = NULL; s->transmit = FALSE; break; } s->current_tx_type = type; }
static int power_meter_tests(void) { awgn_state_t noise_source; power_meter_t meter; tone_gen_descriptor_t tone_desc; tone_gen_state_t gen; int i; int idum = 1234567; int16_t amp[1000]; int len; int32_t level; power_meter_init(&meter, 7); printf("Testing with zero in the power register\n"); printf("Power: expected %fdBm0, got %fdBm0\n", -90.169f, power_meter_current_dbm0(&meter)); printf("Power: expected %fdBOv, got %fdBOv\n", -96.329f, power_meter_current_dbov(&meter)); printf("Testing with a square wave 10dB from maximum\n"); for (i = 0; i < 1000; i++) { amp[i] = (i & 1) ? 10362 : -10362; level = power_meter_update(&meter, amp[i]); //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter)); } printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level); printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter)); printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter)); if (level < power_meter_level_dbov(-10.0f)*0.99f || level > power_meter_level_dbov(-10.0f)*1.01f) { printf("Test failed (level)\n"); exit(2); } if (0.1f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER)) { printf("Test failed (dBm0)\n"); exit(2); } if (0.1f < fabsf(power_meter_current_dbov(&meter) + 10.0)) { printf("Test failed (dBOv)\n"); exit(2); } printf("Testing with a sine wave tone 10dB from maximum\n"); tone_gen_descriptor_init(&tone_desc, 1000, -4, 0, 1, 1, 0, 0, 0, true); tone_gen_init(&gen, &tone_desc); len = tone_gen(&gen, amp, 1000); for (i = 0; i < len; i++) { level = power_meter_update(&meter, amp[i]); //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter)); } printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level); printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter)); printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter)); if (level < power_meter_level_dbov(-10.0f)*0.95f || level > power_meter_level_dbov(-10.0f)*1.05f) { printf("Test failed (level)\n"); exit(2); } if (0.2f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER)) { printf("Test failed (dBm0)\n"); exit(2); } if (0.2f < fabsf(power_meter_current_dbov(&meter) + 10.0)) { printf("Test failed (dBOv)\n"); exit(2); } printf("Testing with AWGN 10dB from maximum\n"); awgn_init_dbov(&noise_source, idum, -10.0f); for (i = 0; i < 1000; i++) amp[i] = awgn(&noise_source); for (i = 0; i < 1000; i++) { level = power_meter_update(&meter, amp[i]); //printf("%12d %fdBm0 %fdBov\n", level, power_meter_current_dbm0(&meter), power_meter_current_dbov(&meter)); } printf("Level: expected %" PRId32 "/%" PRId32 ", got %" PRId32 "\n", power_meter_level_dbov(-10.0f), power_meter_level_dbm0(-10.0f + DBM0_MAX_POWER), level); printf("Power: expected %fdBm0, got %fdBm0\n", -10.0f + DBM0_MAX_POWER, power_meter_current_dbm0(&meter)); printf("Power: expected %fdBOv, got %fdBOv\n", -10.0f, power_meter_current_dbov(&meter)); if (level < power_meter_level_dbov(-10.0f)*0.95f || level > power_meter_level_dbov(-10.0f)*1.05f) { printf("Test failed (level)\n"); exit(2); } if (0.2f < fabsf(power_meter_current_dbm0(&meter) + 10.0f - DBM0_MAX_POWER)) { printf("Test failed (dBm0)\n"); exit(2); } if (0.2f < fabsf(power_meter_current_dbov(&meter) + 10.0f)) { printf("Test failed (dBOv)\n"); exit(2); } return 0; }
int main(int argc, char *argv[]) { int f; int i; int16_t amp[8000]; int16_t value; int signal; float power[10]; tone_gen_descriptor_t tone_desc; tone_gen_state_t tone_state; awgn_state_t noise_source; fir32_state_t line_model_d2; fir32_state_t line_model_d3; fir32_state_t line_model_d4; fir32_state_t line_model_d5; fir32_state_t line_model_d6; fir32_state_t line_model_d7; fir32_state_t line_model_d8; fir32_state_t line_model_d9; fir_float_state_t level_measurement_bp; signal_load(&local_css, "sound_c1_8k.wav"); signal_load(&far_css, "sound_c3_8k.wav"); fir32_create(&line_model_d2, line_model_d2_coeffs, sizeof(line_model_d2_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d3, line_model_d3_coeffs, sizeof(line_model_d3_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d4, line_model_d4_coeffs, sizeof(line_model_d4_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d5, line_model_d5_coeffs, sizeof(line_model_d5_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d6, line_model_d6_coeffs, sizeof(line_model_d6_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d7, line_model_d7_coeffs, sizeof(line_model_d7_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d8, line_model_d8_coeffs, sizeof(line_model_d8_coeffs)/sizeof(int32_t)); fir32_create(&line_model_d9, line_model_d9_coeffs, sizeof(line_model_d9_coeffs)/sizeof(int32_t)); fir_float_create(&level_measurement_bp, level_measurement_bp_coeffs, sizeof(level_measurement_bp_coeffs)/sizeof(float)); for (f = 10; f < 4000; f++) { tone_gen_descriptor_init(&tone_desc, f, -10, 0, 0, 1, 0, 0, 0, true); tone_gen_init(&tone_state, &tone_desc); tone_gen(&tone_state, amp, 8000); for (i = 0; i < 10; i++) power[i] = 0.0f; for (i = 0; i < 800; i++) { signal = fir32(&line_model_d2, amp[i]); power[0] += ((signal*signal - power[0])/32.0f); signal = fir32(&line_model_d3, amp[i]); power[1] += ((signal*signal - power[1])/32.0f); signal = fir32(&line_model_d4, amp[i]); power[2] += ((signal*signal - power[2])/32.0f); signal = fir32(&line_model_d5, amp[i]); power[3] += ((signal*signal - power[3])/32.0f); signal = fir32(&line_model_d6, amp[i]); power[4] += ((signal*signal - power[4])/32.0f); signal = fir32(&line_model_d7, amp[i]); power[5] += ((signal*signal - power[5])/32.0f); signal = fir32(&line_model_d8, amp[i]); power[6] += ((signal*signal - power[6])/32.0f); signal = fir32(&line_model_d9, amp[i]); power[7] += ((signal*signal - power[7])/32.0f); signal = fir_float(&level_measurement_bp, amp[i]); power[8] += ((signal*signal - power[8])/32.0f); signal = amp[i]; power[9] += ((signal*signal - power[9])/32.0f); } printf("%d %f %f %f %f %f %f %f %f %f %f\n", f, sqrt(power[0])*LINE_MODEL_D2_GAIN, sqrt(power[1])*LINE_MODEL_D3_GAIN, sqrt(power[2])*LINE_MODEL_D4_GAIN, sqrt(power[3])*LINE_MODEL_D5_GAIN, sqrt(power[4])*LINE_MODEL_D6_GAIN, sqrt(power[5])*LINE_MODEL_D7_GAIN, sqrt(power[6])*LINE_MODEL_D8_GAIN, sqrt(power[7])*LINE_MODEL_D9_GAIN, sqrt(power[8]), sqrt(power[9])); } awgn_init_dbm0(&noise_source, 1234567, -20.0f); for (i = 0; i < 10; i++) power[i] = 0.0f; signal_restart(&local_css, 0.0f); signal_restart(&far_css, 0.0f); for (i = 0; i < SAMPLE_RATE; i++) { value = signal_amp(&local_css); //value = awgn(&noise_source); signal = fir32(&line_model_d2, value); power[0] += ((signal*signal - power[0])/32.0f); signal = fir32(&line_model_d3, value); power[1] += ((signal*signal - power[1])/32.0f); signal = fir32(&line_model_d4, value); power[2] += ((signal*signal - power[2])/32.0f); signal = fir32(&line_model_d5, value); power[3] += ((signal*signal - power[3])/32.0f); signal = fir32(&line_model_d6, value); power[4] += ((signal*signal - power[4])/32.0f); signal = fir32(&line_model_d7, value); power[5] += ((signal*signal - power[5])/32.0f); signal = fir32(&line_model_d8, value); power[6] += ((signal*signal - power[6])/32.0f); signal = fir32(&line_model_d9, value); power[7] += ((signal*signal - power[7])/32.0f); signal = fir_float(&level_measurement_bp, value); power[8] += ((signal*signal - power[8])/32.0f); signal = value; power[9] += ((signal*signal - power[9])/32.0f); } for (i = 0; i < 10; i++) power[i] = 0.0f; for (i = 0; i < SAMPLE_RATE; i++) { value = signal_amp(&local_css); //value = awgn(&noise_source); signal = fir32(&line_model_d2, value); power[0] += ((signal*signal - power[0])/32.0f); signal = fir32(&line_model_d3, value); power[1] += ((signal*signal - power[1])/32.0f); signal = fir32(&line_model_d4, value); power[2] += ((signal*signal - power[2])/32.0f); signal = fir32(&line_model_d5, value); power[3] += ((signal*signal - power[3])/32.0f); signal = fir32(&line_model_d6, value); power[4] += ((signal*signal - power[4])/32.0f); signal = fir32(&line_model_d7, value); power[5] += ((signal*signal - power[5])/32.0f); signal = fir32(&line_model_d8, value); power[6] += ((signal*signal - power[6])/32.0f); signal = fir32(&line_model_d9, value); power[7] += ((signal*signal - power[7])/32.0f); signal = fir_float(&level_measurement_bp, value); power[8] += ((signal*signal - power[8])/32.0f); signal = value; power[9] += ((signal*signal - power[9])/32.0f); } printf("%d %f %f %f %f %f %f %f %f %f %f\n", 0, sqrt(power[0])*LINE_MODEL_D2_GAIN, sqrt(power[1])*LINE_MODEL_D3_GAIN, sqrt(power[2])*LINE_MODEL_D4_GAIN, sqrt(power[3])*LINE_MODEL_D5_GAIN, sqrt(power[4])*LINE_MODEL_D6_GAIN, sqrt(power[5])*LINE_MODEL_D7_GAIN, sqrt(power[6])*LINE_MODEL_D8_GAIN, sqrt(power[7])*LINE_MODEL_D9_GAIN, sqrt(power[8]), sqrt(power[9])); printf("%d %f %f %f %f %f %f %f %f %f %f\n", 0, sqrt(power[0]), sqrt(power[1]), sqrt(power[2]), sqrt(power[3]), sqrt(power[4]), sqrt(power[5]), sqrt(power[6]), sqrt(power[7]), sqrt(power[8]), sqrt(power[9])); printf("%d %f %f %f %f %f %f %f %f %f %f\n", 0, sqrt(power[0])/sqrt(power[9]), sqrt(power[1])/sqrt(power[9]), sqrt(power[2])/sqrt(power[9]), sqrt(power[3])/sqrt(power[9]), sqrt(power[4])/sqrt(power[9]), sqrt(power[5])/sqrt(power[9]), sqrt(power[6])/sqrt(power[9]), sqrt(power[7])/sqrt(power[9]), sqrt(power[8]), sqrt(power[9])); printf("%d %f %f %f %f %f %f %f %f %f %f\n", 0, sqrt(power[0])*LINE_MODEL_D2_GAIN/sqrt(power[9]), sqrt(power[1])*LINE_MODEL_D3_GAIN/sqrt(power[9]), sqrt(power[2])*LINE_MODEL_D4_GAIN/sqrt(power[9]), sqrt(power[3])*LINE_MODEL_D5_GAIN/sqrt(power[9]), sqrt(power[4])*LINE_MODEL_D6_GAIN/sqrt(power[9]), sqrt(power[5])*LINE_MODEL_D7_GAIN/sqrt(power[9]), sqrt(power[6])*LINE_MODEL_D8_GAIN/sqrt(power[9]), sqrt(power[7])*LINE_MODEL_D9_GAIN/sqrt(power[9]), sqrt(power[8]), sqrt(power[9])); for (i = 0; i < (int) (sizeof(css_c1)/sizeof(css_c1[0])); i++) printf("%d\n", css_c1[i]); printf("\n"); for (i = 0; i < (int) (sizeof(css_c1)/sizeof(css_c3[0])); i++) printf("%d\n", css_c3[i]); signal_free(&local_css); signal_free(&far_css); fir32_free(&line_model_d2); fir32_free(&line_model_d3); fir32_free(&line_model_d4); fir32_free(&line_model_d5); fir32_free(&line_model_d6); fir32_free(&line_model_d7); fir32_free(&line_model_d8); fir32_free(&line_model_d9); fir_float_free(&level_measurement_bp); return 0; }