예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
파일: sig_tone.c 프로젝트: yallo/plcify
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;
}
예제 #6
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}