both_ways_line_model_state_t *both_ways_line_model_init(int model1, float noise1, int model2, float noise2, int codec, int rbs_pattern) { float echo_level; both_ways_line_model_state_t *s; if ((s = (both_ways_line_model_state_t *) malloc(sizeof(*s))) == NULL) return NULL; memset(s, 0, sizeof(*s)); s->line1.munge = codec_munge_init(codec, rbs_pattern); s->line2.munge = codec_munge_init(codec, rbs_pattern); s->line1.bulk_delay = 8; s->line2.bulk_delay = 8; s->line1.bulk_delay_ptr = 0; s->line2.bulk_delay_ptr = 0; s->line1.near_filter = models[model1]; s->line1.near_filter_len = 129; s->line2.near_filter = models[model2]; s->line2.near_filter_len = 129; s->line1.far_filter = models[model1]; s->line1.far_filter_len = 129; s->line2.far_filter = models[model2]; s->line2.far_filter_len = 129; awgn_init_dbm0(&s->line1.near_noise, 1234567, noise1); awgn_init_dbm0(&s->line2.near_noise, 7654321, noise2); awgn_init_dbm0(&s->line1.far_noise, 1234567, noise1); awgn_init_dbm0(&s->line2.far_noise, 7654321, noise2); s->line1.dc_offset = 0.0f; s->line2.dc_offset = 0.0f; s->line1.mains_interference = 0; s->line2.mains_interference = 0; /* Echos */ echo_level = -15; /* in dB */ s->line1.near_co_hybrid_echo = pow(10, echo_level/20.0); s->line2.near_co_hybrid_echo = pow(10, echo_level/20.0); s->line1.near_cpe_hybrid_echo = pow(10, echo_level/20.0); s->line2.near_cpe_hybrid_echo = pow(10, echo_level/20.0); return s; }
one_way_line_model_state_t *one_way_line_model_init(int model, float noise, int codec, int rbs_pattern) { one_way_line_model_state_t *s; if ((s = (one_way_line_model_state_t *) malloc(sizeof(*s))) == NULL) return NULL; memset(s, 0, sizeof(*s)); s->bulk_delay = 8; s->bulk_delay_ptr = 0; s->munge = codec_munge_init(codec, rbs_pattern); s->near_filter = models[model]; s->near_filter_len = 129; s->far_filter = models[model]; s->far_filter_len = 129; awgn_init_dbm0(&s->near_noise, 1234567, noise); awgn_init_dbm0(&s->far_noise, 1234567, noise); s->dc_offset = 0.0f; s->mains_interference = 0; return s; }
static int end_to_end_tests(void) { ademco_contactid_receiver_state_t *receiver; ademco_contactid_sender_state_t *sender; logging_state_t *logging; codec_munge_state_t *munge; awgn_state_t noise_source; int16_t amp[SAMPLES_PER_CHUNK]; int16_t sndfile_buf[2*SAMPLES_PER_CHUNK]; int samples; int i; int j; printf("End to end tests\n"); if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL) { fprintf(stderr, " Cannot open audio file '%s'\n", OUTPUT_FILE_NAME); exit(2); } if ((receiver = ademco_contactid_receiver_init(NULL, rx_callback, NULL)) == NULL) return -1; ademco_contactid_receiver_set_realtime_callback(receiver, rx_callback, receiver); logging = ademco_contactid_receiver_get_logging_state(receiver); span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); span_log_set_tag(logging, "Ademco-rx"); if ((sender = ademco_contactid_sender_init(NULL, tx_callback, NULL)) == NULL) return -1; ademco_contactid_sender_set_realtime_callback(sender, tx_callback, sender); logging = ademco_contactid_sender_get_logging_state(sender); span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); span_log_set_tag(logging, "Ademco-tx"); awgn_init_dbm0(&noise_source, 1234567, -50); munge = codec_munge_init(MUNGE_CODEC_ALAW, 0); sending_complete = FALSE; rx_callback_reported = FALSE; for (i = 0; i < 1000; i++) { samples = ademco_contactid_sender_tx(sender, amp, SAMPLES_PER_CHUNK); for (j = samples; j < SAMPLES_PER_CHUNK; j++) amp[j] = 0; for (j = 0; j < SAMPLES_PER_CHUNK; j++) sndfile_buf[2*j] = amp[j]; /* There is no point in impairing this signal. It is just DTMF tones, which will work as wel as the DTMF detector beign used. */ ademco_contactid_receiver_rx(receiver, amp, SAMPLES_PER_CHUNK); samples = ademco_contactid_receiver_tx(receiver, amp, SAMPLES_PER_CHUNK); for (j = samples; j < SAMPLES_PER_CHUNK; j++) amp[j] = 0; /* We add AWGN and codec impairments to the signal, to stress the tone detector. */ codec_munge(munge, amp, SAMPLES_PER_CHUNK); for (j = 0; j < SAMPLES_PER_CHUNK; j++) { sndfile_buf[2*j + 1] = amp[j]; /* Add noise to the tones */ amp[j] += awgn(&noise_source); } codec_munge(munge, amp, SAMPLES_PER_CHUNK); ademco_contactid_sender_rx(sender, amp, SAMPLES_PER_CHUNK); sf_writef_short(outhandle, sndfile_buf, SAMPLES_PER_CHUNK); } if (!rx_callback_reported) { fprintf(stderr, " Report not received\n"); return -1; } if (sf_close_telephony(outhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME); return -1; } printf(" Passed\n"); return 0; }