Esempio n. 1
0
int32_t Debug_vstate_render_voice(
        Voice_state* vstate,
        Proc_state* proc_state,
        const Device_thread_state* proc_ts,
        const Au_state* au_state,
        const Work_buffers* wbs,
        int32_t frame_count,
        double tempo)
{
    rassert(vstate != NULL);
    rassert(proc_state != NULL);
    rassert(proc_ts != NULL);
    rassert(au_state != NULL);
    rassert(wbs != NULL);
    rassert(frame_count > 0);
    rassert(tempo > 0);

    const Processor* proc = (const Processor*)proc_state->parent.device;

    // Get pitches
    const Cond_work_buffer* actual_pitches = Cond_work_buffer_init(
            COND_WORK_BUFFER_AUTO,
            Device_thread_state_get_voice_buffer(
                proc_ts, DEVICE_PORT_TYPE_RECV, 0, NULL),
            0);

    // Get output buffers for writing
    float* out_buffer = NULL;
    {
        Work_buffer* out_wb = Device_thread_state_get_voice_buffer(
                proc_ts, DEVICE_PORT_TYPE_SEND, 0, NULL);
        if (out_wb != NULL)
        {
            rassert(Work_buffer_get_sub_count(out_wb) == 2);
            rassert(Work_buffer_get_stride(out_wb) == 2);

            out_buffer = Work_buffer_get_contents_mut(out_wb, 0);
            Work_buffer_mark_valid(out_wb, 0);
            Work_buffer_mark_valid(out_wb, 1);
        }
    }

    Proc_debug* debug = (Proc_debug*)proc->parent.dimpl;
    if (debug->single_pulse)
    {
        if (vstate->pos == 1)
        {
            vstate->active = false;
            return 0;
        }

        const float val = 1.0;
        if (out_buffer != NULL)
        {
            out_buffer[0] = val;
            out_buffer[1] = val;
        }

        // We want all single pulses to be included in test buffers,
        // even if another voice replaces us in the channel foreground
        Voice_state_set_keep_alive_stop(vstate, 1);

        vstate->pos = 1;

        return 1;
    }

    if ((vstate->pos >= 10) || (!vstate->note_on && vstate->noff_pos_rem >= 2))
    {
        vstate->active = false;
        return 0;
    }

    const int32_t audio_rate = proc_state->parent.audio_rate;

    for (int32_t i = 0; i < frame_count; ++i)
    {
        const double freq = cents_to_Hz(
                Cond_work_buffer_get_value(actual_pitches, i));

        double vals[KQT_BUFFERS_MAX] = { 0 };

        if (vstate->rel_pos == 0)
        {
            vals[0] = vals[1] = 1.0;
            vstate->rel_pos = 1;
        }
        else
        {
            vals[0] = vals[1] = 0.5;
        }

        if (!vstate->note_on)
        {
            vals[0] = -vals[0];
            vals[1] = -vals[1];
        }

        if (out_buffer != NULL)
        {
            out_buffer[i * 2] = (float)vals[0];
            out_buffer[i * 2 + 1] = (float)vals[1];
        }

        vstate->rel_pos_rem += freq / audio_rate;

        if (!vstate->note_on)
        {
            vstate->noff_pos_rem += freq / audio_rate;
            if (vstate->noff_pos_rem >= 2)
            {
                Voice_state_set_keep_alive_stop(vstate, i + 1);
                return i + 1;
            }
        }

        if (vstate->rel_pos_rem >= 1)
        {
            ++vstate->pos;
            if (vstate->pos >= 10)
            {
                Voice_state_set_keep_alive_stop(vstate, i + 1);
                return i + 1;
            }
            vstate->rel_pos = 0;
            vstate->rel_pos_rem -= floor(vstate->rel_pos_rem);
        }
    }

    Voice_state_set_keep_alive_stop(vstate, frame_count);

    return frame_count;
}
Esempio n. 2
0
static int32_t Debug_vstate_render_voice(
        Voice_state* vstate,
        Proc_state* proc_state,
        const Device_thread_state* proc_ts,
        const Au_state* au_state,
        const Work_buffers* wbs,
        int32_t buf_start,
        int32_t buf_stop,
        double tempo)
{
    rassert(vstate != NULL);
    rassert(proc_state != NULL);
    rassert(proc_ts != NULL);
    rassert(au_state != NULL);
    rassert(wbs != NULL);
    rassert(tempo > 0);

    const Processor* proc = (const Processor*)proc_state->parent.device;

    // Get pitches
    const Cond_work_buffer* actual_pitches = Cond_work_buffer_init(
            COND_WORK_BUFFER_AUTO,
            Device_thread_state_get_voice_buffer(proc_ts, DEVICE_PORT_TYPE_RECV, 0),
            0);

    // Get output buffers for writing
    float* out_buffers[2] = { NULL };
    Proc_state_get_voice_audio_out_buffers(proc_ts, 0, 2, out_buffers);

    Proc_debug* debug = (Proc_debug*)proc->parent.dimpl;
    if (debug->single_pulse)
    {
        if (buf_start < buf_stop)
        {
            const float val = 1.0;
            if (out_buffers[0] != NULL)
                out_buffers[0][buf_start] = val;
            if (out_buffers[1] != NULL)
                out_buffers[1][buf_start] = val;
            Voice_state_set_finished(vstate);

            // We want all single pulses to be included in test buffers,
            // even if another voice replaces us in the channel foreground
            Voice_state_mark_release_data(vstate, buf_start + 1);

            return buf_start + 1;
        }
        return buf_start;
    }

    const int32_t audio_rate = proc_state->parent.audio_rate;

    for (int32_t i = buf_start; i < buf_stop; ++i)
    {
        const double freq = cents_to_Hz(
                Cond_work_buffer_get_value(actual_pitches, i));

        double vals[KQT_BUFFERS_MAX] = { 0 };

        if (vstate->rel_pos == 0)
        {
            vals[0] = vals[1] = 1.0;
            vstate->rel_pos = 1;
        }
        else
        {
            vals[0] = vals[1] = 0.5;
        }

        if (!vstate->note_on)
        {
            vals[0] = -vals[0];
            vals[1] = -vals[1];

            Voice_state_mark_release_data(vstate, i + 1);
        }

        if (out_buffers[0] != NULL)
            out_buffers[0][i] = (float)vals[0];
        if (out_buffers[1] != NULL)
            out_buffers[1][i] = (float)vals[1];

        vstate->rel_pos_rem += freq / audio_rate;

        if (!vstate->note_on)
        {
            vstate->noff_pos_rem += freq / audio_rate;
            if (vstate->noff_pos_rem >= 2)
            {
                Voice_state_set_finished(vstate);
                return i + 1;
            }
        }

        if (vstate->rel_pos_rem >= 1)
        {
            ++vstate->pos;
            if (vstate->pos >= 10)
            {
                Voice_state_set_finished(vstate);
                return i + 1;
            }
            vstate->rel_pos = 0;
            vstate->rel_pos_rem -= floor(vstate->rel_pos_rem);
        }
    }

    return buf_stop;
}