On 2011-05-06 19:03, Pedro Lopez-Cabanillas wrote:
Sorry for coming so late to the discussion.
On Friday 06 May 2011, Jonathan Slenders wrote:
One thing, I moved player->user_callback(...)
before fluid_synth_handle_midi_event. Because I sometimes also wanted to
adjust the pan, the volume, and instruments on the channel played for a
I can also image that someone (maybe me too) wants to alter the midi
supress notes or change pitch an octave up at a certain point.
Me too :-)
Seriously. This is something that I was planning for using in one of
my pet projects: http://www.kde.org/applications/multimedia/kmid .
This program is a MIDI/karaoke player with features like pitch
transpose, tempo control, channel solo/mute, synchronized lyrics
display and integrated pianola. It plays to hardware MIDI ports or
soft synths. The program has three MIDI backends right now:
Linux/ALSA, Windows and MacOSX/CoreMIDI. My plan was to develop a
fourth backend based on FluidSynth only. It would require exactly the
same feature you are trying: a callback just before delivering the
MIDI event to the synth, allowing the client application to change
event's parameters. But for my program this is only one of the
required additions to FluidSynth. Another one would be a callback
while FS is parsing the MIDI file, reporting to the client application
all the meta-events like titles, track names, copyright notices, texts
and lyrics, time/key signatures, that are ignored right
w in FluidSynth but would be required by kmid. Talking about text and
lyrics, these events would be reported by the player callback at
playing time as well, although they would be ignored by the synthesizer.
Considering the two proposed callbacks, instead of new_fluid_player2()
perhaps I would prefer two functions:
fluid_player_register_parser_callback() with their corresponding
The parser callback would be quite innocuous in process time
constraints, and will be called in the same thread as
fluid_player_add(), so there is little concern about it. The playback
callback is another issue: first, it will be potentially called from a
realtime thread, with small time constraints. If the callback allows
event modifications it should be called synchronously, ahead of the
delivering time to the synth, and the client application would need to
return within this time frame. It would be easier to implement a pure
notification callback, called asynchronously from FluidSynth but
without allowing event modifications.
Talking about events. The structure fluid_midi_event_t has been opaque
for a long time in FluidSynth, and I think it should remain opaque.
There are API functions to access some event properties, and more API
functions would be welcome if needed.
Hi folks and thanks for the patches and comments,
I mostly agree with Pedro (e g about letting the fluid_midi_event_t
remain hidden), but I'd like the callback function to be used instead of
(rather than before or after) calling fluid_synth_handle_midi_event.
That means that we'll start off with the player's callback function
pointer being fluid_synth_handle_midi_event (for simplicity and
backwards compatibility) but we can change it through a new api function
called fluid_player_set_playback_callback(). That way you should be able
to not only insert your own processing (eavesdropping, changing and
removing notes as necessary), but also to insert our existing midi
router into the playback chain for midi files.
Does that make sense or am I missing something?