SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem_connect_tones_tx_state_t *s, int tone_type) { int alloced; alloced = FALSE; if (s == NULL) { if ((s = (modem_connect_tones_tx_state_t *) malloc(sizeof(*s))) == NULL) return NULL; alloced = TRUE; } s->tone_type = tone_type; switch (s->tone_type) { case MODEM_CONNECT_TONES_FAX_CNG: /* 0.5s of 1100Hz+-38Hz + 3.0s of silence repeating. Timing +-15% */ s->tone_phase_rate = dds_phase_rate(1100.0); s->level = dds_scaling_dbm0(-11); s->duration_timer = ms_to_samples(500 + 3000); s->mod_phase_rate = 0; s->tone_phase = 0; s->mod_phase = 0; s->mod_level = 0; break; case MODEM_CONNECT_TONES_ANS: case MODEM_CONNECT_TONES_ANSAM: /* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. */ s->tone_phase_rate = dds_phase_rate(2100.0); s->level = dds_scaling_dbm0(-11); s->duration_timer = ms_to_samples(200 + 2600); s->mod_phase_rate = dds_phase_rate(15.0); s->tone_phase = 0; s->mod_phase = 0; s->mod_level = (s->tone_type == MODEM_CONNECT_TONES_ANSAM) ? s->level/5 : 0; break; case MODEM_CONNECT_TONES_ANS_PR: case MODEM_CONNECT_TONES_ANSAM_PR: s->tone_phase_rate = dds_phase_rate(2100.0); s->level = dds_scaling_dbm0(-12); s->duration_timer = ms_to_samples(200 + 3300); s->mod_phase_rate = dds_phase_rate(15.0); s->tone_phase = 0; s->mod_phase = 0; s->hop_timer = ms_to_samples(450); s->mod_level = (s->tone_type == MODEM_CONNECT_TONES_ANSAM_PR) ? s->level/5 : 0; break; default: if (alloced) free(s); return NULL; } return s; }
SPAN_DECLARE(tone_gen_descriptor_t *) tone_gen_descriptor_init(tone_gen_descriptor_t *s, int f1, int l1, int f2, int l2, int d1, int d2, int d3, int d4, int repeat) { if (s == NULL) { if ((s = (tone_gen_descriptor_t *) span_alloc(sizeof(*s))) == NULL) { return NULL; } } memset(s, 0, sizeof(*s)); if (f1) { #if defined(SPANDSP_USE_FIXED_POINT) s->tone[0].phase_rate = dds_phase_rate((float) f1); if (f2 < 0) s->tone[0].phase_rate = -s->tone[0].phase_rate; s->tone[0].gain = dds_scaling_dbm0((float) l1); #else s->tone[0].phase_rate = dds_phase_ratef((float) f1); if (f2 < 0) s->tone[0].phase_rate = -s->tone[0].phase_rate; s->tone[0].gain = dds_scaling_dbm0f((float) l1); #endif } if (f2) { #if defined(SPANDSP_USE_FIXED_POINT) s->tone[1].phase_rate = dds_phase_rate((float) abs(f2)); s->tone[1].gain = (f2 < 0) ? (float) 32767.0f*l2/100.0f : dds_scaling_dbm0((float) l2); #else s->tone[1].phase_rate = dds_phase_ratef((float) abs(f2)); s->tone[1].gain = (f2 < 0) ? (float) l2/100.0f : dds_scaling_dbm0f((float) l2); #endif } s->duration[0] = d1*SAMPLE_RATE/1000; s->duration[1] = d2*SAMPLE_RATE/1000; s->duration[2] = d3*SAMPLE_RATE/1000; s->duration[3] = d4*SAMPLE_RATE/1000; s->repeat = repeat; return s; }
fsk_rx_state_t *fsk_rx_init(fsk_rx_state_t *s, fsk_spec_t *spec, int sync_mode, put_bit_func_t put_bit, void *user_data) { int chop; memset(s, 0, sizeof(*s)); s->baud_rate = spec->baud_rate; s->sync_mode = sync_mode; fsk_rx_signal_cutoff(s, (float) spec->min_level); s->put_bit = put_bit; s->user_data = user_data; /* Detect by correlating against the tones we want, over a period of one baud. The correlation must be quadrature. */ /* First we need the quadrature tone generators to correlate against. */ s->phase_rate[0] = dds_phase_rate((float) spec->freq_zero); s->phase_rate[1] = dds_phase_rate((float) spec->freq_one); s->phase_acc[0] = 0; s->phase_acc[1] = 0; s->last_sample = 0; /* The correlation should be over one baud. */ s->correlation_span = SAMPLE_RATE/spec->baud_rate; /* But limit it for very slow baud rates, so we do not overflow our buffer. */ if (s->correlation_span > FSK_MAX_WINDOW_LEN) s->correlation_span = FSK_MAX_WINDOW_LEN; /* We need to scale, to avoid overflow in the correlation. */ s->scaling_shift = 0; chop = s->correlation_span; while (chop != 0) { s->scaling_shift++; chop >>= 1; } /* Initialise the baud/bit rate tracking. */ s->baud_inc = (s->baud_rate*0x10000)/SAMPLE_RATE; s->baud_pll = 0; /* Initialise a power detector, so sense when a signal is present. */ power_meter_init(&(s->power), 4); s->signal_present = 0; return s; }
SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data) { int i; if (sig_update == NULL || tone_type < 1 || tone_type > 3) return NULL; /*endif*/ if (s == NULL) { if ((s = (sig_tone_tx_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); s->sig_update = sig_update; s->user_data = user_data; s->desc = &sig_tones[tone_type - 1]; for (i = 0; i < 2; i++) { if (s->desc->tone_freq[i]) s->phase_rate[i] = dds_phase_rate((float) s->desc->tone_freq[i]); else s->phase_rate[i] = 0; s->tone_scaling[i][0] = dds_scaling_dbm0((float) s->desc->tone_amp[i][0]); s->tone_scaling[i][1] = dds_scaling_dbm0((float) s->desc->tone_amp[i][1]); } return s; }
static int detection_range_tests(super_tone_rx_state_t *super) { int16_t amp[SAMPLES_PER_CHUNK]; int i; int j; int x; uint32_t phase; int32_t phase_inc; int scale; printf("Detection range tests\n"); super_tone_rx_tone_callback(super, wakeup, (void *) "test"); phase = 0; phase_inc = dds_phase_rate(440.0f); for (level = -80; level < 0; level++) { printf("Testing at %ddBm0\n", level); scale = dds_scaling_dbm0(level); for (j = 0; j < 100; j++) { for (i = 0; i < SAMPLES_PER_CHUNK; i++) amp[i] = (dds(&phase, phase_inc)*scale) >> 15; x = super_tone_rx(super, amp, SAMPLES_PER_CHUNK); } } return 0; }
SPAN_DECLARE(swept_tone_state_t *) swept_tone_init(swept_tone_state_t *s, float start, float end, float level, int duration, int repeating) { if (s == NULL) { if ((s = (swept_tone_state_t *) malloc(sizeof(*s))) == NULL) return NULL; } memset(s, 0, sizeof(*s)); s->current_phase_inc = s->starting_phase_inc = dds_phase_rate(start); s->phase_inc_step = dds_phase_rate((end - start)/(float) duration); s->scale = dds_scaling_dbm0(level); s->duration = duration; s->repeating = repeating; s->pos = 0; s->phase = 0; return s; }
fsk_tx_state_t *fsk_tx_init(fsk_tx_state_t *s, fsk_spec_t *spec, get_bit_func_t get_bit, void *user_data) { s->baud_rate = spec->baud_rate; s->get_bit = get_bit; s->user_data = user_data; s->phase_rates[0] = dds_phase_rate((float) spec->freq_zero); s->phase_rates[1] = dds_phase_rate((float) spec->freq_one); s->scaling = dds_scaling_dbm0((float) spec->tx_level); /* Initialise fractional sample baud generation. */ s->phase_acc = 0; s->baud_inc = (s->baud_rate*0x10000)/SAMPLE_RATE; s->baud_frac = 0; s->current_phase_rate = s->phase_rates[1]; s->shutdown = FALSE; return s; }
SPAN_DECLARE(int) ademco_contactid_receiver_tx(ademco_contactid_receiver_state_t *s, int16_t amp[], int max_samples) { int i; int samples; switch (s->step) { case 0: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; vec_zeroi16(amp, samples); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "Initial silence finished\n"); s->step++; s->tone_phase_rate = dds_phase_rate(1400.0); s->tone_level = dds_scaling_dbm0(-11); s->tone_phase = 0; s->remaining_samples = ms_to_samples(100); return samples; case 1: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; for (i = 0; i < samples; i++) amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "1400Hz tone finished\n"); s->step++; s->remaining_samples = ms_to_samples(100); return samples; case 2: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; vec_zeroi16(amp, samples); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "Second silence finished\n"); s->step++; s->tone_phase_rate = dds_phase_rate(2300.0); s->tone_level = dds_scaling_dbm0(-11); s->tone_phase = 0; s->remaining_samples = ms_to_samples(100); return samples; case 3: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; for (i = 0; i < samples; i++) amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "2300Hz tone finished\n"); s->step++; s->remaining_samples = ms_to_samples(100); return samples; case 4: /* Idle here, waiting for a response */ return 0; case 5: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; vec_zeroi16(amp, samples); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "Sending kissoff\n"); s->step++; s->tone_phase_rate = dds_phase_rate(1400.0); s->tone_level = dds_scaling_dbm0(-11); s->tone_phase = 0; s->remaining_samples = ms_to_samples(850); return samples; case 6: samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; for (i = 0; i < samples; i++) amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); s->remaining_samples -= samples; if (s->remaining_samples > 0) return samples; span_log(&s->logging, SPAN_LOG_FLOW, "1400Hz tone finished\n"); s->step = 4; s->remaining_samples = ms_to_samples(100); return samples; } return max_samples; }
static int power_surge_detector_tests(void) { SNDFILE *outhandle; power_surge_detector_state_t *sig; int i; int sample; int16_t amp[8000]; int16_t amp_out[2*8000]; awgn_state_t *awgnx; int32_t phase_rate; uint32_t phase_acc; int16_t phase_scale; float signal_power; int32_t signal_level; int signal_present; int prev_signal_present; int ok; int extremes[4]; if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL) { fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME); exit(2); } sig = power_surge_detector_init(NULL, -50.0f, 5.0f); prev_signal_present = false; phase_rate = dds_phase_rate(450.0f); phase_acc = 0; phase_scale = dds_scaling_dbm0(-33.0f); awgnx = awgn_init_dbm0(NULL, 1234567, -45.0f); extremes[0] = 8001; extremes[1] = -1; extremes[2] = 8001; extremes[3] = -1; for (sample = 0; sample < 800000; sample += 8000) { ok = 0; for (i = 0; i < 8000; i++) { amp[i] = awgn(awgnx); if (i < 4000) amp[i] += dds_mod(&phase_acc, phase_rate, phase_scale, 0); signal_level = power_surge_detector(sig, amp[i]); signal_present = (signal_level != 0); if (prev_signal_present != signal_present) { signal_power = power_surge_detector_current_dbm0(sig); if (signal_present) { if (ok == 0 && i >= 0 && i < 25) ok = 1; if (extremes[0] > i) extremes[0] = i; if (extremes[1] < i) extremes[1] = i; printf("On at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power); } else { if (ok == 1 && i >= 4000 + 0 && i < 4000 + 35) ok = 2; if (extremes[2] > i) extremes[2] = i; if (extremes[3] < i) extremes[3] = i; printf("Off at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power); } prev_signal_present = signal_present; } amp_out[2*i] = amp[i]; amp_out[2*i + 1] = signal_present*5000; } sf_writef_short(outhandle, amp_out, 8000); if (ok != 2 || extremes[0] < 1 || extremes[1] > 30 || extremes[2] < 4001 || extremes[3] > 4030) { printf(" Surge not detected correctly (%d)\n", ok); exit(2); } } if (sf_close_telephony(outhandle)) { fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME); exit(2); } printf("Min on %d, max on %d, min off %d, max off %d\n", extremes[0], extremes[1], extremes[2], extremes[3]); power_surge_detector_free(sig); awgn_free(awgnx); return 0; }