Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizing fluid_synth_write functions #571

Closed
carlo-bramini opened this issue Oct 19, 2019 · 5 comments
Closed

Optimizing fluid_synth_write functions #571

carlo-bramini opened this issue Oct 19, 2019 · 5 comments

Comments

@carlo-bramini
Copy link
Contributor

carlo-bramini commented Oct 19, 2019

The rendering functions, like fluid_synth_write_float() for example, are implemented with a for () cycle with inside some calculations. Inside this cycle, there is a block for ever sample:

if(cur >= synth->curmax)
{
    int blocksleft = (len - i + FLUID_BUFSIZE - 1) / FLUID_BUFSIZE;
    synth->curmax = FLUID_BUFSIZE * fluid_synth_render_blocks(synth, blocksleft);
    fluid_rvoice_mixer_get_bufs(synth->eventhandler->mixer, &left_in, &right_in);
    cur = 0;
}

In my opinion, this piece of code could be rewritten in a more efficient way.
I made two do...while cycles and I moved this block outside the loop with the samples, which was more speed critical. On my plaftorms, the improvements were very interesting.
It is true that we could use FLUID_UNLIKELY macro inside the 'if' statements, but in my opinion if we do not execute useless instructions, it would be better.
However, it does not seem to be a difficult and dangerous change to me.

What do you think?

EDIT: of course, the content of that 'if' statement is executed at multiple of FLUID_BUFSIZE, the improvement comes out by eliminating the execution costs of the test at every cycle.

@derselbst
Copy link
Member

I made two do...while cycles and I moved this block outside the loop with the samples, which was more speed critical.

Moving that if out of the for loop sounds good. Since you've already done it I'd welcome a PR for that.

On my plaftorms,

For curiosity, which platforms, pls.?

@carlo-bramini
Copy link
Contributor Author

For curiosity, which platforms, pls.?

ARM Cortex M4, with single precision FPU, 120MHz, 8MB RAM.

@derselbst
Copy link
Member

ARM Cortex M4,

Oh, right, I remember. That thing doesn't have branch prediction, right? In this case, you might also be interested in #569. Btw, do you have chorus activated when using fluidsynth on that platform?

@carlo-bramini
Copy link
Contributor Author

Yes, I deactivated many things.
Chorus and reverb are off.
Sample interpolation has been disabled at compile time by changing macro FLUID_INTERP_DEFAULT (perhaps having a setting initialized at FLUID_INTERP_DEFAULT when you call new_fluid_settings() would be better, because the user could change it before the creation of a channel)
I changed fluid_rvoice_get_sample() for using only the upper 16 bit of the sample.
I disabled the dithering.
But I'm using PWM output, which is handled by the CPU, instead of using an I2S DAC, which is handled in DMA and it should be more efficient.
However, at the moment I'm able to play a MIDI file at 11025KHz quite well.

@derselbst
Copy link
Member

Chorus and reverb are off.

Ok, thanks. That's good for me to know for #548, where we want to change chorus to on-the-fly calculation, rather than using lookup tables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants