Ejemplo n.º 1
0
/*
 * hexter_instance_damp_voices
 *
 * advance all sustained voices to the release phase (note that this does not
 * clear the sustain controller.)
 */
void
hexter_instance_damp_voices(hexter_instance_t* instance)
{
    int i;
    dx7_voice_t* voice;

    for (i = 0; i < instance->max_voices; i++) {
        voice = instance->voice[i];
        if (_SUSTAINED(voice)) {
            /* this assumes the caller has cleared the sustain controller */
            dx7_voice_release_note(instance, voice);
        }
    }
}
Ejemplo n.º 2
0
/*
 * hexter_instance_all_notes_off
 *
 * put all notes into the released state
 */
void
hexter_instance_all_notes_off(hexter_instance_t* instance)
{
    int i;
    dx7_voice_t *voice;

    /* reset the sustain controller */
    instance->cc[MIDI_CTL_SUSTAIN] = 0;
    for (i = 0; i < instance->max_voices; i++) {
        voice = instance->voice[i];
        if (_ON(voice) || _SUSTAINED(voice)) {
            dx7_voice_release_note(instance, voice);
        }
    }
}
Ejemplo n.º 3
0
/*
 * nekobee_synth_all_notes_off
 *
 * put all notes into the released state
 */
void
nekobee_synth_all_notes_off(nekobee_synth_t* synth)
{
    int i;
    nekobee_voice_t *voice;

    /* reset the sustain controller */
    synth->cc[MIDI_CTL_SUSTAIN] = 0;
    for (i = 0; i < synth->voices; i++) {
        //voice = synth->voice[i];
		voice = synth->voice;
        if (_ON(voice) || _SUSTAINED(voice)) {
            nekobee_voice_release_note(synth, voice);
        }
    }
}
Ejemplo n.º 4
0
/*
 * hexter_synth_alloc_voice
 */
static dx7_voice_t *
hexter_synth_alloc_voice(hexter_instance_t* instance, unsigned char key)
{
    int i;
    dx7_voice_t* voice;

    /* If there is another voice on the same key, advance it
     * to the release phase. Note that a DX7 doesn't do this,
     * but we do it here to keep our CPU usage low. */
    for (i = 0; i < instance->max_voices; i++) {
        voice = instance->voice[i];
        if (voice->key == key && (_ON(voice) || _SUSTAINED(voice))) {
            dx7_voice_release_note(instance, voice);
        }
    }

    voice = NULL;

    if (instance->current_voices < instance->max_voices) {
        /* check if there's an available voice */
        for (i = 0; i < instance->max_voices; i++) {
            if (_AVAILABLE(instance->voice[i])) {
                voice = instance->voice[i];
                break;
            }
        }

        /* if not, then stop a running voice. */
        if (voice == NULL) {
            voice = hexter_synth_free_voice_by_kill(instance);
        }
    } else {  /* at instance polyphony limit */
        voice = hexter_synth_free_voice_by_kill(instance);
    }

    if (voice == NULL) {
        DEBUG_MESSAGE(DB_NOTE, " hexter_synth_alloc_voice: failed to allocate a voice (key=%d)\n", key);
        return NULL;
    }

    DEBUG_MESSAGE(DB_NOTE, " hexter_synth_alloc_voice: key %d voice %p\n", key, voice);
    return voice;
}
Ejemplo n.º 5
0
/*
 * hexter_synth_free_voice_by_kill
 *
 * selects a voice for killing. the selection algorithm is a refinement
 * of the algorithm previously in fluid_synth_alloc_voice.
 */
static dx7_voice_t*
hexter_synth_free_voice_by_kill(hexter_instance_t *instance)
{
    int i;
    int best_prio = 10001;
    int this_voice_prio;
    dx7_voice_t *voice;
    int best_voice_index = -1;

    for (i = 0; i < instance->max_voices; i++) {
        voice = instance->voice[i];

        /* safeguard against an available voice. */
        if (_AVAILABLE(voice))
            return voice;

        /* Determine, how 'important' a voice is.
         * Start with an arbitrary number */
        this_voice_prio = 10000;

        if (_RELEASED(voice)) {
            /* This voice is in the release phase. Consider it much less
             * important than a voice which is still held. */
            this_voice_prio -= 2000;
        } else if (_SUSTAINED(voice)) {
            /* The sustain pedal is held down, and this voice is still "on"
             * because of this even though it has received a note off.
             * Consider it less important than voices which have not yet
             * received a note off. This decision is somewhat subjective, but
             * usually the sustain pedal is used to play 'more-voices-than-
             * fingers', and if so, it won't hurt as much to kill one of those
             * voices. */
             this_voice_prio -= 1000;
        };

        /* We are not enthusiastic about releasing voices, which have just been
         * started.  Otherwise hitting a chord may result in killing notes
         * belonging to that very same chord.  So subtract the age of the voice
         * from the priority - an older voice is just a little bit less
         * important than a younger voice. */
        this_voice_prio -= (instance->note_id - voice->note_id);

        /* -FIX- not yet implemented:
         * /= take a rough estimate of loudness into account. Louder voices are more important. =/
         * if (voice->volenv_section != FLUID_VOICE_ENVATTACK){
         *     this_voice_prio += voice->volenv_val*1000.;
         * };
         */

        /* check if this voice has less priority than the previous candidate. */
        if (this_voice_prio < best_prio)
            best_voice_index = i,
            best_prio = this_voice_prio;
    }

    if (best_voice_index < 0)
        return NULL;

    voice = instance->voice[best_voice_index];
    DEBUG_MESSAGE(DB_NOTE, " hexter_synth_free_voice_by_kill: no available voices, killing voice %d note id %d\n", best_voice_index, voice->note_id);
    dx7_voice_off(voice);
    return voice;
}