iMX8MP: How to play WAV between 9600 and 12000 Hz on Torizon?

Kernel version: 6.6.54-7.1.0-g3493ccd66900 #1-Torizon SMP PREEMPT Tue Dec 17 21:04:41 UTC 2024
Distro version: VERSION_ID=7.1.0-build.4
HW model: Toradex Verdin iMX8M Plus on Verdin Development Board
Toradex version: 0063 V1.1B

While trying to play a WAV file on Torizon, the ranges above 9600 and below 12000,
don’t seem to work at least with aplay. I assume, normally resampling would be handled by audio servers. But I can’t get PulseAudio or pipewire working within containers (aplay -l etc. list the cards, but pactl doesn’t). I suspected that it’s because /proc/asound is not accessible from within containers, but I also can’t share that according to docker.

So my question is, how to properly setup audio in a way, that works with Torizon?

Command I use to run the application container, based on a debian 12 container (+alsa):

docker run -it --rm --name=alsatest-run --device /dev/snd  -e XDG_RUNTIME_DIR=/tmp/1000-runtime-dir -e WAYLAND_DISPLAY=wayland-0  -v /tmp:/tmp -v /var/run/dbus:/var/run/dbus     -v /dev/galcore:/dev/galcore --device-cgroup-rule='c 199:* rmw'     --security-opt seccomp=unconfined alsatest

Works:

aplay -f U8 -r 9600 --dump-hw-params /dev/random

Does not work:

aplay -f U8 -r 9601 --dump-hw-params /dev/random

Error message:

Playing raw data '/dev/random' : Unsigned 8 bit, Rate 9601 Hz, Mono
HW Params of device "default":
--------------------
ACCESS:  MMAP_INTERLEAVED MMAP_NONINTERLEAVED MMAP_COMPLEX RW_INTERLEAVED RW_NONINTERLEAVED
FORMAT:  S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE MU_LAW A_LAW IMA_ADPCM S20_LE S20_BE U20_LE U20_BE S24_3LE S24_3BE U24_3LE U24_3BE S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE U18_3BE
SUBFORMAT:  STD
SAMPLE_BITS: [4 64]
FRAME_BITS: [4 640000]
CHANNELS: [1 10000]
RATE: [4000 4294967295)
PERIOD_TIME: (62 2047875]
PERIOD_SIZE: (0 4294967295)
PERIOD_BYTES: (0 4294967295)
PERIODS: (0 4294967295]
BUFFER_TIME: [1 4294967295]
BUFFER_SIZE: [1 4294967294]
BUFFER_BYTES: [1 4294967295]
TICK_TIME: ALL
--------------------
aplay: set_params:1416: Unable to install hw params:
ACCESS:  RW_INTERLEAVED
FORMAT:  U8
SUBFORMAT:  STD
SAMPLE_BITS: 8
FRAME_BITS: 8
CHANNELS: 1
RATE: 9601
PERIOD_TIME: (124988 124989)
PERIOD_SIZE: [1200 1200]
PERIOD_BYTES: (1200 1201)
PERIODS: (3 4)
BUFFER_TIME: (499947 499948)
BUFFER_SIZE: 4800
BUFFER_BYTES: 4800
TICK_TIME: 0

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


Hello! Thank you for sharing detailed information about your system and setup.

Let me address your concerns step-by-step:

Why Sample Rates Like 9601 Hz Don’t Work

On Torizon OS (and most embedded Linux systems), direct audio output via ALSA may only support specific, standard hardware sample rates (e.g., 8000, 11025, 16000, 22050, 32000, 44100, 48000 Hz, etc.). Attempting to use a non-standard sample rate (such as 9601 Hz) with aplay is likely to fail unless:

  • Your hardware supports this exact rate (unlikely; hardware typically supports a discrete set).
  • The software stack automatically performs sample rate conversion (resampling), which ALSA can sometimes do with its plugin layer, but only if properly configured.

Desktop Linux commonly uses PulseAudio or PipeWire for this “smart” resampling. Torizon OS prefers direct ALSA usage for simplicity and lower overhead, so advanced resampling out-of-the-box isn’t present(1).

PulseAudio/PipeWire in Containers

  • PulseAudio and PipeWire aren’t enabled or recommended in standard Torizon images.
  • They require additional configuration to run properly in containers due to user session management, permissions, and shared resources (like /proc/asound and XDG runtime directories), but this adds complexity and overhead which is contrary to Torizon design principles.

/proc/asound Access in Containers

  • /proc/asound is generally mounted in all containers running on the host.
  • Within your container, you should be able to access this unless the container is very tightly sandboxed.
  • ALSA in containers mainly requires access to /dev/snd devices, which you are passing with --device /dev/snd.

Correct Audio Setup in Torizon Containers

Here’s the recommended minimal setup for audio playback using ALSA within a Torizon container:

  1. Make Sure /dev/snd is Exposed

    docker run -it --rm --device /dev/snd <your-container>
    

    (No additional mounts needed for /proc/asound; it’s already exposed.)

  2. Check Supported Sample Rates

    • Run this to see supported audio codecs/cards:
      cat /proc/asound/cards
      
    • To inspect details about PCM capabilities (including rates):
      aplay -l
      aplay --dump-hw-params <YOUR DEVICE>
      

    This will show you the supported sample rates by your hardware.

  3. Use Supported Sample Rates

    • If you try to play a file at a non-standard sample rate (such as 9601 Hz), ALSA will fail unless resampling is set up.
    • Convert your audio files to a supported rate before playback, e.g.:
      sox input.wav --rate 16000 output_16k.wav
      
    • Then play with aplay at 16kHz, which is supported.
  4. If You Need Software-Based Sample Rate Conversion

    • ALSA itself can perform basic resampling using its plugins, but by default, aplay uses the “hw” device, which talks directly to hardware.
    • To enable automatic software resampling, use the “plughw” or “default” ALSA devices:
      aplay -D plughw:0,0 file.wav
      aplay -D default file.wav
      
    • This can allow resampling for non-native rates, but the quality and performance may vary.

Example: Running Audio in a Container

docker run -it --rm --device /dev/snd debian:12

Inside the container:

aplay -l
aplay -f U8 -r 8000 /path/to/audio.wav           # Standard supported rate
aplay -D plughw:0,0 -f U8 -r 9601 /path/to/audio.wav   # Allows resampling

Summary Recommendation

  • Stick to standard sample rates supported by your audio hardware for trouble-free playback.
  • Use ALSA’s “default” or “plughw” devices when you must play non-native-rate files.
  • No need to mount /proc/asound explicitly.
  • Advanced desktop audio servers like PulseAudio/PipeWire aren’t recommended or needed for typical Torizon use cases.

See these resources for practical examples:

If you need a sample container Dockerfile or more help with ALSA configuration, please let me know!

Best regards,
Toradex AI Assistant.

@ToradexAI

The problem is, that it also occurs on sample rates such as 11025.
Furthermore, /proc/asound is empty within the container.

Also I have the concern, that playing multiple audio files at the same time won’t work, unless an audio server is setup.

For “just playing one single file”, I currently have the workaround of using “plug:dmix” as the ALSA device:

aplay -D plug:dmix ./test.wav

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Hello,

Thank you for providing more details. Let’s address your follow-up points:


1. Standard Rates like 11025 Hz Not Working

If 11025 Hz (a standard rate) also fails using plain aplay, this typically means either:

  • The underlying hardware does not support that rate natively.
  • ALSA is accessing the “hw” device directly, which only permits the hardware’s native rates.

Your use of plug:dmix works because plug provides software-level conversion and dmix enables mixing multiple audio streams in software.


2. /proc/asound is Empty in the Container

This is unusual if you’re running your container with --device /dev/snd. Normally, /proc/asound should be visible (populated) since it’s a pseudo-filesystem from the kernel and not blocked by default Docker containerization.

Possible reasons and workarounds:

  • Your container image or entrypoint may be clearing /proc or there’s a restrictive mount namespace.
  • For most ALSA applications, /dev/snd device nodes are more critical than /proc/asound.

You should still be able to interact with audio hardware as long as /dev/snd is available and ALSA libraries can access their configuration.


3. Concurrent Audio Playback and the Need for an Audio Server

You are correct:

  • ALSA hw device: Only one client can access a hardware device at a time.
  • dmix (“plug:dmix”): Enables software mixing, so multiple clients can play audio simultaneously, but only for PCM (not always for everything, like MIDI).
  • PulseAudio/PipeWire: Provide broader capabilities and device/session management but are not default or trivial to set up in Torizon containers.

For robust mixing without PulseAudio/PipeWire:

  • Continue using plug:dmix for software mixing within ALSA.
  • Alternatively, use a framework like GStreamer for mixed/multiple stream playback.

4. Recommendations

a) Always Use plug:dmix or default

For playback from multiple sources or with various sample rates/rates not natively supported, run:

aplay -D plug:dmix yourfile.wav

Or, if default is suitably set up, use:

aplay -D default yourfile.wav

This uses software plugins for both mixing and resampling.

b) For More Advanced Use

For more advanced audio routing, mixing, or synchronizing multiple files/streams, consider GStreamer:

c) Checking /proc/asound

Even if /proc/asound is empty, if aplay -l lists your sound cards, you have access:

aplay -l

d) Reference


Summary:
Your workaround with plug:dmix is the standard solution for playing multiple files or non-native sample rates without an audio server on Torizon. For even more flexibility, look into GStreamer as an in-container solution.

If you need help modifying the ALSA config (.asoundrc) to make plug:dmix the default, or examples for GStreamer, just let me know!

Best regards,
Toradex AI Assistant.

@ToradexAI Please provide me with an example file to make plug:dmix the default

Thanks for your response.

Please remember to tick the “Solution” checkbox below if my response solves your question. If you have follow-up questions, just continue to tag me using @ToradexAI in your new posts.

Did you like my answer? :+1: :-1:


Hello!

Certainly! To make plug:dmix the default ALSA audio device in your container, you can use a .asoundrc file in your home directory. Below is an example .asoundrc configuration that sets plug:dmix as the default PCM and control device:

Create the file (in your container, as root or your user):

touch ~/.asoundrc

Put the following contents into ~/.asoundrc:

pcm.!default {
    type plug
    slave.pcm "dmix"
}

ctl.!default {
    type hw
    card 0
}

What this does:

  • It sets the default PCM device to plug:dmix, so all standard ALSA applications (like aplay) will use software mixing and resampling by default.
  • The control (mixer) is set to the first sound card (usually card 0).

After this, simply running:

aplay ./test.wav

…will automatically use plug:dmix for output.

If your audio card is not card 0, adjust the card number in ctl.!default accordingly.

Additional info:

Let me know if you need further help!

Best regards,
Toradex AI Assistant.