On Sunday 17 June 2012, Raja Mukherji wrote: > I'm not using > fluid_sequencer_register_client and a callback to add new events, > instead I'm adding events using fluid_sequencer_send_at and then > directly calling fluid_synth_write_float in effectively one large loop. [...] > I have found a working solution for now, by writing my own simple > sequencer (which interleaves calls to fluid_synth_write_float with > direct calls to fluid_synth_noteon, fluid_synth_noteoff, etc).
Well, you have already solved your problem, probably reinventing the wheel, but just to be sure and for the sake of others that would doubt because of your claim, I've attached another variation to the metronome example that doesn't use a sequencer callback, scheduling notes and and rendering audio inside a loop. I can't still observe any problem. Regards, Pedro
/* FluidSynth Metronome - Sequencer API example * * This code is in the public domain. * * To compile: * gcc -o rendermetronome2 -lfluidsynth rendermetronome2.c * * To run: * rendermetronome2 soundfont [beats [tempo]] * * [Pedro Lopez-Cabanillas <p...@users.sf.net>] */ #include <stdlib.h> #include <stdio.h> #include <fluidsynth.h> fluid_synth_t *synth; fluid_sequencer_t *sequencer; short synth_destination; unsigned int time_marker; unsigned int sample_rate = 48000; /* default tempo, beats per minute */ #define TEMPO 120 unsigned int note_duration = 60000 / TEMPO; /* metronome click/bell */ unsigned int weak_note = 33; unsigned int strong_note = 34; /* number of notes in one pattern */ unsigned int pattern_size = 4; /* total sequence length in bars */ unsigned int pending_bars = 10; /* number of audio buffers for each bar */ unsigned int periods_per_bar = 20; /* schedule a note on message */ void schedule_noteon (int chan, short key, unsigned int ticks) { fluid_event_t *ev = new_fluid_event (); fluid_event_set_source (ev, -1); fluid_event_set_dest (ev, synth_destination); fluid_event_noteon (ev, chan, key, 127); fluid_sequencer_send_at (sequencer, ev, ticks, 1); delete_fluid_event (ev); } /* schedule the metronome pattern */ void schedule_pattern () { int i, note_time; note_time = time_marker; for (i = 0; i < pattern_size; ++i) { schedule_noteon (9, i ? weak_note : strong_note, note_time); note_time += note_duration; } time_marker = note_time; } void usage (char* prog_name) { printf ("Usage: %s soundfont.sf2 [beats [tempo]]\n", prog_name); printf ("\t(optional) beats: number of pattern beats, default %d\n", pattern_size); printf ("\t(optional) tempo: BPM (Beats Per Minute), default %d\n", TEMPO); } int main (int argc, char *argv[]) { int i, n; int total_bar_size, period_size; fluid_settings_t *settings; fluid_file_renderer_t* renderer; if (argc < 2) { usage (argv[0]); } else { if (argc > 2) { n = atoi (argv[2]); if (n > 0) pattern_size = n; } if (argc > 3) { n = atoi (argv[3]); if (n > 0) note_duration = 60000 / n; } /* total bar size in frames */ total_bar_size = note_duration * pattern_size * sample_rate / 1000; /* audio period size. Max is 8192 */ period_size = total_bar_size / periods_per_bar; if (period_size > 8192) { printf ("Sorry, max. period size exceeded\n"); return; } settings = new_fluid_settings (); fluid_settings_setstr(settings, "audio.file.name", "rendermetronome2.wav"); fluid_settings_setint(settings, "audio.period-size", period_size); fluid_settings_setnum(settings, "synth.gain", 2.0); fluid_settings_setnum(settings, "synth.sample-rate", sample_rate); /* create the synth and sequencer instances */ synth = new_fluid_synth (settings); sequencer = new_fluid_sequencer2 (0); /* register the synth with the sequencer */ synth_destination = fluid_sequencer_register_fluidsynth (sequencer, synth); /* load a SoundFont */ n = fluid_synth_sfload (synth, argv[1], 1); if (n != -1) { renderer = new_fluid_file_renderer (synth); if (!renderer) return; /* get the current time in ticks */ time_marker = fluid_sequencer_get_tick (sequencer); /* schedule and render patterns */ for (n = 0; n < pending_bars; ++n) { schedule_pattern (); for (i = 0; i < periods_per_bar; ++i) { if (fluid_file_renderer_process_block (renderer) != FLUID_OK) { break; } } } delete_fluid_file_renderer (renderer); } /* clean and exit */ delete_fluid_sequencer (sequencer); delete_fluid_synth (synth); delete_fluid_settings (settings); } return 0; }
_______________________________________________ fluid-dev mailing list fluid-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/fluid-dev