[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [fluid-dev] Patch for bad MIDI timing (with large buffer sizes)

From: David Henningsson
Subject: Re: [fluid-dev] Patch for bad MIDI timing (with large buffer sizes)
Date: Mon, 16 Mar 2009 22:40:29 +0100
User-agent: Thunderbird (X11/20090105)

Pedro Lopez-Cabanillas skrev:
>> We also have the case where the user wants to play a MIDI file, play
>> along himself, and put the result into a file. So we can only enable
>> fast rendering if we have both -i, and -n, and file output, and the
>> player does not use system clock timers. Did I forget something?
> There is also the MIDI sequencer case (fluid_seq.c) where you can find 
> another 
> timer instance. This would be used by an application scheduling (queueing) 
> timestamped MIDI events, for instance a drum machine, or a MIDI arpeggiator, 
> or something like that.

I've left the sequencer out of the picture currently. But I agree with
you and Antonio that it should use the slave/sample timer as well.

> Let's call the instance created by new_fluid_timer() a master timer, and the 
> one created by your new_fluid_synth_timer() a slave timer. Whenever there is 
> a process requesting synthesizer buffers at any rate, like the drivers for 
> output audio devices, then you can use the slave timer for MIDI file 
> rendering or other usage. The rate of the slave timer would be the same of 
> the audio process: if it is faster than real time it would be inappropriate 
> for real time usages. If the output is set to an audio device, the slave 
> timer is also real time (with the accuracy provided by the audio driver and 
> hardware).

So after having improved the midi player patch a bit, I went to try
fixing #15, but I'm a little unsure of how to implement it in the file
driver the best way.

First we have to communicate to the driver that we're going to use fast
rendering. Should we use the option infrastructure for this?

To the implementation, the way that changes things the least, would be
to just start another thread that calls write_s16 as fast as it can
(instead of doing it in wall clock pace). But that will still have
problems when it comes to determining when to stop (if one thread writes
audio, and the other one is waiting in fluid_player_join, the result is
not deterministic).

Long story short, we need an audio "pumping loop" that calls write_s16
and after each call checkes the status of the player to know when to
stop. And if we don't want to break existing cohesion this pumping loop
must reside in fluidsynth.c (no other unit is aware of both players and
audio drivers). That way we could also avoid thread creation altogether,
which IMHO is a good thing. On the other hand, that means we must pull a
"render_block" function out through the generic audio driver interface
although it only makes sense for the file driver.

Or should we bypass the generic audio driver and make fluidsynth.c
depend directly on aufile? Or perhaps even create a separate driver for
this purpose?

(Btw, fluidsynth.c's main function could use some refactoring as it is
already 400 lines long and won't be shorter if we add new options and a
pumping loop.)

>> This is actually two problems in one (both complex enough to start
>> separate threads about them...). The first, and I assume harder, problem
>> is to determine when the sounds actually stop. Here we have to take into
>> account reverb/release, what to do if the last midi event is a note-on
>> (for a pad sound that never stops), etc.
>> The second problem is that we have to wait for all audio buffers to be
>> played before we quit the application, it's not enough that the player
>> has finished. When I said that fluidsynth quitted too early, I was
>> talking about this second problem.
>> I don't plan to solve either one currently, my current goal is to fix #15.
> OK. I would open a new ticket for this bug, if you don't open it yourself.

Possibly there should be two tickets, one for each subproblem.

// David

reply via email to

[Prev in Thread] Current Thread [Next in Thread]