How to play audio on Torizon OS using Alsa and C/C++
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.
- Module with Torizon OS installed
- Visual Studio Code installed with Visual Studio Code Extention for Torizon
- Sound output connected to the module's audio output via its carrier board
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.
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.
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.
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.
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.
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.
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.
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
Setting up the example project files
Now you will need to get some source files for this example.
Source main code
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.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)
.vscode/launch.json, change your
stopAtEntry option to
false, so the debugger will not place a breakpoint on the first line code.
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
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.