Lab3: Audio Recording and Playback

Introduction

In this lab, you will learn how to record and play audio on the Mini Pupper using Python. The Mini Pupper 2 has built-in audio capabilities that allow you to record sound through a microphone and play it back through speakers. This is useful for voice commands, audio feedback, and interactive applications.

Prerequisites

Install the required Python packages:

pip install sounddevice soundfile

Audio Configuration

Before running the audio test, ensure your audio devices are properly configured. Check or create the ~/.asoundrc file:

nano ~/.asoundrc

Add the following configuration:

pcm.!default {
    type asym
    playback.pcm {
        type plug
        slave.pcm "hw:0,0"  # Playback device
    }
    capture.pcm {
        type plug
        slave.pcm "hw:1,0"  # Capture device
    }
}

ctl.!default {
    type hw
    card 0  # Control device
}

This configuration sets up asymmetric audio with separate playback and capture devices.

Running the Audio Test

Navigate to the demos folder and run the test:

cd ~/mini_pupper_bsp/demos/
python audio_test.py

Example Output

Audio test running on Mini Pupper

Complete Audio Test Code

#!/usr/bin/env python3
import sounddevice as sd
import soundfile as sf
import time
import os

# Audio record parameters
fs = 48000  # 48KHz, Audio sampling rate
duration = 5  # Recording duration in seconds

# Set the default speaker volume to maximum
# Headphone number is 0 without HDMI output
# Headphone number is 1 when HDMI connect the display
os.system("amixer -c 0 sset 'Headphone' 100%")

print("Mini Pupper 2 audio record start...")
record = sd.rec(int(duration * fs), samplerate=fs, channels=2)
sd.wait()  # Wait for record to finish
print("Mini Pupper 2 audio record end.")

# Increase the volume [manually]
record *= 100

# Save the record
sf.write('/tmp/mini-pupper-2-audio_test.wav', record, fs)

# Wait for 1 second to playback
time.sleep(1)

# Play audio
print("Mini Pupper 2 audio playback start...")
sd.play(record[:, 0], fs)
sd.wait()  # Wait for playback to finish
sd.play(record[:, 1], fs)
sd.wait()  # Wait for playback to finish
print("Mini Pupper 2 audio playback end.")

Code Breakdown

1. Import Libraries

import sounddevice as sd
import soundfile as sf
import time
import os
  • sounddevice: Python library for audio recording and playback
  • soundfile: Library for reading and writing audio files
  • time: For adding delays
  • os: For system commands

2. Audio Parameters

fs = 48000  # 48KHz, Audio sampling rate
duration = 5  # Recording duration in seconds
  • fs: Sample rate of 48kHz (CD quality is 44.1kHz)
  • duration: How long to record in seconds

3. Set Speaker Volume

os.system("amixer -c 0 sset 'Headphone' 100%")

Uses ALSA mixer to set the headphone volume to maximum. The card number may vary:

  • Card 0: Without HDMI output
  • Card 1: When HDMI is connected to a display

4. Record Audio

record = sd.rec(int(duration * fs), samplerate=fs, channels=2)
sd.wait()
  • sd.rec(): Records audio with specified samples, sample rate, and channels
  • sd.wait(): Blocks until recording is complete
  • channels=2: Stereo recording

5. Amplify and Save

record *= 100
sf.write('/tmp/mini-pupper-2-audio_test.wav', record, fs)
  • Multiply the recording by 100 to increase volume
  • Save as WAV file to /tmp/ directory

6. Playback Audio

sd.play(record[:, 0], fs)
sd.wait()
sd.play(record[:, 1], fs)
sd.wait()
  • Play left channel (record[:, 0])
  • Play right channel (record[:, 1])
  • Wait for each playback to complete

Exercises

Exercise 1: Variable Recording Duration

Modify the script to accept recording duration as a command-line argument.

import sys
duration = int(sys.argv[1]) if len(sys.argv) > 1 else 5

Exercise 2: Audio Level Meter

Create a real-time audio level meter that displays the input volume.

import numpy as np

def audio_callback(indata, frames, time, status):
    volume = np.linalg.norm(indata) * 10
    print("|" + "=" * int(volume) + " " * (50 - int(volume)) + "|")

with sd.InputStream(callback=audio_callback):
    sd.sleep(10000)

Exercise 3: Voice-Activated Recording

Implement voice-activated recording that starts when sound is detected above a threshold.

Troubleshooting

Issue Solution
No audio devices found Check arecord -l and aplay -l for available devices
Permission denied Add user to audio group: sudo usermod -a -G audio $USER
Wrong device Update card numbers in ~/.asoundrc
No sound output Check volume with alsamixer
Recording too quiet Increase the multiplication factor (e.g., record *= 200)

Checking Audio Devices

List recording devices:

arecord -l

List playback devices:

aplay -l

Test recording:

arecord -d 5 -f cd test.wav

Test playback:

aplay test.wav

Summary

In this lab, you learned:

  • How to configure ALSA audio devices on Raspberry Pi
  • How to record audio using the sounddevice library
  • How to save and load audio files with soundfile
  • How to play back recorded audio
  • How to adjust audio volume programmatically

Reference