Skip to content

Audio Recording and Playback

The OriginMan extended version comes with a speaker and an audio processing chip, located on the back of OriginMan.

Related examples are located in: /userdata/dev_ws/src/originman/originman_pydemo/audio

image-20220920222359026

Driver Installation

Before using the audio-related devices, the OriginMan controller needs to recognize the audio devices and read audio data from the relevant hardware interfaces.

Use the following commands to drive the audio devices:

insmod snd-soc-max98357a.ko 
insmod snd-soc-hobot-sound-machine.ko
Hint

In OriginMan's image, these commands have already been set up in the startup configuration file, so no further configuration is needed.

Audio Recording

After completing the driver installation, try recording some audio by executing the following command:

arecord -Dhw:1,0 -c 2 -r 48000 -f S32_LE -t wav -d 10 test.wav

This command uses sound card #1's device 0 to record 10 seconds of audio in dual-channel, 48000 Hz sampling rate, 32-bit signed integer little-endian format, and saves the recording as a WAV file named test.wav.

image-20220920222359026

As shown above, a test.wav audio file will be generated after recording.

Hint

The current audio processor only supports the above audio data format; channels and sampling rate cannot be changed. Recording time can be adjusted based on actual needs. Recording can be stopped within 10s using Ctrl+C, and the audio file will still be saved.

Audio Playback

Audio playback can be done using the following command:

aplay -D hw:1,0 test.wav

aplay is a built-in system command for audio playback. hw:1,0, as in audio recording, represents using device 0 of sound card #1.

Press Enter and you'll hear OriginMan playing the audio you just recorded!

Continuous Recording and Playback

Let's execute the following commands for continuous recording and playback:

python3 /userdata/dev_ws/src/originman/originman_pydemo/audio/test_audio.py

# cd /userdata/dev_ws/src/originman/originman_pydemo/audio
# python3 test_audio.py

image-20220920222359026

Here's the content of this Python file:

#!/usr/bin/env python3
import time
import subprocess
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from ros_robot_controller_sdk import Board
import logging

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

class VoiceControlNode:
    def __init__(self):
        # Initialize Board
        self.board = Board()
        self.board.enable_reception()

        # Audio device parameters
        self.audio_device = "plughw:1,0"

    def play_audio(self, file_path):
        """Play audio file"""
        try:
            cmd = ["aplay", "-D", self.audio_device, file_path]
            result = subprocess.run(cmd, check=True, capture_output=True, text=True)
            logging.info(f"Played {file_path}")
        except subprocess.CalledProcessError as e:
            logging.error(f"Error playing {file_path}: {e.stderr.strip()}")

    def record_audio(self, file_path, duration=2):
        """Record audio, default 2 seconds"""
        try:
            cmd = [
                "arecord",
                "-D", self.audio_device,
                "-c", "2",
                "-r", "48000",
                "-f", "S32_LE",
                "-t", "wav",
                "-d", str(duration),
                file_path
            ]
            result = subprocess.run(cmd, check=True, capture_output=True, text=True)
            logging.info(f"Recorded {file_path}")
        except subprocess.CalledProcessError as e:
            logging.error(f"Error recording {file_path}: {e.stderr.strip()}")

    def run(self):
        """Main loop, plays prompt sound, records 2 seconds and plays back"""
        while True:
            self.play_audio("prompt.wav")  # Play prompt sound
            self.record_audio("test.wav", duration=2)  # Record for 2 seconds
            self.play_audio("test.wav")  # Play back recorded audio
            time.sleep(0.5)  # Brief sleep to avoid too frequent loops

def main():
    # Output code usage instructions
    logging.info("Code Usage Instructions:")
    logging.info("1. Ensure that `aplay` and `arecord` tools are installed in your system for audio playback and recording.")
    logging.info("2. Ensure `prompt.wav` file exists in the current working directory to be used as a prompt sound.")
    logging.info("3. After running this script, the program will enter an infinite loop, performing these actions each cycle:")
    logging.info("   - Play `prompt.wav` prompt sound.")
    logging.info("   - Record 2 seconds of audio and save as `test.wav`.")
    logging.info("   - Play back the recently recorded `test.wav` file.")
    logging.info("   - Brief 0.5-second sleep before starting the next cycle.")
    logging.info("4. To stop the program, press `Ctrl + C` in the terminal.")

    node = VoiceControlNode()
    try:
        node.run()
    except KeyboardInterrupt:
        logging.info("Shutting down voice control")

if __name__ == "__main__":
    main()

The main actions are: playing a pre-recorded audio - "I'm here!", then starting recording, and after recording is complete, playing back the recording. The functions used are based on aplay and arecord.

Image1