wavio icon indicating copy to clipboard operation
wavio copied to clipboard

_scale_to_sampwidth() produces DC offset when writing wav

Open rviviano opened this issue 3 years ago • 4 comments

First off, thank you so much for writing this module! It saved me a lot of headache trying to work with 24-bit int wavs.

However, the scaling solution can translate the audio an appreciable amount when the waveform to be written has a zero mean but is asymmetric; that is, the magnitude of vmin and vmax are dissimilar. This is fairly common with complex real-world audio.

This dc offset can produce pops during the beginning and end of sample playback and can show up on spectrum analyzers as a peak << 1hz. Overall, I don't think this function should perform any translation.

I think a better option for 16bit+ would be to normalize the audio with something like:

normalization_ratio = outmax/np.max(np.abs(data)) 
data = normalization_ratio * data

Scaled 8bit audio should maintain a zero-crossing value of 127 or at least try to maintain the mean signal amplitude of the original data.

rviviano avatar Jul 23 '20 00:07 rviviano

+1 on this

nj-vs-vh avatar Nov 04 '20 19:11 nj-vs-vh

We encounter the same issue in our project. As this issue is old, are there any plans to fix this or is this library not supported anymore?

Exitare avatar Sep 20 '21 00:09 Exitare

Hey, I have just created PR for the issue, you can check it out and see if it resolves your problems!

nj-vs-vh avatar Sep 21 '21 11:09 nj-vs-vh

Hey, thanks for the PR!

Exitare avatar Sep 21 '21 15:09 Exitare

A very belated "thanks!" for the feedback. I have rewritten--and simplified--the scaling behavior.

I don't think this function should perform any translation.

You're not the only one who has requested this, so wavio.write() no longer does any translation of the input. In the updated code, wavio.write() will always map the floating point value 0.0 to the midpoint of the integer output (i.e. 0 when the output is 16, 24 or 32 bit).

I haven't made a release yet, but I should get to that within a week.

Important! This is a backwards incompatible change! If you are still using wavio, once I have released 0.0.5, be sure to either update your code to use the new scaling behavior, or pin the dependency to version 0.0.4.

WarrenWeckesser avatar Oct 23 '22 00:10 WarrenWeckesser

I have pushed a new version to PyPI, with the simplified API for writing. The latest release is 0.0.6 (the only difference between 0.0.5 and 0.0.6 is an update to README.rst). As noted in my previous comment, if anyone needs to use the old API for backwards compatibility, they should pin their dependency on wavio to version 0.0.4.

WarrenWeckesser avatar Nov 13 '22 21:11 WarrenWeckesser