[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [fluid-dev] Non-Real-Time Rendering
From: |
Josh Green |
Subject: |
Re: [fluid-dev] Non-Real-Time Rendering |
Date: |
Fri, 27 Apr 2007 12:48:07 +0200 |
Hallo Zachary,
The capability is definitely there to do this with FluidSynth as a
shared library, but the command line interface lacks a real interface to
it. Currently there is raw audio output for rendering to a file, but I
believe it still writes the output in real time (actually now that I
think about it, I could be totally wrong! If someone is using the
FluidSynth command line to render MIDI audio in faster-than-realtime do
let me know ;)
Anyways, my assumption was, that the FluidSynth command line is
currently lacking in this regard, it would be a matter of adding support
to the command line interface.
Best regards,
Josh Green
On Thu, 2007-04-26 at 17:51 -0400, Zachary Northrup wrote:
> I just noticed that on the "Future of Fluidsynth" page, it lists
> non-real-time rendering as feature. Um, I am currently using
> Fluidsynth for this very task in my program, Z-Maestro (you can find
> it on the FluidSynth applications page). Has this never been done
> before, or am I misreading it? I can render a complete 30 second
> project in roughly 2-5 seconds give or take depending on sample rate,
> complexity of the song, and a few other things.
>
> Since I'm doing it all in managed VB.NET, the code sample will
> probably be almost useless, but I'll explain what I do as well. First,
> I take the music project and process it, compiling a list of all MIDI
> events for every channel. I sort the list of MIDI events by position
> to put them in chronological order. Then, I have a function that loops
> from the beginning of the project to a point measured in audio
> samples. Since the smallest increment of an event position is a 16th
> note, I loop from the first 16th note to the last one inside the audio
> sample range. For each 16th note, I send any events that exist at that
> position and then I call fluid_synth_write_s16 (which is called
> FillBuffer in my program) sending in the length, in audio samples, of
> a 16th note for the length of the buffer. Finally, I simply append the
> result to my main buffer.
>
> The final code in my program looks like this:
>
> Protected Function RenderMIDI(ByVal length As Integer) As
> Short()
> Dim instBuff As New ArrayList
> Dim hasSampled As Boolean = False
> Dim lastSamplePos As Integer
> For i As Integer = _currentSamplePos To (_currentSamplePos
> + length - 1)
> If (i / _samplesPerMeasure) Mod (1 / 16) = 0 Then
> If hasSampled Then
>
> instBuff.AddRange(inst.Synthesizer.FillBuffer((1 / 16) *
> _samplesPerMeasure))
> SendEventsAtPos(i / _samplesPerMeasure)
> Else
>
> instBuff.AddRange(inst.Synthesizer.FillBuffer(i - _currentSamplePos))
> SendEventsAtPos(i / _samplesPerMeasure)
> End If
> hasSampled = True
> lastSamplePos = i
> End If
> Next
>
> instBuff.AddRange(inst.Synthesizer.FillBuffer(_currentSamplePos +
> length - lastSamplePos))
> Dim instBuffArr(instBuff.Count - 1) As Short
> instBuff.CopyTo(instBuffArr)
> Return instBuffArr
> End Function
>
> "inst.Synthesizer" is a managed wrapper class for a FluidSynth
> synthesizer. "_currentSamplePos" is the starting sample to use.
> "_samplesPerMeasure" is a precalculated value containing literally the
> number of audio samples per measure based on the temp, sample rate,
> etc. The "AddRange" function simply appends an array to the
> "ArrayList". The "SendEventsAtPos" method simply sends any MIDI events
> existing at the specified position to the synthesizer.
>
> Once again, if this is new, please tell me (and feel free to ask about
> the algorithm). By the way, I'm using version 1.0.0 of FluidSynth due
> to some upgrading issues, if that makes any difference.
> _______________________________________________
> fluid-dev mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/fluid-dev