aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/mt32/Synth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/softsynth/mt32/Synth.cpp')
-rwxr-xr-xaudio/softsynth/mt32/Synth.cpp83
1 files changed, 36 insertions, 47 deletions
diff --git a/audio/softsynth/mt32/Synth.cpp b/audio/softsynth/mt32/Synth.cpp
index 162c5d8cee..00832c5d50 100755
--- a/audio/softsynth/mt32/Synth.cpp
+++ b/audio/softsynth/mt32/Synth.cpp
@@ -63,16 +63,6 @@ static inline PartialState getPartialState(PartialManager *partialManager, unsig
return partial->isActive() ? PARTIAL_PHASE_TO_STATE[partial->getTVA()->getPhase()] : PartialState_INACTIVE;
}
-#if MT32EMU_USE_FLOAT_SAMPLES
-static inline Bit16s convertSample(float sample) {
- return Synth::clipSampleEx(Bit32s(sample * 16384.0f)); // This multiplier takes into account the DAC bit shift
-}
-#else
-static inline float convertSample(Bit16s sample) {
- return float(sample) / 16384.0f; // This multiplier takes into account the DAC bit shift
-}
-#endif
-
class SampleFormatConverter {
protected:
#if MT32EMU_USE_FLOAT_SAMPLES
@@ -98,7 +88,7 @@ public:
}
Sample *inBuffer = sampleBuffer;
while (len--) {
- *(outBuffer++) = convertSample(*(inBuffer++));
+ *(outBuffer++) = Synth::convertSample(*(inBuffer++));
}
}
@@ -133,6 +123,12 @@ public:
class Renderer {
Synth &synth;
+ // These buffers are used for building the output streams as they are found at the DAC entrance.
+ // The output is mixed down to stereo interleaved further in the analog circuitry emulation.
+ Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
+ Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
+
public:
Renderer(Synth &useSynth) : synth(useSynth) {}
@@ -140,7 +136,7 @@ public:
void renderStreams(SampleFormatConverter &nonReverbLeft, SampleFormatConverter &nonReverbRight, SampleFormatConverter &reverbDryLeft, SampleFormatConverter &reverbDryRight, SampleFormatConverter &reverbWetLeft, SampleFormatConverter &reverbWetRight, Bit32u len);
void produceLA32Output(Sample *buffer, Bit32u len);
void convertSamplesToOutput(Sample *buffer, Bit32u len);
- void doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len);
+ void doRenderStreams(DACOutputStreams<Sample> &streams, Bit32u len);
};
Bit32u Synth::getLibraryVersionInt() {
@@ -527,7 +523,7 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, A
return open(controlROMImage, pcmROMImage, DEFAULT_MAX_PARTIALS, analogOutputMode);
}
-bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, unsigned int usePartialCount, AnalogOutputMode analogOutputMode) {
+bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, Bit32u usePartialCount, AnalogOutputMode analogOutputMode) {
if (opened) {
return false;
}
@@ -1698,12 +1694,8 @@ void Renderer::render(SampleFormatConverter &converter, Bit32u len) {
return;
}
- // As in AnalogOutputMode_ACCURATE mode output is upsampled, buffer size MAX_SAMPLES_PER_RUN is more than enough.
- Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN];
- Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN];
-
while (len > 0) {
+ // As in AnalogOutputMode_ACCURATE mode output is upsampled, MAX_SAMPLES_PER_RUN is more than enough for the temp buffers.
Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len;
synth.renderStreams(tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, synth.analog->getDACStreamsLength(thisPassLen));
synth.analog->process(converter.sampleBuffer, tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisPassLen);
@@ -1771,11 +1763,12 @@ void Renderer::renderStreams(
}
}
}
- doRenderStreams(
+ DACOutputStreams<Sample> streams = {
nonReverbLeft.sampleBuffer, nonReverbRight.sampleBuffer,
reverbDryLeft.sampleBuffer, reverbDryRight.sampleBuffer,
- reverbWetLeft.sampleBuffer, reverbWetRight.sampleBuffer,
- thisLen);
+ reverbWetLeft.sampleBuffer, reverbWetRight.sampleBuffer
+ };
+ doRenderStreams(streams, thisLen);
nonReverbLeft.convert(thisLen);
nonReverbRight.convert(thisLen);
reverbDryLeft.convert(thisLen);
@@ -1870,17 +1863,14 @@ void Renderer::convertSamplesToOutput(Sample *buffer, Bit32u len) {
#endif
}
-void Renderer::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sample *reverbDryLeft, Sample *reverbDryRight, Sample *reverbWetLeft, Sample *reverbWetRight, Bit32u len) {
- // Even if LA32 output isn't desired, we proceed anyway with temp buffers
- Sample tmpBufNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpBufNonReverbRight[MAX_SAMPLES_PER_RUN];
- if (nonReverbLeft == NULL) nonReverbLeft = tmpBufNonReverbLeft;
- if (nonReverbRight == NULL) nonReverbRight = tmpBufNonReverbRight;
-
- Sample tmpBufReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpBufReverbDryRight[MAX_SAMPLES_PER_RUN];
- if (reverbDryLeft == NULL) reverbDryLeft = tmpBufReverbDryLeft;
- if (reverbDryRight == NULL) reverbDryRight = tmpBufReverbDryRight;
-
+void Renderer::doRenderStreams(DACOutputStreams<Sample> &streams, Bit32u len) {
if (synth.activated) {
+ // Even if LA32 output isn't desired, we proceed anyway with temp buffers
+ Sample *nonReverbLeft = streams.nonReverbLeft == NULL ? tmpNonReverbLeft : streams.nonReverbLeft;
+ Sample *nonReverbRight = streams.nonReverbRight == NULL ? tmpNonReverbRight : streams.nonReverbRight;
+ Sample *reverbDryLeft = streams.reverbDryLeft == NULL ? tmpReverbDryLeft : streams.reverbDryLeft;
+ Sample *reverbDryRight = streams.reverbDryRight == NULL ? tmpReverbDryRight : streams.reverbDryRight;
+
Synth::muteSampleBuffer(nonReverbLeft, len);
Synth::muteSampleBuffer(nonReverbRight, len);
Synth::muteSampleBuffer(reverbDryLeft, len);
@@ -1898,33 +1888,32 @@ void Renderer::doRenderStreams(Sample *nonReverbLeft, Sample *nonReverbRight, Sa
produceLA32Output(reverbDryRight, len);
if (synth.isReverbEnabled()) {
- synth.reverbModel->process(reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, len);
- if (reverbWetLeft != NULL) convertSamplesToOutput(reverbWetLeft, len);
- if (reverbWetRight != NULL) convertSamplesToOutput(reverbWetRight, len);
+ synth.reverbModel->process(reverbDryLeft, reverbDryRight, streams.reverbWetLeft, streams.reverbWetRight, len);
+ if (streams.reverbWetLeft != NULL) convertSamplesToOutput(streams.reverbWetLeft, len);
+ if (streams.reverbWetRight != NULL) convertSamplesToOutput(streams.reverbWetRight, len);
} else {
- Synth::muteSampleBuffer(reverbWetLeft, len);
- Synth::muteSampleBuffer(reverbWetRight, len);
+ Synth::muteSampleBuffer(streams.reverbWetLeft, len);
+ Synth::muteSampleBuffer(streams.reverbWetRight, len);
}
// Don't bother with conversion if the output is going to be unused
- if (nonReverbLeft != tmpBufNonReverbLeft) {
+ if (streams.nonReverbLeft != NULL) {
produceLA32Output(nonReverbLeft, len);
convertSamplesToOutput(nonReverbLeft, len);
}
- if (nonReverbRight != tmpBufNonReverbRight) {
+ if (streams.nonReverbRight != NULL) {
produceLA32Output(nonReverbRight, len);
convertSamplesToOutput(nonReverbRight, len);
}
- if (reverbDryLeft != tmpBufReverbDryLeft) convertSamplesToOutput(reverbDryLeft, len);
- if (reverbDryRight != tmpBufReverbDryRight) convertSamplesToOutput(reverbDryRight, len);
+ if (streams.reverbDryLeft != NULL) convertSamplesToOutput(reverbDryLeft, len);
+ if (streams.reverbDryRight != NULL) convertSamplesToOutput(reverbDryRight, len);
} else {
- // Avoid muting buffers that wasn't requested
- if (nonReverbLeft != tmpBufNonReverbLeft) Synth::muteSampleBuffer(nonReverbLeft, len);
- if (nonReverbRight != tmpBufNonReverbRight) Synth::muteSampleBuffer(nonReverbRight, len);
- if (reverbDryLeft != tmpBufReverbDryLeft) Synth::muteSampleBuffer(reverbDryLeft, len);
- if (reverbDryRight != tmpBufReverbDryRight) Synth::muteSampleBuffer(reverbDryRight, len);
- Synth::muteSampleBuffer(reverbWetLeft, len);
- Synth::muteSampleBuffer(reverbWetRight, len);
+ Synth::muteSampleBuffer(streams.nonReverbLeft, len);
+ Synth::muteSampleBuffer(streams.nonReverbRight, len);
+ Synth::muteSampleBuffer(streams.reverbDryLeft, len);
+ Synth::muteSampleBuffer(streams.reverbDryRight, len);
+ Synth::muteSampleBuffer(streams.reverbWetLeft, len);
+ Synth::muteSampleBuffer(streams.reverbWetRight, len);
}
synth.partialManager->clearAlreadyOutputed();