Example #1
0
static gboolean tone_play(const gchar *filename, VFSFile *file)
{
    GArray *frequencies;
    gfloat data[BUF_SAMPLES];
    gsize i;
    gboolean error = FALSE;
    struct
    {
        gdouble wd;
        guint period, t;
    } *tone = NULL;

    frequencies = tone_filename_parse(filename);
    if (frequencies == NULL)
        return FALSE;

    if (aud_input_open_audio(FMT_FLOAT, OUTPUT_FREQ, 1) == 0)
    {
        error = TRUE;
        goto error_exit;
    }

    aud_input_set_bitrate(16 * OUTPUT_FREQ);

    tone = g_malloc(frequencies->len * sizeof(*tone));
    for (i = 0; i < frequencies->len; i++)
    {
        gdouble f = g_array_index(frequencies, gdouble, i);
        tone[i].wd = 2 * PI * f / OUTPUT_FREQ;
        tone[i].period = (G_MAXINT * 2U / OUTPUT_FREQ) * (OUTPUT_FREQ / f);
        tone[i].t = 0;
    }

    while (!aud_input_check_stop())
    {
        for (i = 0; i < BUF_SAMPLES; i++)
        {
            gsize j;
            double sum_sines;

            for (sum_sines = 0, j = 0; j < frequencies->len; j++)
            {
                sum_sines += sin(tone[j].wd * tone[j].t);
                if (tone[j].t > tone[j].period)
                    tone[j].t -= tone[j].period;
                tone[j].t++;
            }
            /* dithering can cause a little bit of clipping */
            data[i] = (sum_sines * 0.999 / (gdouble) frequencies->len);
        }

        aud_input_write_audio(data, BUF_BYTES);
    }

error_exit:
    g_array_free(frequencies, TRUE);
    g_free(tone);

    return !error;
}
Example #2
0
static gchar *tone_title(const gchar * filename)
{
    GArray *freqs;
    gchar *title;
    gsize i;

    freqs = tone_filename_parse(filename);
    if (freqs == NULL)
        return NULL;

    title = g_strdup_printf(_("%s %.1f Hz"), _("Tone Generator: "), g_array_index(freqs, double, 0));
    for (i = 1; i < freqs->len; i++)
    {
        gchar *old_title = title;
        title = g_strdup_printf("%s;%.1f Hz", old_title, g_array_index(freqs, double, i));
        g_free(old_title);
    }
    g_array_free(freqs, TRUE);

    return title;
}
Example #3
0
static gboolean tone_play(InputPlayback *playback, const gchar *filename,
    VFSFile *file, gint start_time, gint stop_time, gboolean pause)
{
    GArray *frequencies;
    gfloat data[BUF_SAMPLES];
    gsize i;
    gboolean error = FALSE;
    struct
    {
        gdouble wd;
        guint period, t;
    } *tone = NULL;

    frequencies = tone_filename_parse(filename);
    if (frequencies == NULL)
        return FALSE;

    if (playback->output->open_audio(FMT_FLOAT, OUTPUT_FREQ, 1) == 0)
    {
        error = TRUE;
        goto error_exit;
    }

    if (pause)
        playback->output->pause(TRUE);

    playback->set_params(playback, 16 * OUTPUT_FREQ, OUTPUT_FREQ, 1);

    tone = g_malloc(frequencies->len * sizeof(*tone));
    for (i = 0; i < frequencies->len; i++)
    {
        gdouble f = g_array_index(frequencies, gdouble, i);
        tone[i].wd = 2 * PI * f / OUTPUT_FREQ;
        tone[i].period = (G_MAXINT * 2U / OUTPUT_FREQ) * (OUTPUT_FREQ / f);
        tone[i].t = 0;
    }

    stop_flag = FALSE;
    playback->set_pb_ready(playback);

    while (!stop_flag)
    {
        for (i = 0; i < BUF_SAMPLES; i++)
        {
            gsize j;
            double sum_sines;

            for (sum_sines = 0, j = 0; j < frequencies->len; j++)
            {
                sum_sines += sin(tone[j].wd * tone[j].t);
                if (tone[j].t > tone[j].period)
                    tone[j].t -= tone[j].period;
                tone[j].t++;
            }
            /* dithering can cause a little bit of clipping */
            data[i] = (sum_sines * 0.999 / (gdouble) frequencies->len);
        }

        if (!stop_flag)
            playback->output->write_audio(data, BUF_BYTES);
    }

error_exit:
    g_array_free(frequencies, TRUE);
    g_free(tone);

    playback->output->close_audio();
    stop_flag = TRUE;

    return !error;
}