SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s, int use_tep, hdlc_frame_handler_t hdlc_accept, hdlc_underflow_handler_t hdlc_tx_underflow, put_bit_func_t non_ecm_put_bit, get_bit_func_t non_ecm_get_bit, tone_report_func_t tone_callback, void *user_data) { if (s == NULL) { if ((s = (fax_modems_state_t *) span_alloc(sizeof(*s))) == NULL) return NULL; } /*endif*/ memset(s, 0, sizeof(*s)); s->use_tep = use_tep; modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "FAX modems"); s->tone_callback = tone_callback; s->tone_callback_user_data = user_data; if (tone_callback) { modem_connect_tones_rx_init(&s->connect_rx, MODEM_CONNECT_TONES_FAX_CNG, s->tone_callback, s->tone_callback_user_data); } /*endif*/ dc_restore_init(&s->dc_restore); s->get_bit = non_ecm_get_bit; s->get_bit_user_data = user_data; s->put_bit = non_ecm_put_bit; s->put_bit_user_data = user_data; s->hdlc_accept = hdlc_accept; s->hdlc_accept_user_data = user_data; hdlc_rx_init(&s->hdlc_rx, false, false, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, s); hdlc_tx_init(&s->hdlc_tx, false, 2, false, hdlc_tx_underflow, user_data); fax_modems_start_slow_modem(s, FAX_MODEM_V21_RX); fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); silence_gen_init(&s->silence_gen, 0); s->rx_signal_present = false; s->rx_handler = (span_rx_handler_t) &span_dummy_rx; s->rx_fillin_handler = (span_rx_fillin_handler_t) &span_dummy_rx; s->rx_user_data = NULL; s->rx_fillin_user_data = NULL; s->tx_handler = (span_tx_handler_t) &silence_gen; s->tx_user_data = &s->silence_gen; return s; }
int main (int argc, char *argv[]) { awgn_state_t noise_source; dc_restore_state_t dc_state; int i; int idum = 1234567; int16_t dirty; int16_t clean; int estimate; int min; int max; int dc_offset; dc_offset = 5000; awgn_init_dbm0(&noise_source, idum, -10.0); dc_restore_init(&dc_state); for (i = 0; i < 100000; i++) { dirty = awgn(&noise_source) + dc_offset; clean = dc_restore(&dc_state, dirty); if ((i % 1000) == 0) { printf("Sample %6d: %d (expect %d)\n", i, dc_restore_estimate(&dc_state), dc_offset); } } /* We should have settled by now. Look at the variation we get */ min = 99999; max = -99999; for (i = 0; i < 100000; i++) { dirty = awgn(&noise_source) + dc_offset; clean = dc_restore(&dc_state, dirty); estimate = dc_restore_estimate(&dc_state); if (estimate < min) min = estimate; if (estimate > max) max = estimate; } printf("Spread of DC estimate for an offset of %d was %d to %d\n", dc_offset, min, max); if (min < dc_offset - 50 || max > dc_offset + 50) { printf("Test failed.\n"); exit(2); } printf("Test passed.\n"); return 0; }
SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s, int use_tep, hdlc_frame_handler_t hdlc_accept, hdlc_underflow_handler_t hdlc_tx_underflow, put_bit_func_t non_ecm_put_bit, get_bit_func_t non_ecm_get_bit, tone_report_func_t tone_callback, void *user_data) { if (s == NULL) { if ((s = (fax_modems_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); s->use_tep = use_tep; hdlc_rx_init(&s->hdlc_rx, FALSE, FALSE, HDLC_FRAMING_OK_THRESHOLD, hdlc_accept, user_data); hdlc_tx_init(&s->hdlc_tx, FALSE, 2, FALSE, hdlc_tx_underflow, user_data); fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); fsk_tx_init(&s->v21_tx, &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &s->hdlc_tx); v17_rx_init(&s->v17_rx, 14400, non_ecm_put_bit, user_data); v17_tx_init(&s->v17_tx, 14400, s->use_tep, non_ecm_get_bit, user_data); v29_rx_init(&s->v29_rx, 9600, non_ecm_put_bit, user_data); v29_rx_signal_cutoff(&s->v29_rx, -45.5f); v29_tx_init(&s->v29_tx, 9600, s->use_tep, non_ecm_get_bit, user_data); v27ter_rx_init(&s->v27ter_rx, 4800, non_ecm_put_bit, user_data); v27ter_tx_init(&s->v27ter_tx, 4800, s->use_tep, non_ecm_get_bit, user_data); silence_gen_init(&s->silence_gen, 0); modem_connect_tones_tx_init(&s->connect_tx, MODEM_CONNECT_TONES_FAX_CNG); if (tone_callback) { modem_connect_tones_rx_init(&s->connect_rx, MODEM_CONNECT_TONES_FAX_CNG, tone_callback, user_data); } dc_restore_init(&s->dc_restore); s->rx_signal_present = FALSE; s->rx_handler = (span_rx_handler_t *) &span_dummy_rx; s->rx_user_data = NULL; s->tx_handler = (span_tx_handler_t *) &silence_gen; s->tx_user_data = &s->silence_gen; return s; }
fax_state_t *fax_init(fax_state_t *s, int calling_party) { if (s == NULL) { if ((s = (fax_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "FAX"); t30_init(&(s->t30_state), calling_party, fax_set_rx_type, (void *) s, fax_set_tx_type, (void *) s, fax_send_hdlc, (void *) s); t30_set_supported_modems(&(s->t30_state), T30_SUPPORT_V27TER | T30_SUPPORT_V29); hdlc_rx_init(&(s->hdlcrx), FALSE, FALSE, 5, t30_hdlc_accept, &(s->t30_state)); fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &(s->hdlcrx)); fsk_rx_signal_cutoff(&(s->v21rx), -45.5); hdlc_tx_init(&(s->hdlctx), FALSE, 2, FALSE, hdlc_underflow_handler, &(s->t30_state)); s->first_tx_hdlc_frame = TRUE; fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &(s->hdlctx)); v17_rx_init(&(s->v17rx), 14400, t30_non_ecm_put_bit, &(s->t30_state)); v17_tx_init(&(s->v17tx), 14400, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); v29_rx_init(&(s->v29rx), 9600, t30_non_ecm_put_bit, &(s->t30_state)); v29_rx_signal_cutoff(&(s->v29rx), -45.5); v29_tx_init(&(s->v29tx), 9600, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); v27ter_rx_init(&(s->v27ter_rx), 4800, t30_non_ecm_put_bit, &(s->t30_state)); v27ter_tx_init(&(s->v27ter_tx), 4800, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); silence_gen_init(&(s->silence_gen), 0); dc_restore_init(&(s->dc_restore)); t30_restart(&(s->t30_state)); #if defined(LOG_FAX_AUDIO) { char buf[100 + 1]; struct tm *tm; time_t now; time(&now); tm = localtime(&now); sprintf(buf, "/tmp/fax-rx-audio-%x-%02d%02d%02d%02d%02d%02d", s, tm->tm_year%100, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); s->fax_audio_rx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666); sprintf(buf, "/tmp/fax-tx-audio-%x-%02d%02d%02d%02d%02d%02d", s, tm->tm_year%100, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); s->fax_audio_tx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666); } #endif return s; }