Skip to main content
Version: Torizon OS 6.x.y

How to play audio on Torizon OS using Alsa and C/C++

Introduction

In this article, we will show you how to play audio using Alsa (the Advanced Linux Sound Architecture) and C/C++ on Torizon OS.

Alsa is the Advanced Linux Sound Architecture, which is responsible to access input and output sound devices and it works based on client/server pattern, where the server-side is the Alsa driver inside Linux kernel space.

On Linux distributions for desktops (e.g. Ubuntu), we usually don't use Alsa directly because it can only support one client at a time, so we use PulseAudio, which can be seen as a layer between applications and Alsa and makes it possible to have more than one application using sound devices. Since an embedded system usually serves a single purpose, not using PulseAudio generally doesn't represent a limitation.

Prerequisites

tip

In case you want to learn more about C/C++ Development on Torizon, It's also recommended reading the C/C++ Development and Debugging on Torizon OS Using Visual Studio Code article.

Instructions

Creating the project

Here, using the Visual Studio Code Extension for Torizon OS, you will create a headless project for C/C++ for your module, based on CMake. You must choose between arm32 or arm64, depending on your module's architecture.

CMake-based project

Let's call out project alsa-example.

After creating the alsa-example project, create the folder alsa-example/appconfig_0/audio, download and place the audio file example Ryan Andersen - Faster! Faster! Faster!.wav (original MP3 from here, converted to WAVE file) .

Configuring the project

Now, to configure your project, you need to tackle both the application runtime perspective and application development perspective.

Runtime perspective

From the application perspective, you will need to make sure that the application will:

  • have access to the sound devices;
  • have access to the audio file.
  • have the necessary packages for its runtime;
  • have the audio file as an input argument (this is needed since your application will play the audio file defined by its input argument)
Making a device available to the application

To make the sound devices available, you need to add /dev/snd to the devices entry of the Torizon Tab.

Screenshot of /dev/snd added to devices entry on Torizon Tab

Making a file available to the application

To make the audio file accessible, you need to add COPY audio /audio to the targetfiles entry of the Torizon Tab. With this, the audio file Ryan Andersen - Faster! Faster! Faster!.wav will be placed on the root of the filesystem of your application, but of course, you can place it where it best fits for your needs.

Screenshot of COPY audio /audio added to devices entry on Torizon Tab

Making a package available to the application

To make the packages available to the application's runtime, you need to add libasound2 alsa-utils to the extrapackages entry of the Torizon Tab. This will make the libasound2 (so you can use the Alsa API) and alsa-utils (so you can easily make audio configurations) to be installed on your application's Docker image.

Screenshot of libasound2 alsa-utils added to extrapackages entry on Torizon Tab

Setting input argument for the application

To set the input argument for the application, you need to add "/audio/Ryan Andersen - Faster! Faster! Faster!.wav" to the arg entry of the Torizon Tab.

Screenshot of /audio/Ryan Andersen - Faster! Faster! Faster!.wav added to appargs entry on Torizon Tab

Development perspective

And, from the development perspective, you will need to make sure that your SDK will:

  • have access to the compile-time necessary packages
Making a package available for compile-time

To make the package available to the application's compile-time, you need to add the development package of libasound2, so it will be added to your application's SDK Docker image. To perform this. You would need to pay attention to your module's architecture since your application will be cross-compiled, but the Visual Studio Code Extension for Torizon makes available the platform.debian-arch variable available, so you can add to devpackages libasound2-dev:#%platform.debian-arch%#.

Screenshot of libasound2-dev:#%platform.debian-arch%# added to devpackages entry on Torizon Tab

Setting up the example project files

Now you will need to get some source files for this example.

Source main code

Substitute your alsa-example.cpp with this alsa-example.cpp from the github repository (if you used a name other than alsa-example for this project, you may have to rename this file accordingly)

CMakeLists file

Substitute your CMakeLists.txt with this CMakeLists.txt from the repository (if you used a name other than alsa-example for this project, you may have to rename this file accordingly).

Debugging options (optional)

On your .vscode/launch.json, change your stopAtEntry option to false, so the debugger will not place a breakpoint on the first line code.

Screenshot of stopAtEntry defined as false on .vscode/launch.json

Executing the application on the module

Now you can hit F5 to deploy your application-container to the module and, if you have your module/carrier board correctly connected to a sound system, you should listen to the Faster! Faster! Faster! from Ryan Andersen.

Remark: the original alsa-example.cpp is from here

tip

Despite this tutorial being designed for C/C++ applications, most of the contents here can be applied while developing a Python script for playing audio. Please contact us if you have any questions about it.



Send Feedback!