earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
2.02k stars 432 forks source link

Mixing 8bit WAVs produces DC bias, clipping and clicks #648

Open positron96 opened 1 year ago

positron96 commented 1 year ago

Hello and thanks for a wonderful library.

Here is a bug report. 8bit WAVs have unsigned samples. The library seems aware of this, but shifting the sample to signed 16bit happens in AudioOutput classes by calling MakeSampleStereo16 function. However, this happens too late in the pipeline in case the file is first mixed with another file, or its gain is changed by AudioMixer class. In this case the sequence of events is the following:

  1. Sample is loaded and stored as u8 in i16 buffer in AudioGeneratorWAV, its 0 amplitude is value 128.
  2. Sample is passed to AudioMixer class where it is scaled by applying gain (0 amplitude is not 128 anymore) or added to other channels (DC bias is added to bias of other channels).
  3. Resulting sample is passed to final output class (e.g. AudioOutputI2S) where it is unbiased by MakeSampleStereo16, but it is only subtracting 128 from value, so the DC bias is modified but still remains.

I propose the change to convert the sample to signed when loading it in GeneratorWAV class, and use it as such from then on. MakeSampleStereo16 function should not do the shifting, but only scaling.

PS Not sure, but this might be the cause of some reports of people having clicks and pops in sound output.