pHAT DAC – Mixing multiple sounds?

Hello everyone!

I just received my pHAT DAC and am playing around a bit with it. What I’m currently trying to do is playing multiple sounds via a python script at once. This works flawlessly with my internal RPi 2 sound system for up to 8 streams. But as soon as I’m using the pHAT DAC there is only one sound coming out at once.

For reference: A small script that I used for the RPi with maximal 8 sounds playing simultaneously. Assume that there is a directory sounds with the soundfiles 1.wav, 2.wav, …

#!/usr/bin/python3

import time
from subprocess import Popen
from queue import Queue

sounds = Queue(maxsize = 8)

def play(number):
    if sounds.qsize() >= 8: sounds.get().kill()
    process = Popen(['aplay', './sounds/' + str(number) + '.wav'])
    sounds.put(process)

for i in range(1, 10):
    play(i)
    time.sleep(0.5)

What I would expect is to get 9 sounds (8 at a time maximal) to play in parallel, each started half a second before the preceding one. What happens in reality is that the first sound seems to block the output. Let’s assume it is 3 seconds long, then only 7.wav will be heard, the rest simply doesn’t play.

Is there anything I missed? Isn’t it possible to mix multiple sounds?

Thanks in advance for your help!

the pHAT DAC has no hardware mixing capability. I guess that is the problem here, with each of your processes being a different PCM stream. It’s my understanding that you have to set up a dmixer to work around the limitation.

… I can’t say I am particularly knowledgeable on the subject, so I can only refer you to some alsa documentation:

http://alsa.opensrc.org/Hardware_mixing,_software_mixing

Thanks a lot for your reply!

That sounds like it must be my problem – thanks for pointing it out. After copying the .asoundrc I get the following error from aplay:

ALSA lib pcm_direct.c:896:(snd1_pcm_direct_initialize_slave) slave plugin does not support mmap interleaved or mmap noninterleaved access
ALSA lib pcm_dmix.c:1034:(snd_pcm_dmix_open) unable to initialize slave

When including the mmap_emulation parameter as suggested by the linked documentation, I only get:

ALSA lib pcm_hw.c:1741:(_snd_pcm_hw_open) Unknown field mmap_emulation
ALSA lib pcm_dmix.c:1022:(snd_pcm_dmix_open) unable to open slave

As I’m far from an expert in this area, has anyone an idea on how to fix this? Maybe the parameters changed since that documentation-version?

This is probably the least succinct and concise example, but the Piano HAT simple-piano.py uses pygame.mixer to mix and play multiple .wav files simultaneously. If it works via pHAT DAC you may be able to modify this example for your own purposes:

Thanks a lot for this hint! It works perfect and is exactly what I wanted!