Пример #1
0
int fsk_tx(fsk_tx_state_t *s, int16_t *amp, int len)
{
    int sample;
    int bit;

    if (s->shutdown)
        return 0;
    /* Make the transitions between 0 and 1 phase coherent, but instantaneous
       jumps. There is currently no interpolation for bauds that end mid-sample.
       Mainstream users will not care. Some specialist users might have a problem
       with them, if they care about accurate transition timing. */
    for (sample = 0;  sample < len;  sample++)
    {
        if ((s->baud_frac += s->baud_inc) >= 0x10000)
        {
            s->baud_frac -= 0x10000;
            if ((bit = s->get_bit(s->user_data)) == PUTBIT_END_OF_DATA)
            {
                s->shutdown = TRUE;
                break;
            }
            s->current_phase_rate = s->phase_rates[bit & 1];
        }
        amp[sample] = dds_mod(&(s->phase_acc), s->current_phase_rate, s->scaling, 0);
    }
    return sample;
}
Пример #2
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;
}
Пример #3
0
SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
{
    int i;
    int j;
    int k;
    int n;
    int16_t tone;
    int need_update;
    int high_low;

    for (i = 0;  i < len;  i += n)
    {
        if (s->current_tx_timeout)
        {
            if (s->current_tx_timeout <= len - i)
            {
                n = s->current_tx_timeout;
                need_update = TRUE;
            }
            else
            {
                n = len - i;
                need_update = FALSE;
            }
            s->current_tx_timeout -= n;
        }
        else
        {
            n = len - i;
            need_update = FALSE;
        }
        if (!(s->current_tx_tone & SIG_TONE_TX_PASSTHROUGH))
            vec_zeroi16(&amp[i], n);
        /*endif*/
        if ((s->current_tx_tone & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT)))
        {
            /* Are we in the early phase (high tone energy level), or the sustaining
               phase (low tone energy level) of tone generation? */
            /* This doesn't try to get the high/low timing precise, as there is no
               value in doing so. It works block by block, and the blocks are normally
               quite short. */
            if (s->high_low_timer > 0)
            {
                if (n > s->high_low_timer)
                    n = s->high_low_timer;
                s->high_low_timer -= n;
                high_low = 0;
            }
            else
            {
                high_low = 1;
            }
            /*endif*/
            for (k = 0;  k < s->desc->tones;  k++)
            {
                if ((s->current_tx_tone & tone_present_bits[k])  &&  s->phase_rate[k])
                {
                    for (j = i;  j < i + n;  j++)
                    {
                        tone = dds_mod(&s->phase_acc[k], s->phase_rate[k], s->tone_scaling[k][high_low], 0);
                        amp[j] = saturated_add16(amp[j], tone);
                    }
                    /*endfor*/
                }
                /*endif*/
            }
        }
        /*endif*/
        if (need_update  &&  s->sig_update)
            s->sig_update(s->user_data, SIG_TONE_TX_UPDATE_REQUEST, 0, 0);
        /*endif*/
    }
    /*endfor*/
    return len;
}
Пример #4
0
SPAN_DECLARE_NONSTD(int) tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples)
{
    int samples;
    int limit;
#if defined(SPANDSP_USE_FIXED_POINT)
    int16_t xamp;
#else
    float xamp;
#endif
    int i;

    if (s->current_section < 0)
        return  0;

    for (samples = 0;  samples < max_samples;  )
    {
        limit = samples + s->duration[s->current_section] - s->current_position;
        if (limit > max_samples)
            limit = max_samples;
        
        s->current_position += (limit - samples);
        if (s->current_section & 1)
        {
            /* A silent section */
            for (  ;  samples < limit;  samples++)
                amp[samples] = 0;
        }
        else
        {
            if (s->tone[0].phase_rate < 0)
            {
                /* Modulated tone */
                for (  ;  samples < limit;  samples++)
                {
                    /* There must be two, and only two, tones */
#if defined(SPANDSP_USE_FIXED_POINT)
                    xamp = ((int32_t) dds_mod(&s->phase[0], -s->tone[0].phase_rate, s->tone[0].gain, 0)
                            *(32767 + (int32_t) dds_mod(&s->phase[1], s->tone[1].phase_rate, s->tone[1].gain, 0))) >> 15;
                    amp[samples] = xamp;
#else
                    xamp = dds_modf(&s->phase[0], -s->tone[0].phase_rate, s->tone[0].gain, 0)
                         *(1.0f + dds_modf(&s->phase[1], s->tone[1].phase_rate, s->tone[1].gain, 0));
                    amp[samples] = (int16_t) lfastrintf(xamp);
#endif
                }
            }
            else
            {
                for (  ;  samples < limit;  samples++)
                {
#if defined(SPANDSP_USE_FIXED_POINT)
                    xamp = 0;
#else
                    xamp = 0.0f;
#endif
                    for (i = 0;  i < 4;  i++)
                    {
                        if (s->tone[i].phase_rate == 0)
                            break;
#if defined(SPANDSP_USE_FIXED_POINT)
                        xamp += dds_mod(&s->phase[i], s->tone[i].phase_rate, s->tone[i].gain, 0);
#else
                        xamp += dds_modf(&s->phase[i], s->tone[i].phase_rate, s->tone[i].gain, 0);
#endif
                    }
                    /* Saturation of the answer is the right thing at this point.
                       However, we are normally generating well controlled tones,
                       that cannot clip. So, the overhead of doing saturation is
                       a waste of valuable time. */
#if defined(SPANDSP_USE_FIXED_POINT)
                    amp[samples] = xamp;
#else
                    amp[samples] = (int16_t) lfastrintf(xamp);
#endif
                }
            }
        }
        if (s->current_position >= s->duration[s->current_section])
        {
            s->current_position = 0;
            if (++s->current_section > 3  ||  s->duration[s->current_section] == 0)
            {
                if (!s->repeat)
                {
                    /* Force a quick exit */
                    s->current_section = -1;
                    break;
                }
                s->current_section = 0;
            }
        }
    }
Пример #5
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;
}
Пример #6
0
SPAN_DECLARE(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *s,
                                         int16_t amp[],
                                         int len)
{
    int16_t mod;
    int i;
    int xlen;

    i = 0;
    switch (s->tone_type)
    {
    case MODEM_CONNECT_TONES_FAX_CNG:
        for (  ;  i < len;  i++)
        {
            if (s->duration_timer > ms_to_samples(3000))
            {
                if ((xlen = i + s->duration_timer - ms_to_samples(3000)) > len)
                    xlen = len;
                s->duration_timer -= (xlen - i);
                for (  ;  i < xlen;  i++)
                    amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
            }
            if (s->duration_timer > 0)
            {
                if ((xlen = i + s->duration_timer) > len)
                    xlen = len;
                s->duration_timer -= (xlen - i);
                memset(amp + i, 0, sizeof(int16_t)*(xlen - i));
                i = xlen;
            }
            if (s->duration_timer == 0)
                s->duration_timer = ms_to_samples(500 + 3000);
        }
        break;
    case MODEM_CONNECT_TONES_ANS:
        if (s->duration_timer < len)
            len = s->duration_timer;
        if (s->duration_timer > ms_to_samples(2600))
        {
            /* There is some initial silence to be generated. */
            if ((i = s->duration_timer - ms_to_samples(2600)) > len)
                i = len;
            memset(amp, 0, sizeof(int16_t)*i);
        }
        for (  ;  i < len;  i++)
            amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
        s->duration_timer -= len;
        break;
    case MODEM_CONNECT_TONES_ANS_PR:
        if (s->duration_timer < len)
            len = s->duration_timer;
        if (s->duration_timer > ms_to_samples(3300))
        {
            if ((i = s->duration_timer - ms_to_samples(3300)) > len)
                i = len;
            memset(amp, 0, sizeof(int16_t)*i);
        }
        for (  ;  i < len;  i++)
        {
            if (--s->hop_timer <= 0)
            {
                s->hop_timer = ms_to_samples(450);
                s->tone_phase += 0x80000000;
            }
            amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
        }
        s->duration_timer -= len;
        break;
    case MODEM_CONNECT_TONES_ANSAM:
        if (s->duration_timer < len)
            len = s->duration_timer;
        if (s->duration_timer > ms_to_samples(3300))
        {
            if ((i = s->duration_timer - ms_to_samples(3300)) > len)
                i = len;
            memset(amp, 0, sizeof(int16_t)*i);
        }
        for (  ;  i < len;  i++)
        {
            mod = (int16_t) (s->level + dds_mod(&s->mod_phase, s->mod_phase_rate, s->mod_level, 0));
            amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, mod, 0);
        }
        s->duration_timer -= len;
        break;
    case MODEM_CONNECT_TONES_ANSAM_PR:
        if (s->duration_timer < len)
            len = s->duration_timer;
        if (s->duration_timer > ms_to_samples(3300))
        {
            if ((i = s->duration_timer - ms_to_samples(3300)) > len)
                i = len;
            memset(amp, 0, sizeof(int16_t)*i);
        }
        for (  ;  i < len;  i++)
        {
            if (--s->hop_timer <= 0)
            {
                s->hop_timer = ms_to_samples(450);
                s->tone_phase += 0x80000000;
            }
            mod = (int16_t) (s->level + dds_mod(&s->mod_phase, s->mod_phase_rate, s->mod_level, 0));
            amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, mod, 0);
        }
        s->duration_timer -= len;
        break;
    }
    return len;
}