oxesoft / oxefmsynth

Oxe FM Synth official repository
https://oxesoft.wordpress.com/
GNU General Public License v3.0
178 stars 27 forks source link

Fix: Reverb wrapping distortion caused by integer overflow in calculation #16

Open djtuBIG-MaliceX opened 7 years ago

djtuBIG-MaliceX commented 7 years ago

This has been an outstanding issue for a while, but after looking at the output from a wave recording in a sound editor, the shape of a sine wave with reverb turned on and playing them at the loudest volume made it obvious.

Been trying to fix it on my own in the code but there seems to be some funny quirks with the coefficients in the calculation in synth/reverb.cpp (even after trying to simply clip to the INT_MAX/INT_MIN of possible culprits in the equations). In any case, here's a WAV recording of the symptoms in its obvious form (you can see it wrap the sine waveform in an oscilloscope): https://dl.dropboxusercontent.com/u/1287967/oxefmsynth-reverbwrappingdistiort.mp3

EDIT: on further investigation, it may well also be an issue with synthesizer.cpp unctions for SumStereoMono() and SumMonoStereo() since they sum integers without taking into account of any possible overflow wrapping?

djtuBIG-MaliceX commented 3 years ago

I decided to have a look at this again, recompiled current sources and found the culprit. It's in the DC filter.

https://github.com/oxesoft/oxefmsynth/blob/master/src/synth/reverb.cpp#L118

The operation ou0 = b[i] - in1 + ((ou0*32674)/32768); is causing an integer overflow on calculation of ou0 * 32674. Casting ou0 with either float or double resolves the issue.

In addition, may want to consider using floating point buffers instead of integers, as DAWs can better handle 'extreme-value' loudness (eg: place a limiter in front of the signal chain), rather than have the synthesizer clip internally.

djtuBIG-MaliceX commented 3 years ago

If anyone wants to test, try these builds out. OxeFMSynth-7jan2021.zip

samboy commented 3 years ago

Related: I think we can do better here than having a simple Schroeder reverb. As reverb guru Sean Costello has put it, the first thing reverb designers do is implement the Schroeder reverb. The second thing reverb designers do is realize the Schroeder reverb is no good and implement something else. A FDN is probably the easiest good sounding reverb to implement; a 4-line FDN can sound really good with careful tuning, and a 8-line or 12-line FDN can more easily sound good if we’re willing to take the CPU hit.