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
24 bit sample support #301
Conversation
I suppose the test was done using an audio card with a 24bits DAC ?.
What do you mean ?
Do you mean, lost in computation time ? |
Good point, I cant even tell right now.
Yes, that's why I was expecting none, else this would have probably meant I introduced some strange bug.
Not sure. But since most soundfonts are only 16 bit, dithering will still be useful.
See the attachment. Watching the two files in e.g. audacity you can see a slight difference for some samples, so at least it seem to have any effect.
I dont think lost is the correct word in this context, but yes I was referring to computation time which stayed the same. |
Using In the two files, the
The average difference is 0.45 cB (i.e 0.6 %), so this is an inaudible difference.
Please, how the |
If you load both files in audacity, invert one of them and mix them together you get the difference. It does look like the changes are miniscule and not audible. |
I think it would be great to add more instrumentation (like jjcs profiling patch) to objectively measure performance. And maybe keep a wiki page updated with the numbers for different platforms for each release. That way we can be sure that there are no performance regressions. |
I just noticed that the demo files I provided used the default s16 for "audio.file.format" setting, so that waveform analysis was quite meaningless I guess.
Even if we manage it to setup a fully automated test suite, I dont think gathering those performance information across multiple/different platforms is something we can bear up in the long term. Anyway, here is the demo program I used. And these are my test results, depending on the interp. method used: Test with OmegaGMGS2.sf2
fluidsynth-master (without sm24)interp = 0 : 3983.905100 ms fluidsynth-1.1.8interp = 0 : 4091.934600 ms fluidsynth-sm24 (this PR)interp = 0 : 3987.057500 ms Test with FluidR3_GM.sf2
fluidsynth-master (without sm24)interp = 0 : 4220.572200 ms fluidsynth-1.1.8interp = 0 : 4422.360800 ms fluidsynth-sm24 (this PR)interp = 0 : 4201.633800 ms I'm not quite sure why sm24 is even faster today, didnt experienced that two days ago... |
Good point . This is because i haven't yet audacity installed that i have used an other available tool . In fact, the difference are mainly for small amplitude sample: (for 16 bits the smallest level is 1/32768.0f against 1/8388608.0f for 24bits. So, the worst case difference could be -48dB).
As an example,I have used this patch to compare different reverb Another example, using a Raspberry 2, it was possible to see that when playing 50 voices the result was:
On this hardware the reverb cpu load is high 27.90% (probably due to the lack of floating point unit ?). |
To get a behaviour similar to this sm24 PR , i have implemented Theses are interesting results tests using the
The condition of the measure:
Definitions:
In those tests, because we are only interested by the impact on Test:1 Without sm24 PR behaviour.
The duration of one voice sample is 0.16% of the sample period. Test:2 With fluid_rvoice_get_sample() - fluid_voice_calculate_gain_amplitude()
The duration of one voice sample is 0.22% of the sample period. This correspond to an augmentation of 35 % compared to Test 1. Test:3 With fluid_rvoice_get_sample() and fluid_voice_calculate_gain_amplitude() now implemented
|
I dont experience any performance boost when marking those functions inline explicitly. What platform are you on? What compiler + version did you use? |
That "inline" is only a suggestion to the compiler anyway. The function might be inlined even when not marked as inline explicitly, or the compiler might ignore the suggestion. I think there's a |
Yes, and when compiled with |
The OS is Win XP. The CPU is an AMD. I have chosen the
May be inline code is not appropriate to Debug ?. |
RelWithDebInfo is a release build that enables compiler optimizations and should inline appropriately. I think the problem is your compiler. Marking functions as inline usually really helped compilers from the good old 90s and Visual C++ 6.0 was released in '98. Although I do think explicitly inlining functions is outdated, in this case it seems to be useful. |
fluid_voice_calculate_gain_amplitude() fluid_rvoice_get_sample()
in rvoice_dsp
@mawe42 Are you all right with this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, looks good!
This adds support for 24 bit sample soundfonts. It has been implemented by adding a separate pointer
data24
tofluid_sample_t
that points to the lower byte counterpart of each sample. This pointer can be set to NULL if a soundfont only has 16 bit samples. Implementing it this way ensures two important aspects:fluid_sample_t
struct, andPutting the 16 bit samples together with a potentially present 8 bit counterpart to create a 24 bit sample is done as late as possible, specifically in the interpolation routines in
rvoice_dsp
. But even if there is no 8 bit counterpart, we now always use 24 bit samples (in factint32_t
) for mixing inrvoice_dsp
(the lower part is assumed to be zero in this case, seefluid_rvoice_get_sample()
).This leads to the interesting question: Is there even any gain in precision when using 24 bit samples?
The synthesizing pipeline looks as follows:
rvoice_dsp
during interpolation and create a 32 bit integer sample from it (with a value range of[-2^23 ; 2^23 - 1]
)INT24_MAX
to force them to a normalized range of[-1.0 ; 1.0)
The only potential precision loss due to 32 bit integers I can see could occur at 3. However even with single point precision floating points we can accurately represent integer values in the range
[-2^24 ; 2^24]
when promoting them to floats. The 32 bit integer samples are guaranteed to be in that range so there should be no rounding errors that haven't been there before.I tested the synthesized output with the OmegaGMGS2 soundfont. As expected an audible difference was not hearable. However the resulting 24 bit waveform is slightly different from the one synthesized with fluidsynth 1.1.8. Also as far as I can tell there doesnt seem to be any measurable drop in performance.
Any feedback welcome.