For discussion: es550[56] devices generate 20bit samples, not 16-bit ones. #14329
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is intended as much for discussion as for potentially merging into MAME.
The Ensoniq ES5506 (OTTO) sound synthesis chip generates 20-bit samples.
See "ENSONIQ OTTO Specification Rev. 2.3" page 14, section "6 THE CHANNEL REGISTERS - page 40hex":
See also Figure 16.6 on page 48, "SERIAL INTERFACE TIMING", which shows that the data shifted out on the serial audio data lines are the most significant 16 or 18 of the 20 bits in the channel register
The es5506_device code in es5506.cpp correctly generates 20-bit samples, but they are currently added to the audio stream as if they were 16-bit samples:
stream.put_int(c, sampindex, cursample[c], 32768);
This results in samples in a range of ±16 rather than ±1.
While the Ensoniq ES5505 (OTIS) chip does generate 16-bit samples, the es5505_device uses the same code as es5506_device, and thus also generates 20-bit samples, again added to the audio stream as if they were 16-bit ones.
The esq_5505_5510_pump_device in esqpump.cpp has always compensated for this by shifting the incoming 20-bit samples from the es5505_device right by
SAMPLE_SHIFT
= 4 bits, ever since this was added back when samples were still integers.I have verified, by logging the incoming samples to the esq_5505_5501_pump_device while playing music on an sd132 (in esq5505.cpp), that the samples it receives from the es5505_device are generally in the ±16 range, so this is not just theoretical.
None of this prevents anything from working, but it does mean that the es550[56]_device generated samples are outside of the documented tech specs:
Anyone who reads the documentation and then tries to use an es550[56] device would likely be surprised by the sample range they would actually encounter. To me, it seems better if the es550[56]_device classes follow the principle of least astonishment and add their samples to their output streams in the documented ±1 range.
Another issue is that the current code even generates samples outside the ±16 range - samples which both ES550[56] chips would have clamped, see the ES5505 (OTIS) datasheet" page 7, under "Serial Mode Register (SERMODE) -8",
and the "ENSONIQ OTTO Specification Rev. 2.3" on page 14, section "6 THE CHANNEL REGISTERS - page 40hex"
While the tech specs say that
the clamping here does happen in the real hardware, so should be simulated.
That actually also fixes some real observed audio glitches when playing back a demo sequence (
$SD-PALETTE
from the SD-1 Sequencer OS 4.10 disk).Without this PR, so without clamping: without_clamping.wav
With this PR, so including clamping: with_clamping.wav
This PR proposes to address both of these by updating es5506.cpp to add generated samples to the output stream by
which not only brings the generated samples from 20-bit integers into the ±1 float range, but also clamps them.
Once the samples are generated in the correct ±1 range, the
SAMPLE_SHIFT
inesqpump.cpp
can be removed, which this PR also does.This PR also updates all routes that I was able to find in the codebase of audio from an es550[56]_device to anything that is not an esq_5505_5510_pump_device (that one is also being updated to handle the change in sample range), multiplying the route gain by 16 to compensate for the fact that the generated samples are now a factor of 16 smaller.
This should leave all audio sounding as before.
I have verified that the VFX family of keyboards (vfx, vfxsd, sd1 and sd132) do in fact sound the same after as before, which makes sense, as they use the esq_5505_5510_pump_device and the reduction in the incoming sample range from ±16 is exactly compensated for by removing the 4-bit SAMPLE_SHIFT.
However, as I am not familiar with any of the other devices, they should probably be tested by someone who is, to verify that they still behave as expected. I may also have missed something, so more and more knowledgeable pairs of eyes would be a great help.
So I hope that this PR can be a starting point for discussion and finding the correct solution, which may of course be something completely different than this - or simply accepting the status quo, since it does after all work.