fluid-dev
[Top][All Lists]
Advanced

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

Re: [fluid-dev] pausing the sequencer


From: Tom M.
Subject: Re: [fluid-dev] pausing the sequencer
Date: Mon, 30 Nov 2020 22:14:21 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.4.2

Pls. make sure to include the mailing list when replying.

On 30.11.20 17:54, Jeroen Neve wrote:
Thanks for the reply, Tom.

Let's say I have a music notation program, and I want to use FluidSynth to 
render an audio-file of the music as it is notated.
There are more than 16 voices in parallel, so MIDI is not an option 😉 (Which is 
the main point of using FluidSynth.)

I tell FluidSynth to send its output to the file renderer, but as soon as I 
feed the sequencer the MIDI events, the file starts rendering
What I'm worried about is that the rendering process (which for a file is much 
faster than real-time) will be faster than the events I can collect from the 
score.
If I cannot fill the sequencer fast enough with new events, then at some point 
I tell the sequencer to send an event in the past.

It gets even worse: the events may not be sent to the sequencer in order. First 
I send the events for the flutes, then the bassoon, the horns, the clarinet, 
then the violins, etc.

So my ideal solution would be:
- pause the sequencer
- send all the events to the sequencer ( is that possible?)
- set up the file renderer (delete the audio-driver first!)
- continue the sequencer
- render the file until the callback function receives "done playing"
- delete the file renderer

Another solution is to collect all the events first, order them, and then send 
them to the sequencer as fast as possible of course.
But that case is still a scenario of the hare outrunning the hounds. The hare 
may escape, or it may not.


Full disclosure:
I am not the programmer of the project, but I did direct David to FluidSynth to 
implement it as a new feature into his application. ( I do have a programming 
background though! <g>)
I will point him to this mailing list, if he hasn't subscribed already!


Thanks again,
Jeroen Neve




> Let's say I have a music notation program, and I want to use FluidSynth to render an audio-file of the music as it is notated.

Understood. Although it's not clear to me how you are planning to connect that "music notation program" to fluidsynth. But, ok.

> There are more than 16 voices in parallel, so MIDI is not an option (Which is the main point of using FluidSynth.)

I assume by "voices" you meant "channels". fluidsynth is heavily based on MIDI. Those two things do not mutually exclude each other. The number of MIDI channels can be tweaked in fluidsynth via the

synth.midi-channels

setting. So, putting aside the rest of your proposed solution (I don't quite understand it, sry), I see two possible attempts:

1) If you *must* synthesize audio "as it is notated" (i.e. in real-time, i.e. on-the-fly) you would:

- set synth.midi-channels to the desired number
- create the synth
- create a MIDI driver (http://www.fluidsynth.org/api/RealtimeMIDI.html)
--> Alsa and Jack MIDI drivers will honor synth.midi-channels, i.e. they will create a total of "synth.midi-channels / 16" MIDI ports AND they will adjust the channel number appropriately according to the port they've received the event (not sure if others do currently) - create the "file" audio driver (not to be confused with the fast file renderer!)
- click the "play" button in your notation software


2) The non-realtime scenario:

- set synth.midi-channels to the desired number
- create the synth
- create the sequencer (new_fluid_sequencer2()) and tell it to use the sample timer (rather than the system timer... perhaps this is where your confusion of "pausing" things comes from)
- collect the events from the notation software somehow (unclear to me)
- parse those notation software events into "fluid_event"s
- feed all those events with correct *absolute* timestamp into the sequencers event queue (fluid_sequencer_send_at())
- call fluid_sequencer_register_fluidsynth()
- note: at this point, no rendering has been done, i.e. the sequencer is still at tick zero! - finally to start the rendering: create the fast file renderer new_fluid_file_renderer() - pump audio via fluid_file_renderer_process_block() until the last event has been processed

Remark: How to know when the last event has been processed from the sequencers queue? By enqueuing a fluid_event_timer() that gives your application a callback to set some termination-flag or so.


> It gets even worse: the events may not be sent to the sequencer in order. First I send the events for the flutes, then the bassoon, the horns, the clarinet, then the violins, etc.

For solution 2) this doesn't matter, because event's are ordered according to the timestamp you have provided when enqueuing.


P.S.: Yes, you could (ab-)use fluidsynth's sequencer for solution 1) as well. You could even enqueue sync-events into the sequencer's queue, which give your application a callback in which you are free to do anything. Since that callback comes from the "synth context", you could even wait within that callback until the first flowers are blooming. But it would be more effort and you would also successfully bypass many of fluidsynth's primitives that already abstract that kind of work for you... unless that "David's" surname is Back, in which case, I'm afraid, this would be the way to go when having to sync up to four synth instances.


Tom



reply via email to

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