SOLVED! Adafruit i2s DAC reducing pops / crackle help needed

I’ve been looking at ways to get this functionality working without having to manually mess around with the ALSA config.

So far I’ve managed a PR to enable “pluggable” ALSA config - next up is a dmix plugin which uses it.

1 Like

Hi Tim,
Great progress. Well done. No more sshing in to mess with config files looks like it will be a real thing! Good luck with getting a plugin up and running.
I look forward to further updates to Volumio.

I’ve been doing quite a bit of work in this area trying to see if I can make proper use of the shutdown pin on the MAX98357A. This reduces power usage (from approx 1.5mW to 10µW as far as I can tell) which is good for battery life on a system that I want to be portable. In doing that I have found that there is a kernel module and device overlay specifically for the device which uses the SD pin and avoids popping as a result!

The kernel module is included in the latest 5.4.y kernel, but not the stable 4.19.y used by Volumio. I have, however, worked out how to get it up and running.

  1. Enable SSH on your device
  2. Log in and get the kernel sources using volumio kernelsources
  3. Install the other things you need to build the kernel sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
  4. Edit /usr/src/rpi-linux/sound/soc/codecs/Kconfig to add:
config SND_SOC_TEST
        tristate "Select MAX 98375A"
        select SND_SOC_MAX98357A

between menu "CODEC drivers" and config SND_SOC_ALL_CODECS

  1. Run the first step of https://www.raspberrypi.org/documentation/linux/kernel/building.md#build_sources (i.e. selecting the build definition for the type of pi that you’re on)
  2. Run sudo make menuconfig and select the entry for the MAX98357A (drivers -> sound card -> soc -> codecs) to be a module (press m)
  3. Build the codec modules using sudo make M=sound/soc/codecs/ scripts prepare modules_prepare modules
  4. Copy the kernel module from sound/soc/codecs/snd-soc-max98357a.ko to your local modules folder
  5. Load the module, and you should have audio!
  6. Shutdown the pi, add a wire from GPIO 4 to the SD pin and you should have pop-free audio when you next boot and load the module

Hi Tim,
This sounds like a simple (certainly adding a one wire to my microsystem) and I but I’m not sure about how to issue the “kernalsources” command correctly to get what I need.

Could you confirm this for me?

When I’ve time later this week I’ll have a look at updating the kernal and configuring my little system.

You’re doing a great job of fixing up this little DAC for everyday usage. (WAF will improve greatly if there is no crackle!)

Hi TIme,
So I’ve got some time to look at this and I noticed why I couldn’t proceed last time - typo! The initial command should be volumio kernelsource not volumio kernelsources

Now I’ve done that and installed the build tools, I am unable to proceed as the /usr/src/rpi-linux/sound/soc/codecs/Kconfig isn’t on my system. When I follow the file tree through I only get to /usr/src as there is not rpi-linux in that folder.

Any ideas where I’ve gone wrong?
Thanks

So I’ve got some time to look at this and I noticed why I couldn’t proceed last time - typo! The initial command should be volumio kernelsource not volumio kernelsources

Sorry about that, completely my fault for trying to type out instructions at speed!

Now I’ve done that and installed the build tools, I am unable to proceed as the /usr/src/rpi-linux/sound/soc/codecs/Kconfig isn’t on my system. When I follow the file tree through I only get to /usr/src as there is not rpi-linux in that folder.

Did the volumio kernelsource command complete successfully? If you’re tight on SD card space then it may not have the space to download and unzip the kernel sources…

You can see the script that does the work at /volumio/app/plugins/system_controller/volumio_command_line_client/commands/kernelsource.sh It definitely does the following:

tar --strip-components 1 -xf rpi-linux.tar.gz -C /usr/src/rpi-linux
cd /usr/src/rpi-linux

Another thing to add:

  1. Shutdown the pi, add a wire from GPIO 4 to the SD pin and you should have pop-free audio when you next boot and load the module

This is true, but you may end up with audio only for the left channel (or possibly right channel) but not the (L+R)/2 that happens normally. I corrected this by using a 47kΩ resistor between GPIO4 and the SD pin, with another 10kΩ resistor between SD and ground. edit - I think a 10kΩ and 1kΩ would work, as would a 100kΩ and 22kΩ. The important thing is to drag the voltage below 0.15V when GPIO4 is low and up to about 0.5V when GPIO4 is high.

Another option would be to create a route plugin (or modified /etc/asound.conf) which does the (L+R)/2 in software, but the hardware approach is a bit more elegant.

Also, the volumio kernel is currently 4.19.y, which doesn’t include a fix for the MAX98357A driver that you might want. Specifically: https://github.com/raspberrypi/linux/commit/fdf34366d3242d5eeffa1b4d9a3497ebf30a4ecb - it’s relatively simple to make the change by hand if you care about not resampling the audio, but the ALSA stack will cope without the patch.

Another another thing to add :slight_smile:

You will probably need to run sudo depmod after copying the module you’ve made into your local modules folder (the folder will be something like /lib/modules/4.19.118+/sound/soc/codecs). This scans the available modules and registers them so they can be loaded.

An update in case you’re interested. The latest Volumio Buster images use kernel 5.4.y and include the MAX98357A kernel module which prevents popping using the SD pin.

Obviously if you decide to do this you’ll need to plan how you’re going to control the SD pin, as Adafruit have helpfully connected it to Vin via a 1MΩ resistor. If you’re using 5V as Vin then connecting SD directly to the GPIO might fry your GPIO with 5V!

Hi Timothy,
Thanks for the update. I will be looking into doing this as I would like to get my volumio speaker working seamlessly.
I have just reread your earlier post about what resistors you used and I may need some further guidance as I’m not very knowledgable about electronics - but I can follow instructions (usually.)

I have just reread your earlier post about what resistors you used and I may need some further guidance as I’m not very knowledgable about electronics - but I can follow instructions (usually.)

Well you have a few options with varying levels of complexity. The end goal is to have the SD pin controlled by GPIO 4 (pin 7 on the GPIO header, and yes the numbering is a pain) so that the driver can mute the amp when nothing is playing.

Option 1: Removing the 1MΩ resistor and driving the pin directly

This option involves desoldering the surface mount resistor from the Adafruit board. It’s not that hard to do but may be more risk than you want to take.

The resistor is clearly visible on the board it’s the small component near the ground pin labelled 1004 (the code for 1MΩ). It also has a clear trace linking to the SD pin. There are plenty of guides to desoldering online. The main thing is to be sure that you don’t bridge the two connectors, or else you’ll be constantly forcing the SD pin to +5V.

Once the resistor is removed you can then either:

Option 1.a GPIO through a resistor

Connect the SD pin to GPIO 4 (the default control pin in the MAX98357a driver) using a resistor in the range 600-700kΩ. This will be SD “off” when the GPIO is low and “(L+R)/2” when the GPIO is high.

Option 1.b GPIO direct with software stereo to mono

Connect the SD pin directly to GPIO 4 (the default control pin in the MAX98357a driver). This will be SD “off” when the GPIO is low and “L” when the GPIO is high. To make sure that you hear your music properly you will need to configure ALSA to mix the left and right channels into the left channel. This would be best done as a plugin to Volumio (which doesn’t yet exist).

Option 1.c Stereo output

Get a second MAX98357A, desolder the 1MΩ resistor, then wire it up in parallel with the first amp. Connect one SD pin directly to GPIO 4 and the other SD pin to GPIO4 through a 220kΩ resistor. You will then have Left and Right output for two speakers

Option 2 No desoldering

If you don’t want to risk desoldering a component from the amplifier board then you can make things work using a potential divider between GPIO4, SD and GND to ensure that:

  • The GPIO pin is never pushed over 3.3V
  • The SD pin is pulled low enough to shutdown when the GPIO is low

I’ve tried this with reasonable success. My resistors were as follows:

  • A 47kΩ resistor between GPIO4 and the SD pin
  • A 10kΩ resistor between the SD pin and GND

When GPIO4 is low, this means that the connection to ground pulls the SD pin low (despite the 5V through 1MΩ as 10kΩ is 100 times smaller). When GPIO 4 is high the 47kΩ and 10kΩ divider sets the SD pin to about 0.58V, which what you want for the (L+R)/2 output.

I hope that this helps.

For reference, Option 1a is probably the best from a long-term power use and safety perspective (even if you accidentally short GPIO4 then 600kΩ will prevent excessive current) as long as you don’t accidentally bridge the contacts when desoldering the 1MΩ resistor.

I will therefore attempt the desoldering option. I’ll have to get some tools, but this is not a bad option. I can also get a couple of the MX98537A boards in case I ruin it and if not, I am sure I can make some more volumio mono speakers!

Hi Tim, thanks for the instructions on ways to fix this issue. I’ve not been 100% successful as of yet.

I successfully desoldered the 1MΩ and I’ve connected up 600KΩ worth of resistors (as 6 x 100K resistors in series - I didn’t have a 600kΩ single one) from GPIO4 to the SD pin and freshly installed volumio 3.015.

I still seem to be experiencing popping between tracks.

Any ideas about what to do next? More resistance between the GPIO4 and the SD pin?

edit: Actually it partially works - it no longer pops on stopping a track, just when starting playing.

Any ideas about what to do next?

It sounds like you’ve done everything right with the hardware, I’m just a bit unsure about where you got the 3.015 Volumio. To my knowledge the Volumio 3 beta hasn’t gone public yet, and if it had the version number would be a bit higher than that. My guess is that you have an image that someone in the community created?

The public beta should be starting very soon and I’ll let you know when it does.

It was the one from here. Thought it was semi-official. I should read the fine print more closely…

Thanks again for your help. I look forward to trying out Volumio 3.

The beta is live now. It may be a slightly less polished experience, but it will have native support for your MAX98357A!

I’m still seeing this issue, on a fresh install of Volumio 3. Unfortunately the fix you described doesn’t work, whether due to my bad Linux skills or changes in the OS I don’t know.
Using a Raspberry Pi Zero 2 W, MAX98357 DAC, I still get a crackle at every track change.
When I try to implement the changes you describe ALSA seems to stop working, the service exits with an error [aplay: main:828: audio open error].
Any ideas?

Hi BAWE,
Ultimately it came down to making some hardware mods.
I went with option 1a that Timothyjward suggested above. You have to remove/desolder the 1M ohm resistor on the board (a little fiddly but doable with a soldering iron and a bit of patience) and added the 600k ohm resistors between GPIO4 and the SD pin on the MAX98357. It worked a great for me and haven’t had an issue since.
Good luck and welcome to the forum!

Thanks! Thought it could be done with a software fix going by the above, but apparently not. I’ll give the option you suggest a whirl.