aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/softsynth/mt32/LA32FloatWaveGenerator.cpp')
-rw-r--r--audio/softsynth/mt32/LA32FloatWaveGenerator.cpp28
1 files changed, 21 insertions, 7 deletions
diff --git a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
index 486942b75c..0c9687b4d8 100644
--- a/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
+++ b/audio/softsynth/mt32/LA32FloatWaveGenerator.cpp
@@ -315,15 +315,29 @@ void LA32PartialPair::generateNextSample(const PairType useMaster, const Bit32u
}
}
+static inline float produceDistortedSample(float sample) {
+ if (sample < -1.0f) {
+ return sample + 2.0f;
+ } else if (1.0f < sample) {
+ return sample - 2.0f;
+ }
+ return sample;
+}
+
float LA32PartialPair::nextOutSample() {
- float outputSample;
- if (ringModulated) {
- float ringModulatedSample = masterOutputSample * slaveOutputSample;
- outputSample = mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample;
- } else {
- outputSample = masterOutputSample + slaveOutputSample;
+ if (!ringModulated) {
+ return masterOutputSample + slaveOutputSample;
}
- return outputSample;
+ /*
+ * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
+ * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191.
+ * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case.
+ * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space,
+ * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication.
+ * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
+ */
+ float ringModulatedSample = produceDistortedSample(masterOutputSample) * produceDistortedSample(slaveOutputSample);
+ return mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample;
}
void LA32PartialPair::deactivate(const PairType useMaster) {