SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ademco_contactid_sender_state_t *s, tone_report_func_t callback, void *user_data) { if (s == NULL) { if ((s = (ademco_contactid_sender_state_t *) span_alloc(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, "Ademco"); if (!tone_rx_init) { make_goertzel_descriptor(&tone_1400_desc, 1400.0f, GOERTZEL_SAMPLES_PER_BLOCK); make_goertzel_descriptor(&tone_2300_desc, 2300.0f, GOERTZEL_SAMPLES_PER_BLOCK); tone_rx_init = true; } goertzel_init(&s->tone_1400, &tone_1400_desc); goertzel_init(&s->tone_2300, &tone_2300_desc); s->current_sample = 0; s->callback = callback; s->callback_user_data = user_data; s->step = 0; s->remaining_samples = ms_to_samples(100); dtmf_tx_init(&s->dtmf, NULL, NULL); /* The specified timing is 50-60ms on, 50-60ms off */ dtmf_tx_set_timing(&s->dtmf, 55, 55); return s; }
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(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; }
int main(int argc, char *argv[]) { dtmf_tx_state_t *gen; int16_t amp[16384]; int len; SNDFILE *outhandle; int add_digits; if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL) { fprintf(stderr, " Cannot open audio file '%s'\n", OUTPUT_FILE_NAME); exit(2); } gen = dtmf_tx_init(NULL, NULL, NULL); len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "123", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "456", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "789", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "*#", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); add_digits = 1; do { len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) sf_writef_short(outhandle, amp, len); if (add_digits) { if (dtmf_tx_put(gen, "1234567890", -1)) { printf("Digit buffer full\n"); add_digits = 0; } } } while (len > 0); dtmf_tx_init(gen, NULL, NULL); len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "123", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 16384); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "456", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "789", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "0*#", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); if (dtmf_tx_put(gen, "ABCD", -1)) { printf("Ooops\n"); exit(2); } len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); sf_writef_short(outhandle, amp, len); /* Try modifying the level and length of the digits */ printf("Try different levels and timing\n"); dtmf_tx_set_level(gen, -20, 5); dtmf_tx_set_timing(gen, 100, 200); if (dtmf_tx_put(gen, "123", -1)) { printf("Ooops\n"); exit(2); } do { len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) sf_writef_short(outhandle, amp, len); } while (len > 0); printf("Restore normal levels and timing\n"); dtmf_tx_set_level(gen, -10, 0); dtmf_tx_set_timing(gen, 50, 55); if (dtmf_tx_put(gen, "A", -1)) { printf("Ooops\n"); exit(2); } add_digits = TRUE; do { len = dtmf_tx(gen, amp, 160); printf("Generated %d samples\n", len); if (len > 0) sf_writef_short(outhandle, amp, len); if (add_digits) { if (dtmf_tx_put(gen, "1234567890", -1)) { printf("Digit buffer full\n"); add_digits = FALSE; } } } while (len > 0); if (sf_close_telephony(outhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME); exit(2); } return 0; }