Esempio n. 1
0
int main(int argc, char *argv[])
{
    AFfilehandle inhandle;
    AFfilehandle outhandle;
    AFfilesetup filesetup;
    plc_state_t plc;
    int inframes;
    int outframes;
    int16_t amp[1024];
    int block_no;
    int lost_blocks;
    int block_len;
    int loss_rate;
    int dropit;
    int block_real;
    int block_synthetic;
    int tone;
    int i;
    uint32_t phase_acc;
    int32_t phase_rate;

    loss_rate = 25;
    block_len = 160;
    block_real = FALSE;
    block_synthetic = FALSE;
    tone = -1;
    for (i = 1;  i < argc;  i++)
    {
        if (strcmp(argv[i], "-l") == 0)
        {
            loss_rate = atoi(argv[++i]);
            continue;
        }
        if (strcmp(argv[i], "-b") == 0)
        {
            block_len = atoi(argv[++i]);
            continue;
        }
        if (strcmp(argv[i], "-t") == 0)
        {
            tone = atoi(argv[++i]);
            continue;
        }
        if (strcmp(argv[i], "-r") == 0)
            block_real = TRUE;
        if (strcmp(argv[i], "-s") == 0)
            block_synthetic = TRUE;
    }
    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
    afInitFileFormat(filesetup, AF_FILE_WAVE);
    afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);

    phase_rate = 0;
    inhandle = NULL;
    if (tone < 0)
    {
        if ((inhandle = afOpenFile(INPUT_FILE_NAME, "r", NULL)) == AF_NULL_FILEHANDLE)
        {
            fprintf(stderr, "    Failed to open wave file '%s'\n", INPUT_FILE_NAME);
            exit(2);
        }
    }
    else
    {
        phase_rate = dds_phase_ratef((float) tone);
    }
    if ((outhandle = afOpenFile(OUTPUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "    Failed to open wave file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }
    plc_init(&plc);
    lost_blocks = 0;
    for (block_no = 0;  ;  block_no++)
    {
        if (tone < 0)
        {
            inframes = afReadFrames(inhandle,
                                    AF_DEFAULT_TRACK,
                                    amp,
                                    block_len);
            if (inframes != block_len)
                break;
        }
        else
        {
            if (block_no > 10000)
                break;
            for (i = 0;  i < block_len;  i++)
                amp[i] = (int16_t) dds_modf(&phase_acc, phase_rate, 10000.0, 0);
            inframes = block_len;
        }
        dropit = rand()/(RAND_MAX/100);
        if (dropit > loss_rate)
        {
            plc_rx(&plc, amp, inframes);
            if (block_real)
                memset(amp, 0, sizeof(int16_t)*inframes);
        }
        else
        {
            lost_blocks++;
            plc_fillin(&plc, amp, inframes);
            if (block_synthetic)
                memset(amp, 0, sizeof(int16_t)*inframes);
        }
        outframes = afWriteFrames(outhandle,
                                  AF_DEFAULT_TRACK,
                                  amp,
                                  inframes);
        if (outframes != inframes)
        {
            fprintf(stderr, "    Error writing out sound\n");
            exit(2);
        }
    }
    printf("Dropped %d of %d blocks\n", lost_blocks, block_no);
    if (tone < 0)
    {
        if (afCloseFile(inhandle) != 0)
        {
            fprintf(stderr, "    Cannot close wave file '%s'\n", INPUT_FILE_NAME);
            exit(2);
        }
    }
    if (afCloseFile(outhandle) != 0)
    {
        fprintf(stderr, "    Cannot close wave file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }
    afFreeFileSetup(filesetup);
    return 0;
}
Esempio n. 2
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;
            }
        }
    }
Esempio n. 3
0
int tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples)
{
    int samples;
    int limit;
    float xamp;
    float yamp;

    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
        {
            for (  ;  samples < limit;  samples++)
            {
                xamp = 0.0;
                if (s->phase_rate[0])
                    xamp = dds_modf(&(s->phase[0]), s->phase_rate[0], s->gain[0], 0);
                if (s->phase_rate[1])
                {
                    yamp = dds_modf(&(s->phase[1]), s->phase_rate[1], s->gain[1], 0);
                    if (s->modulate)
                        xamp *= (1.0f + yamp);
                    else
                        xamp += yamp;
                }
                /* 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. */
                amp[samples] = (int16_t) rintf(xamp);
            }
        }
        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;
            }
        }
    }
    return samples;
}
Esempio n. 4
0
int super_tone_tx(super_tone_tx_state_t *s, int16_t amp[], int max_samples)
{
    int samples;
    int limit;
    int len;
    float xamp;
    super_tone_tx_step_t *tree;

    if (s->level < 0  ||  s->level > 3)
        return  0;
    samples = 0;
    tree = s->levels[s->level];
    while (tree  &&  samples < max_samples)
    {
        if (tree->tone)
        {
            /* A period of tone. A length of zero means infinite
               length. */
            if (s->current_position == 0)
            {
                /* New step - prepare the tone generator */
                s->phase_rate[0] = tree->phase_rate[0];
                s->gain[0] = tree->gain[0];
                s->phase_rate[1] = tree->phase_rate[1];
                s->gain[1] = tree->gain[1];
            }
            len = tree->length - s->current_position;
            if (tree->length == 0)
            {
                len = max_samples - samples;
                /* We just need to make current position non-zero */
                s->current_position = 1;
            }
            else if (len > max_samples - samples)
            {
                len = max_samples - samples;
                s->current_position += len;
            }
            else
            {
                s->current_position = 0;
            }
            for (limit = len + samples;  samples < limit;  samples++)
            {
                xamp = 0.0;
                if (s->phase_rate[0])
                    xamp += dds_modf(&(s->phase[0]), s->phase_rate[0], s->gain[0], 0);
                if (s->phase_rate[1])
                    xamp += dds_modf(&(s->phase[1]), s->phase_rate[1], s->gain[1], 0);
                amp[samples] = (int16_t) rintf(xamp);
            }
            if (s->current_position)
                return samples;
        }
        else if (tree->length)
        {
            /* A period of silence. The length must always
               be explicitly stated. A length of zero does
               not give infinite silence. */
            len = tree->length - s->current_position;
            if (len > max_samples - samples)
            {
                len = max_samples - samples;
                s->current_position += len;
            }
            else
            {
                s->current_position = 0;
            }
            memset(amp + samples, 0, sizeof(uint16_t)*len);
            samples += len;
            if (s->current_position)
                return samples;
        }
        /* Nesting has priority... */
        if (tree->nest)
        {
            tree = tree->nest;
            s->levels[++s->level] = tree;
            s->cycles[s->level] = tree->cycles;
        }
        else
        {
            /* ...Next comes repeating, and finally moving forward a step. */
            /* When repeating, note that zero cycles really means endless cycles. */
            while (tree->cycles  &&  --s->cycles[s->level] <= 0)
            {
                tree = tree->next;
                if (tree)
                {
                    /* A fresh new step. */
                    s->levels[s->level] = tree;
                    s->cycles[s->level] = tree->cycles;
                    break;
                }
                /* If we are nested we need to pop, otherwise this is the end. */
                if (s->level <= 0)
                {
                    /* Mark the tone as completed */
                    s->levels[0] = NULL;
                    break;
                }
                tree = s->levels[--s->level];
            }
        }

    }
    return  samples;
}
Esempio n. 5
0
int tone_gen(tone_gen_state_t *s, int16_t amp[], int max_samples)
{
    int samples;
    int limit;
    float xamp;
    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)
            {
                for (  ;  samples < limit;  samples++)
                {
                    /* There must be two, and only two tones */
                    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) lrintf(xamp);
                }
            }
            else
            {
                for (  ;  samples < limit;  samples++)
                {
                    xamp = 0.0f;
                    for (i = 0;  i < 4;  i++)
                    {
                        if (s->tone[i].phase_rate == 0)
                            break;
                        xamp += dds_modf(&s->phase[i], s->tone[i].phase_rate, s->tone[i].gain, 0);
                    }
                    /* 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. */
                    amp[samples] = (int16_t) lrintf(xamp);
                }
            }
        }
        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;
            }
        }
    }
    return samples;
}