recording to wav/aiff causes very distorted audio if it saturates

Bug #1637786 reported by JosepMa
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mixxx
Fix Released
Undecided
JosepMa

Bug Description

Mixxx 2.0 and above.

Recording the mix to wav or aiff generates audio files that distort in the places where audio saturates (goes above full scale).

The root of the cause is that the conversion from float to integer does not clip the values and they overflow.

JosepMa (josepma)
Changed in mixxx:
assignee: nobody → JosepMa (josepma)
status: New → In Progress
Revision history for this message
Daniel Schürmann (daschuer) wrote :
Revision history for this message
JosepMa (josepma) wrote :

Thanks. I knew the but was already reported, but didn't find the correct words to find them.

The bug itself is fixed ( libsndfile normalization is ok, but it needs the clip option too ).

Manual clamping was the first natural idea, but one that I could not implement, because the buffer that is received in process is constant, so the compiler prevents it to be modified. Dynamically creating a buffer just for clamping seemed like a bad idea too.

And I will definitely try to implement the different bitsize saving. Should be trivial.

JosepMa (josepma)
Changed in mixxx:
status: In Progress → Fix Committed
Revision history for this message
Daniel Schürmann (daschuer) wrote :

Fix Committed = Pull Request is merged.

Changed in mixxx:
status: Fix Committed → In Progress
Revision history for this message
Daniel Schürmann (daschuer) wrote :

The libsndfile normalization is IMHO heavily broken by design.

It is up to the user to level the gain of the recoded samples before he starts recording.
All normalization during the recording does not reflect the original samples passed to the sound card, which is probably intended. This means, clipping at the sound-card should IMHO be recorded to the file as it is. The libsndfile normalization would apply an instant gain to the signal, which introduces a click sound and leads to a recording where the first half is louder than the second half.

You may apply the clipping in
EngineSideChain::run() or
EngineSideChain::writeSamples()
to get around the const issue

This would prevent to record samples above 1 in a float recording
So finally a second buffer seams to be required.

Revision history for this message
JosepMa (josepma) wrote :

I believe we are not on the same page.

As I understand libsndfile option of normalize, it simply means that it translates the full scale. It does not try to guess which is the peak value.

That is, if normalization is not selected, in order to get a 16 bit PCM audio with -32768 to 32767 range, the floating point data provided should be -32768.0 to 32767.0, whereas if normalization is used, that same PCM range is obtained from a floating point data between -1.0 to 1.0.

And that's it, no more.

So, what if the floating point data is -1.3 to 1.2 due to excessive gain? Then you need to tell it to clip at full scale. And that's what I've just changed in the code.

Revision history for this message
Daniel Schürmann (daschuer) wrote :

Oh yes, you are right, I have misread the docs. You proposed solution is correct.

Reading it again, I noticed the dither topic.

Could you check if dithering is enabled on write?
This is required to remove the quantization noise from the recorded fixed point samples.

I have found noting in the API docs about it. Only the test code:
https://github.com/erikd/libsndfile/blob/2fcf531ac940829cf350f86786fcff5160a32143/tests/dither_test.c#L157

Revision history for this message
JosepMa (josepma) wrote :

Mmmm... Indeed, it's not documented.

But the code exists since many years ago: https://github.com/erikd/libsndfile/blob/master/src/dither.c

I've written there an issue so that they are aware of this.

Going to try the code and see.

Revision history for this message
JosepMa (josepma) wrote :
Changed in mixxx:
status: In Progress → Fix Committed
Changed in mixxx:
milestone: none → 2.1.0
Changed in mixxx:
status: Fix Committed → Fix Released
Revision history for this message
Swiftb0y (swiftb0y) wrote :

Mixxx now uses GitHub for bug tracking. This bug has been migrated to:
https://github.com/mixxxdj/mixxx/issues/8674

lock status: Metadata changes locked and limited to project staff
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.