static short _fluid_seq_queue_init(fluid_sequencer_t* seq, int maxEvents) { seq->heap = _fluid_evt_heap_init(maxEvents); if (seq->heap == NULL) { fluid_log(FLUID_PANIC, "sequencer: Out of memory\n"); return -1; } seq->preQueue = NULL; seq->preQueueLast = NULL; FLUID_MEMSET(seq->queue0, 0, 2*256*sizeof(fluid_evt_entry *)); FLUID_MEMSET(seq->queue1, 0, 2*255*sizeof(fluid_evt_entry *)); seq->queueLater = NULL; seq->queue0StartTime = fluid_sequencer_get_tick(seq); seq->prevCellNb = -1; fluid_mutex_init(seq->mutex); /* start timer */ if (seq->useSystemTimer) { seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process, (void *)seq, TRUE, FALSE, TRUE); } return (0); }
/** * Activates play mode for a MIDI player if not already playing. * @param player MIDI player instance * @return #FLUID_OK on success, #FLUID_FAILED otherwise */ int fluid_player_play(fluid_player_t *player) { if (player->status == FLUID_PLAYER_PLAYING) { return FLUID_OK; } if (player->playlist == NULL) { return FLUID_OK; } player->status = FLUID_PLAYER_PLAYING; if (player->use_system_timer) { player->system_timer = new_fluid_timer((int) player->deltatime, fluid_player_callback, (void *) player, TRUE, FALSE, TRUE); if (player->system_timer == NULL) { return FLUID_FAILED; } } else { player->sample_timer = new_fluid_sample_timer(player->synth, fluid_player_callback, (void *) player); if (player->sample_timer == NULL) { return FLUID_FAILED; } } return FLUID_OK; }
/** * Set the time scale of a sequencer. * @param seq Sequencer object * @param scale Sequencer scale value in ticks per second * (default is 1000 for 1 tick per millisecond, max is 1000.0) * * If there are already scheduled events in the sequencer and the scale is changed * the events are adjusted accordingly. */ void fluid_sequencer_set_time_scale (fluid_sequencer_t* seq, double scale) { if (scale <= 0) { fluid_log(FLUID_WARN, "sequencer: scale <= 0 : %f\n", scale); return; } if (scale > 1000.0) // Otherwise : problems with the timer = 0ms... scale = 1000.0; if (seq->scale != scale) { double oldScale = seq->scale; // stop timer if (seq->timer) { delete_fluid_timer(seq->timer); seq->timer = NULL; } seq->scale = scale; // change start0 so that cellNb is preserved seq->queue0StartTime = (seq->queue0StartTime + seq->prevCellNb)*(seq->scale/oldScale) - seq->prevCellNb; // change all preQueue events for new scale { fluid_evt_entry* tmp; tmp = seq->preQueue; while (tmp) { if (tmp->entryType == FLUID_EVT_ENTRY_INSERT) tmp->evt.time = tmp->evt.time*seq->scale/oldScale; tmp = tmp->next; } } /* re-start timer */ if (seq->useSystemTimer) { seq->timer = new_fluid_timer((int)(1000/seq->scale), _fluid_seq_queue_process, (void *)seq, TRUE, FALSE, TRUE); } } }
fluid_audio_driver_t* new_fluid_file_audio_driver(fluid_settings_t* settings, fluid_synth_t* synth) { fluid_file_audio_driver_t* dev; int msec; dev = FLUID_NEW(fluid_file_audio_driver_t); if (dev == NULL) { FLUID_LOG(FLUID_ERR, "Out of memory"); return NULL; } FLUID_MEMSET(dev, 0, sizeof(fluid_file_audio_driver_t)); fluid_settings_getint(settings, "audio.period-size", &dev->period_size); fluid_settings_getnum(settings, "synth.sample-rate", &dev->sample_rate); dev->data = synth; dev->callback = (fluid_audio_func_t) fluid_synth_process; dev->samples = 0; dev->renderer = new_fluid_file_renderer(synth); if (dev->renderer == NULL) goto error_recovery; msec = (int) (0.5 + dev->period_size / dev->sample_rate * 1000.0); dev->timer = new_fluid_timer(msec, fluid_file_audio_run_s16, (void*) dev, TRUE, FALSE, TRUE); if (dev->timer == NULL) { FLUID_LOG(FLUID_PANIC, "Couldn't create the audio thread."); goto error_recovery; } return (fluid_audio_driver_t*) dev; error_recovery: delete_fluid_file_audio_driver((fluid_audio_driver_t*) dev); return NULL; }