Beispiel #1
0
static int main_loop(synth_t *synth)
{
    const SDLKey keyboard[] = {
    //  c       c#      d       d#      e       f       f#      g       g#      a       a#      b       c       d       e
        SDLK_z, SDLK_s, SDLK_x, SDLK_d, SDLK_c, SDLK_v, SDLK_g, SDLK_b, SDLK_h, SDLK_n, SDLK_j, SDLK_m, SDLK_COMMA, SDLK_l, SDLK_PERIOD,
        SDLK_q, SDLK_2, SDLK_w, SDLK_3, SDLK_e, SDLK_r, SDLK_5, SDLK_t, SDLK_6, SDLK_y, SDLK_7, SDLK_u, SDLK_i, SDLK_9, SDLK_o, SDLK_0, SDLK_p
    };
    int notes[] = {
    //  c       c#      d       d#      e       f       f#      g       g#      a       a#      b       c       d       e
        0,      1,      2,      3,      4,      5,      6,      7,      8,      9,      10,     11,     12,     13,     14,
        12,    13,     14,     15,     16,     17,     18,     19,     20,     21,      22,     23,     24,     25,     26,     27,     28,
    };

    int num_keys = sizeof(keyboard)/sizeof(*keyboard);
    int base_octave = 4;

    bool quit = false;
    while(!quit)
    {
        const float background[] = { 0.2, 0.4, 0.7, 1.0 };
        glClearBufferfv(GL_COLOR, 0, background);

        SDL_GL_SwapBuffers();

        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_KEYDOWN &&
                event.key.keysym.sym == SDLK_ESCAPE)
                quit = true;
            else if(event.type == SDL_KEYDOWN && event.key.keysym.sym >= SDLK_F1 && event.key.keysym.sym <= SDLK_F12)
                base_octave = event.key.keysym.sym - SDLK_F1;
            else if(event.type == SDL_KEYDOWN)
            {
                for(int i = 0; i < num_keys; ++i)
                {
                    if(keyboard[i] != event.key.keysym.sym) continue;

                    SDL_LockAudio();
                    synth->instruments->carrier.freq = note_freq(base_octave * 12 + notes[i]);
                    adsr_trigger(&synth->instruments[0].adsr);
                    SDL_UnlockAudio();
                }
            }
        }
    }

    return 0;
}
Beispiel #2
0
/* a helper function to activate a voice for a patch */
inline static void
patch_trigger_patch (Patch* p, int note, float vel, Tick ticks)
{
    int i;
    PatchVoice* v;
    int index;          /* the index we ended up settling on */
    float key_track;
    bool legato;

    if (p->sample->sp == NULL)
        return;

    if (p->upper_note == p->lower_note)
        key_track = 1.0;
    else
        key_track = (float)(note - p->lower_note)
                                / (p->upper_note - p->lower_note);

    legato = patch_bool_get(&p->legato, p);

    if (p->mono && legato)
    {
        /*  half of the previous logic operating here was ignored.
         *  removing it left only logic which could be simplified
         *  to the following:
         */

        v = p->voices[0];
        index = 0;

        if (!v->active || v->released)
            v->vel = vel;
        else
        {
            /* don't trigger voice, do legato instead: */
            v->ticks =      ticks;
            v->note =       note;
            v->vel =        vel;
            v->relset =     -1;	/* cancel any pending release */
            v->relmode =    RELEASE_NONE;
            v->released =   false;
            v->to_end =     false;
            v->xfade =      false;
            v->loop =       p->play_mode & PATCH_PLAY_LOOP;
            v->key_track =  key_track;
            v->portamento = patch_bool_get(&p->porta, p);
            v->porta_secs = patch_float_get(&p->porta_secs, p);
            prepare_pitch(p, v, note);
            return;
        }
    }
    else /* mono w/o legato, or poly */
    {    
        int oldest = 0;
        Tick oldestticks = ticks;

        /* find a free voice slot and determine the oldest running voice */
        for (i = 0; i < PATCH_VOICE_COUNT; ++i)
        {
            if (p->voices[i]->ticks <= oldestticks)
            {
                oldestticks = p->voices[i]->ticks;
                oldest = i;
            }

            if (!p->voices[i]->active)
                break;
        }

        /* take the oldest running voice's slot if we couldn't find an
         * empty one */
        index = (i == PATCH_VOICE_COUNT) ? oldest : i;
    }

    v = p->voices[index];

    /* shutdown any running voices if monophonic */
    if (p->mono)
        patch_release_patch(p, -69, RELEASE_CUTOFF);

    /* fill in our voice */
    v->ticks =      ticks;
    v->relset =     -1; /* N/A at this time */
    v->relmode =    RELEASE_NONE;
    v->released =   false;
    v->to_end =     false; /* TRUE after loop */
    v->xfade =      false;
    v->loop =       p->play_mode & PATCH_PLAY_LOOP;
    v->note =       note;
    v->key_track =  key_track;
    v->legato =     legato;
    v->portamento = patch_bool_get(&p->porta, p);
    v->porta_secs = patch_float_get(&p->porta_secs, p);

    if (!(p->mono && v->legato))
        v->vel = vel;

    if (!p->mono)
        v->fll = v->fbl = v->flr = v->fbr = 0;

    for (i = 0; i < MAX_MOD_SLOTS; ++i)
    {
        v->amp_mod[i] = patch_mod_id_to_pointer(p->amp.mod_id[i], p, v);
        v->pan_mod[i] = patch_mod_id_to_pointer(p->pan.mod_id[i], p, v);
        v->ffreq_mod[i] = patch_mod_id_to_pointer(p->ffreq.mod_id[i], p, v);
        v->freso_mod[i] = patch_mod_id_to_pointer(p->freso.mod_id[i], p, v);
        v->pitch_mod[i] = patch_mod_id_to_pointer(p->pitch.mod_id[i], p, v);
    }

    if (!(p->mono && v->legato && v->active))
        playstate_init_fade_in(p, v);

    prepare_pitch(p, v, note);

    for (i = 0; i < VOICE_MAX_ENVS; i++)
    {
        if (p->env_params[i].active)
        {
            adsr_set_params(v->env[i], &p->env_params[i]);
            adsr_trigger(v->env[i], key_track, vel);
        }
    }

    for (i = 0; i < VOICE_MAX_LFOS; i++)
    {
        if (p->vlfo_params[i].active)
        {
            float const* src;

            src = patch_mod_id_to_pointer(p->vlfo_params[i].fm1_id, p, v);
            lfo_set_fm1(v->lfo[i], src);
            src = patch_mod_id_to_pointer(p->vlfo_params[i].fm2_id, p, v);
            lfo_set_fm2(v->lfo[i], src);

            src = patch_mod_id_to_pointer(p->vlfo_params[i].am1_id, p, v);
            lfo_set_am1(v->lfo[i], src);
            src = patch_mod_id_to_pointer(p->vlfo_params[i].am2_id, p, v);
            lfo_set_am2(v->lfo[i], src);
            lfo_trigger(v->lfo[i], &p->vlfo_params[i]);
        }
    }

    /* mark our territory */
    v->active = true;
}