7

I am trying a Adafruit I2S 3W Stereo Speaker Bonnet for Raspberry Pi - Mini Kit, which is built around two MAX98357 (datasheet: adafruit, maxim), on a Raspberry Pi Zero W with Raspbian Stretch (upgraded yesterday).

The trouble is that I have "pops" when starting/changing tracks, even with the same audio rate. Their instructions to "fix" these add mostly redundant settings to the alsa configuration files /etc/asound.conf and ~/.asoundrc.

I currently only have asound.conf, like this:

$ cat /etc/asound.conf
pcm.speakerbonnet {
   type hw card 0
}

pcm.dmixer {
   type dmix
   ipc_key 1024
   ipc_perm 0666
   slave {
     pcm "speakerbonnet"
     period_time 0
     period_size 1024
     buffer_size 8192
     rate 44100
     channels 2
   }
}

ctl.dmixer {
    type hw card 0
}

pcm.softvol {
    type softvol
    slave.pcm "dmixer"
    control.name "PCM"
    control.card 0
}

ctl.softvol {
    type hw card 0
}

pcm.!default {
    type             plug
    slave.pcm       "softvol"
#    slave.pcm        "dmixer"

}

softvol exists to be able to control volume globally (in software, wasting resolution), since the DAC does not have hardware control. But apparently some players also can do this themselves, so either should suffice.

Regarding the driver, their instructions add dtoverlay=hifiberry-dac to /boot/config.txt, but the Hifiberry DAC (obsolete) is based on a (single) different chip, the PCM5102.

pi@raspberry:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Hifiberry list the configuration for their products at https://www.hifiberry.com/build/documentation/configuring-linux-3-18-x/.

I'd like to know what the differences are and if the suggestion is a proper match for the IC. Could the driver send additional data that causes a "pop" or "crackle"?

Interestingly, speaker-test never appears to produce the initial noise on playback

$ speaker-test -c2 --test=wav -w /usr/share/sounds/alsa/Front_Center.wav

, while mpg123 does (with a 16kHz mono MP3), also between tracks:

High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3
        version 1.23.8; written and copyright by Michael Hipp and others
        free software (LGPL) without any warranty but with best wishes
Decoder: generic
Trying output module: alsa, device: <nil>
Using default module dir: /usr/lib/arm-linux-gnueabihf/mpg123
Module dir: /usr/lib/arm-linux-gnueabihf/mpg123
Module path: ./output_alsa.so
Chosen output module: alsa
...
Audio driver: alsa
Audio device: (null)
Audio capabilities:
(matrix of [S]tereo or [M]ono support for sample format and rate in Hz)
       |   s16 |   u16 |   s32 |   u32 |   s24 |   u24 |   f32 |    s8 |    u8 |  ulaw |  alaw |
 ------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
  8000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 11025 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 12000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 16000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 22050 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 24000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 32000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 44100 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |
 48000 |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |  M/S  |

(specifying alsa works, specifying device index fails)

It's not in the file, I checked. And also, mplayer starts playing the identical file OK, but has "pops" between tracks, though specifiying mplayers audio output seems to almost eliminate the popping when changing tracks.

mplayer -msglevel all=6 -ao alsa file.mp3

MPlayer 1.3.0 (Debian), built with gcc-6.2.1 (C) 2000-2016 MPlayer Team
CPU: ARM

AUDIO: 16000 Hz, 2 ch, s16le, 24.0 kbit/4.69% (ratio: 3000->64000) 
Selected audio codec: [mpg123] afm: mpg123 (MPEG 1.0/2.0/2.5 layers I, II, III)
========================================================================== 

Building audio filter chain for 16000Hz/2ch/s16le -> 0Hz/0ch/??...
[libaf] Adding filter dummy
[dummy] Was reinitialized: 16000Hz/2ch/s16le
[dummy] Was reinitialized: 16000Hz/2ch/s16le
Trying preferred audio driver 'alsa', options '[none]'
alsa-init: requested format: 16000 Hz, 2 channels, 9
alsa-init: using ALSA 1.1.3
alsa-init: setup for 1/2 channel(s)
alsa-init: using device default
alsa-init: opening device in blocking mode
alsa-init: device reopened in blocking mode
alsa-init: got buffersize=32768
alsa-init: got period size 1024
alsa: 44100 Hz/2 channels/4 bpf/32768 bytes buffer/Signed 16 bit Little Endian
AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample)
AO: Description: ALSA-0.9.x-1.x audio output
AO: Author: Alex Beregszaszi, Zsolt Barat <joy@***.de>
AO: Comment: under development
Building audio filter chain for 16000Hz/2ch/s16le -> 44100Hz/2ch/s16le...
[dummy] Was reinitialized: 16000Hz/2ch/s16le
[libaf] Adding filter lavcresample
[SWR @ 0xb6841020]Using s16p internally between filters
[dummy] Was reinitialized: 44100Hz/2ch/s16le
[dummy] Was reinitialized: 44100Hz/2ch/s16le
Video: no video
Freeing 0 unused video chunks.
Starting playback...

alsa buffersize does not match the configuration's.

MPD (controlled by mpc) clicks/pops once when starting to play, but then apparently "streams" continuously so changing tracks does not cause any noise.

So, whatever causes the pops in the first place (hardware? driver?), some players seem to be better at avoiding that situation (opening/reconfiguring the device).
Any input on how to get to the root cause and fix it much appreciated!


Further digging

Configuring the ALSA plugins in the order plug -> dmix -> softvol -> pcm, results in mplayer giving an error:

[AO_ALSA] alsa-lib: pcm_dmix.c:1057:(snd_pcm_dmix_open) dmix plugin can be only connected to hw plugin

So, back to: plug -> softvol -> dmix -> I2S DAC (kernel PCM).

The configuration file can be written hierarchically as follows:

pcm.!default
{
  type plug
  slave
  {
    pcm
    {
      type softvol
      slave
      {
        pcm
        {
          type dmix
          ipc_key 1024
          ipc_perm 0666
          slave
          {
            pcm
            {
              type hw
              card 0
            }
            #format "S16"
            rate 32000
            channels 2
            period_size 2048  # bytes
            buffer_size 32768 # usec
          }
          bindings
          {
            0 0
            1 1
          }
        }
      }
      control
      {
        name "PCM" 
        card 0
      }
    }
  }
}

Softvol's control is what shows up as mixer device in e.g. alsamixer. I'm still unclear on what ctl's do. Alsa usually stores it's configuration/settings persistantly. This can cause stale mixer devices to appear.

This worked to remove them (use sudo):

rm /var/lib/alsa/asound.state # remove the state file
chmod -x /usr/sbin/alsactl # make alsactl non-executable to prevent settings being written on shutdown
<REBOOT>
chmod +x /usr/sbin/alsactl

With mplayer and 32kHz audio only occasional pops when changing tracks. Increasing the buffer size seems to have solved occasional "stuttering / echo" playback.

dmix is the plugin removing most of the pops on play/stop. It [occasional pops changing tracks with mplayer] does not make a noticable difference whether the sources or the default rate is set in dmix slave's rate.

Device tree overlays (link to documentation below):

$ ls /boot/overlays
adau1977-adc.dtbo                       fe-pi-audio.dtbo               iqaudio-dacplus.dtbo            pitft28-capacitive.dtbo         sdtweak.dtbo
adau7002-simple.dtbo                    goodix.dtbo                    iqaudio-digi-wm8804-audio.dtbo  pitft28-resistive.dtbo          smi-dev.dtbo
ads1015.dtbo                            googlevoicehat-soundcard.dtbo  justboom-dac.dtbo               pitft35-resistive.dtbo          smi.dtbo
ads1115.dtbo                            gpio-ir.dtbo                   justboom-digi.dtbo              pps-gpio.dtbo                   smi-nand.dtbo
ads7846.dtbo                            gpio-poweroff.dtbo             lirc-rpi.dtbo                   pwm-2chan.dtbo                  spi0-cs.dtbo
akkordion-iqdacplus.dtbo                gpio-shutdown.dtbo             mcp23017.dtbo                   pwm.dtbo                        spi0-hw-cs.dtbo
allo-boss-dac-pcm512x-audio.dtbo        hifiberry-amp.dtbo             mcp23s17.dtbo                   qca7000.dtbo                    spi1-1cs.dtbo
allo-digione.dtbo                       hifiberry-dac.dtbo             mcp2515-can0.dtbo               raspidac3.dtbo                  spi1-2cs.dtbo
allo-piano-dac-pcm512x-audio.dtbo       hifiberry-dacplus.dtbo         mcp2515-can1.dtbo               README                          spi1-3cs.dtbo
allo-piano-dac-plus-pcm512x-audio.dtbo  hifiberry-digi.dtbo            mcp3008.dtbo                    rotary-encoder.dtbo             spi2-1cs.dtbo
at86rf233.dtbo                          hifiberry-digi-pro.dtbo        midi-uart0.dtbo                 rpi-backlight.dtbo              spi2-2cs.dtbo
audioinjector-addons.dtbo               hy28a.dtbo                     midi-uart1.dtbo                 rpi-cirrus-wm5102.dtbo          spi2-3cs.dtbo
audioinjector-wm8731-audio.dtbo         hy28b.dtbo                     mmc.dtbo                        rpi-dac.dtbo                    spi-gpio35-39.dtbo
audremap.dtbo                           i2c0-bcm2708.dtbo              mpu6050.dtbo                    rpi-display.dtbo                spi-rtc.dtbo
bmp085_i2c-sensor.dtbo                  i2c1-bcm2708.dtbo              mz61581.dtbo                    rpi-ft5406.dtbo                 tinylcd35.dtbo
dht11.dtbo                              i2c-bcm2708.dtbo               papirus.dtbo                    rpi-proto.dtbo                  uart1.dtbo
dionaudio-loco.dtbo                     i2c-gpio.dtbo                  pi3-act-led.dtbo                rpi-sense.dtbo                  vc4-fkms-v3d.dtbo
dionaudio-loco-v2.dtbo                  i2c-mux.dtbo                   pi3-disable-bt.dtbo             rpi-tv.dtbo                     vc4-kms-v3d.dtbo
dpi18.dtbo                              i2c-pwm-pca9685a.dtbo          pi3-disable-wifi.dtbo           rra-digidac1-wm8741-audio.dtbo  vga666.dtbo
dpi24.dtbo                              i2c-rtc.dtbo                   pi3-miniuart-bt.dtbo            sc16is750-i2c.dtbo              w1-gpio.dtbo
dwc2.dtbo                               i2c-rtc-gpio.dtbo              piscreen2r.dtbo                 sc16is752-spi1.dtbo             w1-gpio-pullup.dtbo
dwc-otg.dtbo                            i2c-sensor.dtbo                piscreen.dtbo                   sdhost.dtbo                     wittypi.dtbo
enc28j60.dtbo                           i2s-gpio28-31.dtbo             pisound.dtbo                    sdio-1bit.dtbo
enc28j60-spi2.dtbo                      iqaudio-dac.dtbo               pitft22.dtbo                    sdio.dtbo

The overlay files are binary, but searching the sources at https://github.com/raspberrypi/linux/search?utf8=%E2%9C%93&q=hifiberry&type=

results in a few hits:

and further

So a specific driver exists. Is it available in Raspbian?

$ find /lib/modules/$(uname -r) -type f -name \*.ko | grep sound
/lib/modules/4.9.59+/kernel/sound/ac97_bus.ko
/lib/modules/4.9.59+/kernel/sound/drivers/mpu401/snd-mpu401.ko
/lib/modules/4.9.59+/kernel/sound/drivers/mpu401/snd-mpu401-uart.ko
/lib/modules/4.9.59+/kernel/sound/drivers/snd-virmidi.ko
/lib/modules/4.9.59+/kernel/sound/drivers/snd-dummy.ko
/lib/modules/4.9.59+/kernel/sound/drivers/snd-aloop.ko
/lib/modules/4.9.59+/kernel/sound/drivers/snd-mtpav.ko
/lib/modules/4.9.59+/kernel/sound/drivers/snd-serial-u16550.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm5102.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-pcm512x-i2c.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-adau7002.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-spdif-tx.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-sigmadsp-i2c.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-spdif-rx.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm8731.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-adau1701.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-cs42xx8-i2c.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-adau1977-i2c.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-ak4554.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm8804-i2c.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-pcm512x.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-sgtl5000.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm8741.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-pcm1794a.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm8804.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-arizona.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-tas5713.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-sigmadsp.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-adau1977.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-tpa6130a2.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-wm-adsp.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-cs42xx8.ko
/lib/modules/4.9.59+/kernel/sound/soc/codecs/snd-soc-pcm5102a.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-googlevoicehat-soundcard.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-rpi-cirrus.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-hifiberry-dacplus.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-hifiberry-amp.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-hifiberry-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-allo-piano-dac-plus.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-raspidac3.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-digidac1-soundcard.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-adau1977-adc.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-rpi-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-audioinjector-pi-soundcard.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-allo-piano-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-fe-pi-audio.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-allo-digione.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-dionaudio-loco.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-bcm2835-i2s.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-rpi-proto.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-allo-boss-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-hifiberry-digi.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-iqaudio-digi.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-pisound.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-iqaudio-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-justboom-digi.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-audioinjector-octo-soundcard.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-dionaudio-loco-v2.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-justboom-dac.ko
/lib/modules/4.9.59+/kernel/sound/soc/bcm/snd-soc-googlevoicehat-codec.ko
/lib/modules/4.9.59+/kernel/sound/soc/snd-soc-core.ko
/lib/modules/4.9.59+/kernel/sound/soc/generic/snd-soc-simple-card.ko
/lib/modules/4.9.59+/kernel/sound/soc/generic/snd-soc-simple-card-utils.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-hwdep.ko
/lib/modules/4.9.59+/kernel/sound/core/oss/snd-mixer-oss.ko
/lib/modules/4.9.59+/kernel/sound/core/oss/snd-pcm-oss.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-pcm.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-compress.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-timer.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-rawmidi.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-hrtimer.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq-virmidi.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/oss/snd-seq-oss.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq-midi-event.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq-device.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq-midi.ko
/lib/modules/4.9.59+/kernel/sound/core/seq/snd-seq-dummy.ko
/lib/modules/4.9.59+/kernel/sound/core/snd.ko
/lib/modules/4.9.59+/kernel/sound/core/snd-pcm-dmaengine.ko
/lib/modules/4.9.59+/kernel/sound/arm/snd-bcm2835.ko
/lib/modules/4.9.59+/kernel/sound/usb/snd-usb-audio.ko
/lib/modules/4.9.59+/kernel/sound/usb/caiaq/snd-usb-caiaq.ko
/lib/modules/4.9.59+/kernel/sound/usb/misc/snd-ua101.ko
/lib/modules/4.9.59+/kernel/sound/usb/6fire/snd-usb-6fire.ko
/lib/modules/4.9.59+/kernel/sound/usb/snd-usbmidi-lib.ko
/lib/modules/4.9.59+/kernel/sound/pci/ac97/snd-ac97-codec.ko

Nope.

Older effort to get driver going for different board: http://community.onion.io/topic/1761/resolved-attaching-pcm5102-to-omega2-i2s/13

This potentially shows how to make a matching device tree overlay and specify the driver (needs compiling?):

https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=8496&start=750#p1216305


Update 2

It must be caused by (re-)opening the device. With $ aplay -D default -c 2 -f S16 -r 48000 /dev/zero & the pops are gone with any player. But playing zeroes and software-mixing them seems a little CPU intensive:

$ w
 18:21:38 up  1:17,  1 user,  load average: 0.11, 0.15, 0.12
 ...

Kill it with

pi@raspberry:~ $ ps | grep aplay
16697 pts/0    00:00:28 aplay
pi@raspberry:~ $ ps aux | grep aplay
pi       16697  2.6  0.6   5828  2996 pts/0    SL   18:08   0:29 aplay -D default -c 2 -f S16 -r 48000 /dev/zero
pi       21159  0.0  0.3   4364  1764 pts/0    S+   18:26   0:00 grep --color=auto aplay
pi@raspberry:~ $ kill 16697
pi@raspberry:~ $ Aborted by signal Terminated...
aplay: pcm_write:2011: write error: Interrupted system call
^C
[1]+  Exit 1                  aplay -D default -c 2 -f S16 -r 48000 /dev/zero
pi@raspberry:~ $

(One could "autostart" this via an entry in /etc/rc.local.)


Update 3

MPD seems to have an option to "keep this audio output always open": https://www.musicpd.org/doc/user/config_audio_outputs.html But it seems to be for streaming only, since it does not affect pops on playback start:

sudo nano /etc/mpd.conf

audio_output {
        type            "alsa"
        name            "default"
#       device          "hw:0,0"        # optional
#       mixer_type      "hardware"      # optional
#       mixer_device    "default"       # optional
        mixer_control   "PCM"           # optional
#       mixer_index     "0"             # optional
        always_on       "yes"
}

sudo service mpd restart

mpc play

mpc stop

Further measurements and comparison with audio recording show:

  • IF the audible glitch/pop/crack occurs at the beginning of playback (I2S starting), it is visible on both speaker outputs as a positive spike
  • I suspect it could by caused by the LRCLK starting approx. 500 us after BCLK
  • datasheet shows different order in "TURN-ON RESPONSE (STANDBY MODE)"

So back to the I2S interface and driver

Building and running (warning: stopping the program even via desetup_io() does not stop the I2S) ...

~ $ git clone https://github.com/arisena-com/rpi_src
...
~/rpi_src/apps/i2s_test/src $ make
...
~/rpi_src/apps/i2s_test/src $ sudo ./i2s_test -t 2

starts the LRCLK on the third rising edge of BCLK and results in a nice ramp-up as shown in the datasheet, although BLCK starts first.


With _i2s_test_. Clock (yellow) starts two pulses before LRCLK (cyan). Audio out ramp-up visible on both channels (no pop or crackle): good

Playing audio. Note glitch/ gap in clock (yellow, about 30 us clock followed by 150 us high). Output (pink/blue) seems undefined before pop occurs (at trigger) when LRCLK starts, about 30 ms before data starts (not shown): bad

Sometimes the pop isn't noticable, but the trace looks very similar.


So is it the BLCK glitch (what causes this, it's probably not intentional) or polarity (i2s_test starts from low-level) while regular operation has high-level?

So, let's try to use the appropriate driver as laid out in https://raspberrypi.stackexchange.com/a/74804/75483

[building the kernel takes probably a day or so, it's probably worth looking into cross-compiling..]

Although it seems to build OK (sound/soc/codecs/snd-soc-max98357a.ko), the pi0w does not appear to boot properly after, at least it does not connect to wifi. I'll have to hook it up to a display and HID.


I could not get a keyboard to work either, and it's not because I used a simple A-micro B adapter instead of a proper OTG adapter first.

Now I probably could attach to it via serial port...

The end of the working (Stretch lite default kernel) boot process output on serial looks like

[    0.000000] Linux version 4.9.41+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #1023 Tue Aug 8 15:47:12 BST 2017

[  OK  ] Started Configure Bluetooth Modems connected by UART.
[  OK  ] Started Load/Save RF Kill Switch Status.
[  OK  ] Started LSB: Resize the root filesystem to fill partition.
[  OK  ] Started dhcpcd on all interfaces.
[  OK  ] Reached target Network.
[  OK  ] Reached target Network is Online.
[  OK  ] Started Daily apt download activities.
[  OK  ] Started Daily apt upgrade and clean activities.
[  OK  ] Reached target Timers.
         Starting OpenBSD Secure Shell server...
         Starting Permit User Sessions...
         Starting /etc/rc.local Compatibility...
My IP address is xxxx:xx:xxxx:xxxx:xxxx:xxxx:xxx:xxxx
[  OK  ] Started OpenBSD Secure Shell server.
[  OK  ] Started Permit User Sessions.
[  OK  ] Started /etc/rc.local Compatibility.
         Starting Daily apt download activities...
         Starting Hold until boot process finishes up...
         Starting Terminate Plymouth Boot Screen...

The image with custom kernel (no wifi, no keyboard) results in

[    0.000000] Linux version 4.9.61+ (pi@raspberry) (gcc version 6.3.0 20170516 (Raspbian 6.3.0-18+rpi1) ) #1 Mon Nov 13 03:14:02 CET 2017

[FAILED] Failed to start Configure Bluetooth Modems connected by UART.
See 'systemctl status hciuart.service' for details.
[  OK  ] Started dhcpcd on all interfaces.
[  OK  ] Reached target Network.
         Starting OpenBSD Secure Shell server...
[  OK  ] Reached target Network is Online.
         Starting LSB: Start NTP daemon...
[  OK  ] Started Music Player Daemon.
         Starting Permit User Sessions...
         Starting /etc/rc.local Compatibility...
[  OK  ] Started /etc/rc.local Compatibility.
[  OK  ] Started Permit User Sessions.
         Starting Terminate Plymouth Boot Screen...
         Starting Hold until boot process finishes up...
[  OK  ] Created slice User Slice of root.
[  OK  ] Started Session c1 of user root.
         Starting User Manager for UID 0...

Isn't WIFI and bluetooth on the same chip? No hardware info or actual schematics available from RPi Foundation.

pi@raspberry:~$ ifconfig wlan0
wlan0: error fetching interface information: Device not found

So I broke the Wifi. Any chance of reverting to the working kernel/configuration without losing my changes/files? Replace kernel files from working SD? No, replacing everything in /boot/ except for config.txt results in a hanging boot at

[    2.930955] mmc1: new high speed SDIO card at address 0001
[   22.411095] random: crng init done

So now I'll really have have to start fresh. I might be able to read my data from home dir by attaching the damaged system via USB OTG and card reader, something like

sudo mkdir /media/usb
sudo chown -R pi:pi /media/usb
sudo mount /dev/sda2 /media/usb
/media/usb/home/pi$ cp -r * ~

Maybe I should have updated first:

pi@raspberrypi:~ $ sudo rpi-update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
...
 *** Backing up modules 4.9.41+
...
 *** depmod 4.9.62-v7+
 *** depmod 4.9.62+
...
 *** If no errors appeared, your firmware was successfully updated to 23b1614bb794dfce586f1300da75198befa4951d
 *** A reboot is needed to activate the new firmware
pi@raspberrypi:~ $ sudo reboot
  • I might try again tomorrow (after making a backup).
  • No Wifi/IP after update (but wlan0 shown in ifconfig)

    • set wifi-country with sudp raspi-config (4 > I4)
  • No need to enable i2s-mmap nor i2s, the hifiberry-dac overlay does this automatically and mmap is available implicitly since 4.9 (April 2017).


See https://github.com/raspberrypi/linux/issues/2212 about this exact issues and some I2S driver details


Resources:

  • Yeah, for iterative debugging you should certainly cross-compile the kernel. Bummer that recompiling broke WiFi. Going from 4.9.41+ to 4.9.61+ isn't a huge change so I would guess the kernel/modules aren't tested well for compiling with gcc 6.3.0. With a cross-compilation environment on Debian 9 you can narrow that out. As for "working kernel/configuration without losing my changes/files? Replace kernel files from working SD?", yes at most you need back up only /boot/kernel.img, /boot/*.dtb, /boot/overlays/, and /lib/modules/ – jdonald Nov 18 '17 at 1:18
  • @jdonald Thanks, I've not given up completely, though setting up Virtualbox with lubuntu has not worked for me yet. I haven't had a linux setup in quite a while so it's quite a big effort and I'd rather be doing other things. In fact, I am doing these right now (working around hardcoded buffer size in py-spidev). I backed up my card with Win32DiskImager but will try your suggestion next time. – handle Nov 18 '17 at 16:54
  • 1
    @jdonald VirtualBox (+ Extensions for Shared Folders and a USB card reader) with Ubuntu 16 LTS now resulted in a working kernel, but it looks like it's the I2S driver and/or hardware causing the BCLK glitch which is in fact responsible for the pop (in conjunction with this specific DAC). – handle Nov 28 '17 at 7:26
2

So a specific driver exists. Is it available in Raspbian?

Nope.

(needs compiling?)

So yes it's available by specifying it as a module and recompiling the kernel. One way to configure for max98357a is to edit sound/soc/bcm/Kconfig add the line:

select SND_SOC_MAX98357A

right under the line with PCM5102A, and then add CONFIG_SND_SOC_MAX98357A=m to your .config before rebuilding.

I'm told this sort of direct editing of .config is frowned upon, but as it stands now this module doesn't appear in menuconfig.

When I load the module via sudo modprobe snd-soc-max98357a on my Pi Zero W it doesn't show any errors in dmesg, for what it's worth. If this could get you closer to your goal or at least rule something out, happy to provide you with these compiled binaries.

The overlay files are binary, but... https://github.com/raspberrypi/linux/blob/rpi-4.9.y/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts

Right, you could try editing hifiberry-dac-overlay.dts and replacing pcm5102a with max98357a. Device tree overlays are automatically rebuilt with the dtbs target in the standard kernel build flow.

  • Thanks, I have that on my todo list, there seem to be a few differences to the drivers but I have not yet looked into it further. The I2S interface shows application-dependant behaviour, i.e. mpg123 seems to open the device twice, causing very noticable pops. mplayer does not appear to do this, and the pops are not as "extreme", but still, they occur regularly on opening the I2S transmission. I've noticed that the bit clock starts and runs for a brief time before stopping and then starting again. I don't know yet if this is intentional, I think not. However, this is probably not a direct ... – handle Nov 6 '17 at 11:21
  • ... cause for the popping. Maybe it's a timing issue. I'll check that with a logic analyser. Regarding drivers: I've found a few places that show how to work with device tree overlays, I'll add links later. – handle Nov 6 '17 at 11:25
  • I've updated the question with oscilloscope traces and a link to this exact issue on the RPi Github where some driver insights were given, but no solution yet (recommendation is to shut down the IC). Changing the device driver might not help, it seems the I2S driver is involved. – handle Nov 22 '17 at 17:19
2

You have to try a more powerful RPi. The mix of the Zero W single core CPU and the Linux give a system that in some case are not so responsive. A "pause" of some milliseconds in the wrong moment is a crack or a pop.

The fact that a bigger buffer helped somewhat is an important symptom. So, maybe, it's not possible to solve your problem.

  • 2
    Glitches due to non-realtime processing seems plausible. @handle is there any difference in behavior when you run mplayer/mpc with nice -20? If these commands spawn subprocesses you may have to look at top and renice the child processes. That's a software approach to testing @nicolap8's explanation. The hardware approach, depending on the difficulty of rebuilding your setup, is to test with a Pi 3. – jdonald Nov 6 '17 at 17:14
  • Unfortunately I don't have access to a model with better CPU to compare. The short interruption of the I2S clock does not appear to be the fundamental cause as it is always there, even, when starting playback does not cause noticable "pop". @jdonald I will test those parameters as well, but likely only on friday. – handle Nov 8 '17 at 11:27
  • No noticable difference.. – handle Nov 11 '17 at 13:19
0

If i Really Understand your quesion correctly: this should help you: If not i will delete it:

This is because a PWM output of the BCM2835 CPU is being used, rather than a >standard DAC. When the PWM function is activated, there’s a jump in output >voltage which results in the popping sound.

Until there’s a driver modification, the work-around suggested (other than using the HDMI sound output or an external USB sound card) is to run PulseAudio on top of ALSA and keep the driver active even when no sound is being output. This is achieved by disabling the module-suspend-on-idle PulseAudio module, then configuring applications to use PulseAudio rather than ALSA. Daniel Bader describes this work-around and how to configure MPD, in a blog post. However, when I tried this approach, the work-around didn’t work.

When module-suspend-on-idle was enabled, there was the popping sound but when module-suspend-on-idle was disabled, there was no sound output. I investigated this, mainly though the debug logs in /var/log/messages produced by PulseAudio after starting it with pulseaudio --start --log-target=syslog --log-level=4. I also had to look at the source occasionally too.

The problem turned out to be because the audio files I was playing were mono with a sampling rate of 16,000 Hz or 48,000 Hz, and the default audio input format for the ALSA driver was stereo (with a 48,000 Hz sampling rate). When the audio was being played, PulseAudio had to change the input format to match, even if the only change was stereo to mono. This format change involves resetting the driver and so causes a pop as it is deactivated and re-activated even if module-suspend-on-idle has not suspended the driver. Once audio playback is finished, the original audio format is restored, leading to a pop then too.

What is worse is that if module-suspend-on-idle is disabled there’s no audio output. When PulseAudio switches the format, the driver is suspended but never resumes. There are some comments in the PulseAudio source which suggest that module-suspend-on-idle is assumed to be available and is responsible for resuming drivers on a format change. Therefore the work-around for the popping, of disabling module-suspend-on-idle, isn’t suitable when the audio input format is not stereo at 48,000 Hz.

Rather than disabling module-suspend-on-idle, the work-around I arrived on was to set a very long idle timeout. This is done by appending timeout=604800 to the line starting with load-module module-suspend-on-idle in /etc/pulse/default.pa. Now, when there was a format change, the driver is still resumed but the driver will not be suspended until a week (604,800 seconds) after the last audio has been played.

Doing this, we don’t get popping between tracks when they are all stereo at 48,000 Hz, and at least other audio input formats play back. However, this doesn’t fix the popping on format change. To deal with this, I converted the audio to 48,000 Hz stereo before sending it to PulseAudio. One program which can do this is mplayer. For example to play back an audio file using PulseAudio do:

mplayer -ao pulse -af channels=2,resample=48000:1 FILENAME

The channels=2 converts mono to stereo and the resample=48000:1 converts the sampling rate to 48,000 Hz. The mplayer manpage gives more detail. These options can also be combined with other uses of mplayer, for example as an audio output program for the Festival speech synthesis program, by adding the following to your ~/.festivalrc:

(Parameter.set 'Audio_Command "mplayer -really-quiet -noconsolecontrols -nojoystick -nolirc -nomouseinput -demuxer rawaudio -rawaudio channels=1:rate=$SR $FILE -ao pulse -af channels=2,resample=48000:1")

Source

  • 1
    While your quoted source (I added proper formatting) has interesting information, you overlooked that my question is about an I2S device, which is in the title and the first sentence, so PWM is not the issue. If it were, your qoute omits that it has been fixed: Update (2013-03-07): According to a comment on the Raspberry Pi bug tracker, this problem has now been fixed. – handle Nov 2 '17 at 15:36
  • 1
    However, I will further try effects of sample rate settings tomorrow (initial tests with adjusting ALSA to the source file's sample rate did not resolve the problem). Please don't delete your answer, it may be helpful to others. – handle Nov 2 '17 at 15:46
  • sorry i will keep looking – User98764431 Nov 2 '17 at 17:20
  • If there are no other answers can I at least get the full bounty? – User98764431 Nov 2 '17 at 21:08

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.