Example #1
0
/*
 * hexter_instance_handle_polyphony
 */
char *
hexter_instance_handle_polyphony(hexter_instance_t *instance, const char *value)
{
    int polyphony = atoi(value);
    int i;
    dx7_voice_t *voice;

    if (polyphony < 1 || polyphony > HEXTER_MAX_POLYPHONY) {
        return dssp_error_message("error: polyphony value out of range");
    }
    /* set the new limit */
    instance->polyphony = polyphony;

    if (!instance->monophonic) {

        dssp_voicelist_mutex_lock(instance);

        instance->max_voices = polyphony;

        /* turn off any voices above the new limit */
        for (i = polyphony; i < HEXTER_MAX_POLYPHONY; i++) {
            voice = instance->voice[i];
            if (_PLAYING(voice)) {
                if (instance->held_keys[0] != -1)
                    hexter_instance_clear_held_keys(instance);
                dx7_voice_off(voice);
            }
        }

        dssp_voicelist_mutex_unlock(instance);
    }

    return NULL; /* success */
}
Example #2
0
/*
 * hexter_instance_handle_monophonic
 */
char *
hexter_instance_handle_monophonic(hexter_instance_t *instance, const char *value)
{
    int mode = -1;

    if (!strcmp(value, "on")) mode = DSSP_MONO_MODE_ON;
    else if (!strcmp(value, "once")) mode = DSSP_MONO_MODE_ONCE;
    else if (!strcmp(value, "both")) mode = DSSP_MONO_MODE_BOTH;
    else if (!strcmp(value, "off"))  mode = DSSP_MONO_MODE_OFF;

    if (mode == -1) {
        return dssp_error_message("error: monophonic value not recognized");
    }

    if (mode == DSSP_MONO_MODE_OFF) {  /* polyphonic mode */

        instance->monophonic = 0;
        instance->max_voices = instance->polyphony;

    } else {  /* one of the monophonic modes */

        if (!instance->monophonic) {

            dssp_voicelist_mutex_lock(instance);

            hexter_instance_all_voices_off(instance);
            instance->max_voices = 1;
            instance->mono_voice = NULL;
            hexter_instance_clear_held_keys(instance);
            dssp_voicelist_mutex_unlock(instance);
        }
        instance->monophonic = mode;
    }

    return NULL; /* success */
}
Example #3
0
/*
 * hexter_run_multiple_synths
 *
 * implements DSSI (*run_multiple_synths)()
 */
static void
hexter_run_multiple_synths(unsigned long instance_count, LADSPA_Handle *handles,
                           unsigned long sample_count, snd_seq_event_t **events,
                           unsigned long *event_count)
{
    hexter_instance_t **instances = (hexter_instance_t **)handles;

    unsigned long samples_done = 0;
    unsigned long event_index[instance_count];
    unsigned long this_pending_event_tick;
    unsigned long next_pending_event_tick;
    unsigned long burst_size;
    int i;

    /* attempt the mutex, return only silence if lock fails. */
    if (dssp_voicelist_mutex_trylock()) {
        for (i = 0; i < instance_count; i++) {
            memset(instances[i]->output, 0, sizeof(LADSPA_Data) * sample_count);
        }
        return;
    }

    for (i = 0; i < instance_count; i++) {
        event_index[i] = 0;

        /* silence the buffer */
        memset(instances[i]->output, 0, sizeof(LADSPA_Data) * sample_count);
#if defined(DSSP_DEBUG) && (DSSP_DEBUG & DB_AUDIO)
*instances[i]->output += 0.10f; /* add a 'buzz' to output so there's something audible even when quiescent */
#endif /* defined(DSSP_DEBUG) && (DSSP_DEBUG & DB_AUDIO) */

        if (instances[i]->pending_program_change > -1)
            hexter_handle_pending_program_change(instances[i]);
    }

    next_pending_event_tick = 0;

    while (samples_done < sample_count) {

        if (!hexter_synth.nugget_remains)
            hexter_synth.nugget_remains = HEXTER_NUGGET_SIZE;

        /* process any ready events */
        while (next_pending_event_tick <= samples_done) {
            this_pending_event_tick = next_pending_event_tick;
            next_pending_event_tick = sample_count;
            for (i = 0; i < instance_count; i++) {
                while (event_index[i] < event_count[i]
                       && events[i][event_index[i]].time.tick == this_pending_event_tick) {
                     hexter_handle_event(instances[i], &events[i][event_index[i]]);
                     event_index[i]++;
                }
                if (event_index[i] < event_count[i]
                    && events[i][event_index[i]].time.tick < next_pending_event_tick) {
                    next_pending_event_tick = events[i][event_index[i]].time.tick;
                }
            }
        }

        /* calculate the sample count (burst_size) for the next
         * hexter_synth_render_voices() call to be the smallest of:
         * - control calculation quantization size (HEXTER_NUGGET_SIZE,
         *     in samples)
         * - the number of samples remaining in an already-begun nugget
         *     (hexter_synth.nugget_remains)
         * - the number of samples left in this run
         * - the number of samples until the next event is ready
         */
        burst_size = HEXTER_NUGGET_SIZE;
        if (hexter_synth.nugget_remains < burst_size) {
            /* we're still in the middle of a nugget, so reduce the burst size
             * to end when the nugget ends */
            burst_size = hexter_synth.nugget_remains;
        }
        if (sample_count - samples_done < burst_size) {
            /* reduce burst size to end at end of this run */
            burst_size = sample_count - samples_done;
        } else if (next_pending_event_tick - samples_done < burst_size) {
            /* reduce burst size to end when next event is ready */
            burst_size = next_pending_event_tick - samples_done;
        }

        /* render the burst */
        hexter_synth_render_voices(samples_done, burst_size,
                                   (burst_size == hexter_synth.nugget_remains));
        samples_done += burst_size;
        hexter_synth.nugget_remains -= burst_size;
    }

    dssp_voicelist_mutex_unlock();
}