Getting Started with USB Audio on i.MX boards

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Getting Started with USB Audio on i.MX boards

Getting Started with USB Audio on i.MX boards

Introduction. 

USB is a highly efficient interface for transporting audio and voice data, offering sufficient bandwidth for applications from voice telephony to high-quality audio playback and recording. To ensure compatibility between devices, the USB Audio Class specification defines standardized mechanisms for audio transport and control, allowing audio peripherals to operate with generic drivers and minimizing platform software requirements. 
 
For i.MX processors, this article describes how an i.MX board can function as a standard USB audio device, enabling audio data to be streamed through the USB port to a host computer. This capability is important for applications such as USB microphones, speakers, audio gateways, and voice-processing systems.
 
As a result, developers can efficiently implement real time audio transfer between i.MX boards and host systems using standard USB audio drivers without requiring additional proprietary interfaces.
 

Required equipment.

  • i.MX95 FRDM board (this is the selected board for this post, it works for others).
  • Debug USB-C cable.
  • Data USB-C cable.
  • USB-C power supply.
  • Ethernet cable.
  • Speakers or headphones with 3.5mm input plug.
  • Personal computer.

To start, we need to flash our Linux BSP into the board. You can build it by yourself or use the pre-built BSP to facilitate the process.

This post was tested with Linux 6.18.20_2.0.0, if you have issues to flash the board, please refer to this article:

Flashing Linux BSP using UUU

This is how my hardware setup looks:

Media.jpg

USB gadget setup.

The following script configures the board to work as an USB audio gadget in Linux. This setup allows the board to be detected as a standard audio device, enabling audio streaming over the USB connection without requiring a custom USB protocol on the host side.

The script creates the USB gadget configuration, assigns the required USB descriptors, with predefined audio parameters such as 16 kHz sample rate, 32-bit sample size, and single-channel capture/playback support. This example is useful for applications such as voice capture, audio processing, USB microphones, or embedded audio demos.

#!/bin/sh

# USB gadget ConfigFS paths
CONFIGFS=/sys/kernel/config/usb_gadget
GADGET=$CONFIGFS/g1
CONFIG=$GADGET/configs/c.1
FUNCTIONS=$GADGET/functions

# USB device descriptors and audio configuration
VID="0x1fc9"
PID="0x0330"
SERIALNUMBER="0123456789"
MANUFACTURER="NXP Semiconductors"
PRODUCT="i.MX USB Audio Gadget"
SAMPLE_RATE=16000
SAMPLE_SIZE=4 # 32-bit audio samples

echo "Setting up USB gadget with the following parameters:"
echo "  Vendor ID: $VID"
echo "  Product ID: $PID"
echo "  Serial Number: $SERIALNUMBER"
echo "  Manufacturer: $MANUFACTURER"
echo "  Product: $PRODUCT"
echo "  Sample Rate: $SAMPLE_RATE Hz"

function add_uac2_function() {
  # Create a USB Audio Class function instance
  mkdir $FUNCTIONS/uac2.$1

  echo "$PRODUCT $1" > $FUNCTIONS/uac2.$1/function_name

  # c_* parameters configure USB Capture 
  # p_* parameters configure USB Playback 

  # Audio sample rate configuration
  echo $SAMPLE_RATE > $FUNCTIONS/uac2.$1/c_srate
  echo $SAMPLE_RATE > $FUNCTIONS/uac2.$1/p_srate

  # Audio sample size in bytes
  echo $SAMPLE_SIZE > $FUNCTIONS/uac2.$1/c_ssize
  echo $SAMPLE_SIZE > $FUNCTIONS/uac2.$1/p_ssize

  echo $2 > $FUNCTIONS/uac2.$1/c_chmask
  echo $3 > $FUNCTIONS/uac2.$1/p_chmask

  # Enable mute and volume controls visible to the USB host
  echo 0x1 > $FUNCTIONS/uac2.$1/c_mute_present
  echo 0x1 > $FUNCTIONS/uac2.$1/c_volume_present
  echo 0x1 > $FUNCTIONS/uac2.$1/p_mute_present
  echo 0x1 > $FUNCTIONS/uac2.$1/p_volume_present

  # Add the UAC2 function to the active USB configuration
  ln -s $FUNCTIONS/uac2.$1 $CONFIG
}

function create_config() {
  # Create the USB gadget device
  mkdir $GADGET

  # Set USB Vendor ID and Product ID
  echo $VID > $GADGET/idVendor
  echo $PID > $GADGET/idProduct

  # Standard USB string descriptors
  mkdir $GADGET/strings/0x409
  echo $SERIALNUMBER > $GADGET/strings/0x409/serialnumber
  echo $MANUFACTURER > $GADGET/strings/0x409/manufacturer
  echo $PRODUCT > $GADGET/strings/0x409/product

  # Create USB configuration description
  mkdir -p $CONFIG/strings/0x409
  echo $1 > $CONFIG/strings/0x409/configuration
}

# Create a UAC2 audio gadget with mono capture and mono playback
create_config "UAC2"
add_uac2_function "Active" 0x1 0x1

echo "Done"

Clean USB gadget.

If you need to free up the USB port, it is necessary to run the following script.

#!/bin/sh

# USB gadget ConfigFS paths
CONFIGFS=/sys/kernel/config/usb_gadget
GADGET=$CONFIGFS/g1
CONFIG=$GADGET/configs/c.1
FUNCTIONS=$GADGET/functions

# Verify that the gadget exists before attempting cleanup
if [ ! -d "$GADGET" ]; then
    echo "Gadget does not exist"
    exit 0
fi

# Disconnects the gadget from the host before removal.
echo "" > $GADGET/UDC 2>/dev/null

# Remove UAC2 function links from the configuration
rm -f $CONFIG/uac2.* 2>/dev/null

# Remove UAC2 function instances
rmdir $FUNCTIONS/uac2.* 2>/dev/null

# Remove configuration strings and configuration directory
rmdir $CONFIG/strings/0x409 2>/dev/null
rmdir $CONFIG/strings 2>/dev/null
rmdir $CONFIG 2>/dev/null

# Remove gadget string descriptors
rmdir $GADGET/strings/0x409 2>/dev/null
rmdir $GADGET/strings 2>/dev/null

# Remove the gadget itself
rmdir $GADGET 2>/dev/null

echo "Cleanup completed"

Testing.

Both scripts can be created into the board using nano or a similar text editor through the console but is easier to do it in your host machine and send it for example using SCP.

After you created both scripts you can send them with the next command:

scp <file_to_transfer> <user>@<ip_address>:<destination_path>

Once you connected the Ethernet cable in any of the available RJ45 connectors in your board, you can get the IP address with the next command:

ifconfig

Now, in your host machine, you can go to the path where are your USB scripts and send them:

scp cleanup_usb_gadget.sh root@<frdm_board_ip>:~/
scp setup_usb_gadget.sh root@<frdm_board_ip>:~/

After transfer the scripts to the board, you need to change file permissions to execute the scripts with chmod and run USB gadget setup script to configure the board as a USB audio interface.

chmod u+x *_usb_gadget.sh

JorgeCas_0-1782324986101.png

Once this script have been executed you can see the USB port in ALSA as a sink/source device:

JorgeCas_2-1782325559529.png

Then, you need to connect the USB port to a host computer and will be recognized as an USB interface:

JorgeCas_4-1782325847685.png

You can validate that the device is working according to the configuration defined in setup script:

Screenshot 2026-07-29 104314.png

I will use Audacity to test audio transfer from on board microphones, in Edit -> Preferences -> Audio settings select i.MX Active as recording device:

JorgeCas_5-1782326183462.png

Note: Use the same sample rate of setup_usb_gadget.sh configuration to avoid errors with the DAW.

In the board, I will start the recording by running the following GStreamer pipeline, which captures audio from the onboard microphones and streams it through the USB port:

gst-launch-1.0 alsasrc device=hw:micfilaudio,0 ! queue ! audioconvert ! audio/x-raw,channels=1,rate=16000,format=F32LE ! audioconvert ! alsasink device=hw:UAC2Gadget,0

After this configuration, add an audio track and now, is possible to get the audio and record it directly in the DAW:

JorgeCas_0-1782327009216.png

If you want to play audio from host PC trough the i.MX board, you need to run the next command before start the audio playback in host. Make sure that the audio card selected is not busy:

gst-launch-1.0 -v alsasrc device=hw:UAC2Gadget,0 ! audio/x-raw,format=S32LE,rate=16000,channels=1 ! audioconvert ! audioresample ! audio/x-raw,format=S16LE,rate=48000,channels=2 ! audioconvert ! alsasink device=plughw:mqsaudio,0

In this case, I selected the MQS output in 3.5mm output jack, you can connect the speakers or headphones with this connector.

After run the clean USB gadget script, the USB audio device is not longer detected in host PC and the board output is the next:

JorgeCas_3-1782325608663.png

References.

USB Implementers Forum. (1998, March 18). Universal Serial Bus device class definition for audio devices (Release 1.0) [PDF]. USB-IF. https://www.usb.org/sites/default/files/audio10.pdf 

 
No ratings
Version history
Last update:
yesterday
Updated by: