Alexa Auto SDK System Audio Module¶
The System Audio
module provides the default audio capturing and playback functionality for macOS, Linux, and QNX.
What's Included¶
The System Audio
module contains the platform implementations of:
aace::audio::AudioOutput
andaace::audio::AudioOutputProvider
for audio playback capabilityaace::audio::AudioInput
andaace::audio::AudioInputProvider
for audio capturing capability
Supported Audio Backends¶
Currently the System Audio
module supports:
-
GStreamer tested on:
-
Ubuntu Linux (18.04 and 20.04)
Note: Ensure installing at least
gstreamer1.0-plugins-base
andgstreamer1.0-plugins-good
. It is recommended to installgstreamer1.0-plugins-bad
for playing content from Amazon Music (which uses HLS) and other Music Service Providers. Refer to https://gstreamer.freedesktop.org/documentation/installing/on-linux.html for instructions.Note: GStreamer on Poky Linux for iMX8 does not support Audible or Amazon Music playback.
-
Automotive Grade Linux with 4A framework support (FF or GG)
-
Poky Linux armv7hf and armv8
-
macOS x86_64 with GStreamer installed by Homebrew
-
-
OpenMAX AL (Encoded audio playback only) tested with:
- QNX Multimedia Suite 2.0 on QNX 7.0.0 armv8
-
QNX Sound Architecture (QSA) (Raw audio only) tested with:
-
QNX 7.0.0 armv8
Note: You'll need a QNX Multimedia Suite license to use OpenMAX AL, and both OpenMAX AL and QSA are required in order to enable full functionality on QNX.
-
Getting Started¶
Prerequisites¶
You'll need GStreamer development packages such as libgstreamer1.0-dev
and libgstreamer-plugins-base1.0-dev
.
Building the Alexa Auto SDK with the System Audio Module¶
The Alexa Auto SDK Builder Tool automatically includes the System Audio
module when you build the C++ sample app. You can include it explicitly by specifying -o aac_modules=aac-module-system-audio,...
to the build command.
Running the C++ Sample App with the Audio Configuration¶
When you run the C++ Sample App, a config-system-audio.json
file with default audio settings for Linux platforms is provided under shared/system-audio/config
.
Changing the Default Audio Settings for Linux (required for Poky 32)¶
If you need to modify the configuration defined in the config-system-audio.json
file for your Linux platform, follow these steps:
-
Edit the
config-system-audio.json
file (located in theaac-sdk/modules/system-audio/configs/linux
directory) as necessary.Note: For Poky 32 boards, you must set
"shared"
to"true"
in the"default"
node. -
Save the
config-system-audio.json
file to the same directory other config files reside. -
Include a
--config path/to/config-system-audio.json
line when you run the C++ Sample App.
Changing the Default Audio Settings for QNX (required)¶
The default audio settings will not work for QNX. To modify the configuration defined in the config-system-audio.json
file for your QNX platform, follow these steps:
- Edit the
config-system-audio.json
file (located in theaac-sdk/modules/system-audio/configs/neutrino
directory) as necessary. See the default QNX configuration for guidance. - Save the
config-system-audio.json
file to the same directory other config files reside. - Include a
--config /opt/AAC/etc/config-system-audio.json
line when you run the C++ Sample App.
Note: You may need to set the
AAL_CAPATH
system environment value to specify which path should OpenMAX AL used forCURLOPT_CAPATH
internally. If you don't set theAAL_CAPATH
system environment variable,/etc/ssl/certs
will be used by default.
Configuring System Audio¶
For complex audio setup, you may need to write your own config file. To use this file, save it as config-system-audio.json
and include a --config path/to/config-system-audio.json
line when you run the C++ Sample App.
Here is the config file template:
{
"aace.systemAudio": {
"<provider>": {
"enabled": {{BOOLEAN}},
"devices": {
"<device-name>": {
"module": "<module-name>",
"card": "<id>",
"rate": "<sample-rate>",
"shared": {{BOOLEAN}}
}
},
"types": {
"<type>": "<device-name>"
}
}
}
}
aace.systemAudio.<provider>
: Set toAudioInputProvider
orAudioOutputProvider
. You can write a configuration for each<provider>
, depending on the direction (input or output).aace.systemAudio.<provider>.enabled
: Set totrue
orfalse
. Setting this parameter tofalse
disables the registration of the<provider>
platform implementation. The default setting istrue
.aace.systemAudio.<provider>.devices.<device-name>
: Set to any"<device-name>"
or todefault
. If you set the"<device-name>"
to"default"
audio will be routed by default if there is no explicit"<device-name>
" available for the configured"<type>"
. You can configure multiple devices, depending on your platform."module"
: Specify a"<module-name>"
to explicitly define which audio backend to use. By default,"module"
is set to an empty string, which configures the system audio module to use whatever backend is available."card"
: Specify the card id for the specific audio backend you defined with the"<module-name>"
parameter. By default,"card"
is set to an empty string since by default"<module-name>"
is not defined."rate"
: Specify the sample rate of audio input. By default the"rate"
is set to0
."shared"
(AudioInputProvider only): Set totrue
orfalse
. Set"shared"
totrue
for Poky 32 boards or in cases where the device should be shared within the Auto SDK Engine; otherwise, the System Audio module will try to open the device for every audio input type. The"shared"
option is useful when the underlying backend doesn't support the input splitter. By default"shared"
is set tofalse
.
aace.systemAudio.<provider>.types.<type>
: Use the"type"
option to specify which device should be used for various types of audio. If you do not explicitly specify a device, thedefault
type is used. Seeaace::audio::AudioInputProvider::AudioInputType
andaace::audio::AudioOutputProvider::AudioOutputType
for the possible"<type>"
values.
Default QNX Configuration ¶
Here is the default configuration for QNX platforms:
{
"aace.systemAudio": {
"AudioInputProvider": {
"devices": {
"default": {
"module": "QSA",
"shared": true
}
}
},
"AudioOutputProvider": {
"devices": {
"default": {
"module": "OpenMAX AL"
},
"raw": {
"module": "QSA"
}
},
"types": {
"COMMUNICATION": "raw"
}
}
}
}
If you use this configuration:
- The audio capturing for all types will use
QSA
, but it will be shared. This means that only a single PCM channel will be opened by the Engine. - The audio playback for all types except
COMMUNICATION
will useOpenMAX AL
.COMMUNICATION
audio will useQSA
instead. Note that the multiple PCM channels will be opened for each types.
Linux Configuration Example¶
Here is a configuration example for Linux platforms:
{
"aace.systemAudio": {
"AudioInputProvider": {
"devices": {
"default": {
"module": "GStreamer"
},
"loopback": {
"module": "GStreamer",
"card": "hw:Loopback,1,0",
"shared": true
}
},
"types": {
"LOOPBACK": "loopback"
}
},
"AudioOutputProvider": {
"devices": {
"default": {
"module": "GStreamer"
}
}
}
}
}
The above example shows how you could provide "Speaker reference" into the engine.
Specifying Input and Output Device¶
The card
field specifies the audio input source and audio output sink.
For devices using module GStreamer
, the card
field can be one of the following values:
- If the
card
field is an empty string or not specified at all, the input device will be decided by GStreamerautoaudiosrc
plugin and the output device will be decided by GStreamerautoaudiosink
plugin automatically. - If the the
card
field starts withbin:
, the input and output device can be specified with a GStreamer bin description. For example, settingcard
of an audio input device tobin:udpsrc port=5000 caps=\"application/x-rtp,channels=(int)1,format=(string)S16LE,media=(string)audio,payload=(int)96,clock-rate=(int)16000,encoding-name=(string)L16\" ! rtpL16depay
will receive audio from local UDP port 5000. See Pipeline Description for details. - If the
card
field starts withelement:
, the input and output device can be specified with a GStreamer element. For example, settingcard
of an audio output device toelement:pulsesink
will deliver the output audio to the PulseAudio server. See Plugins for the list of GStreamer plugins. - If none of the above matches, the string will be treated as an Advanced Linux Sound Architecture (ALSA) device name. You can use
aplay -L
orarecord -L
to list available audio output and input devices.
One practical use of the card
field is to specify virtual audio input/output for the following devices:
- The target device does not have audio input/output hardware.
- The target device is remotely located.
Here is an example to use local microphone and speaker and run C++ sample app on a remote device:
- Local macOS/Linux device
- Deliver audio from local microphone to remote UDP port 5000 by running
gst-launch-1.0 -v autoaudiosrc ! "audio/x-raw, format=(string)S16LE, channels=(int)1, layout=(string)interleaved" ! audioresample ! audio/x-raw, rate=16000 ! audioconvert ! rtpL16pay ! udpsink host=your.remote.device port=5000
. - Build a reverse SSH tunnel by running
ssh -R 24713:localhost:4713 your.remote.device
. - Play audio output received from remote device by running
pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon
.
- Deliver audio from local microphone to remote UDP port 5000 by running
- Remote device
- Receive audio input from UDP port 5000 by specifying
card
of audio input device tobin:udpsrc port=5000 caps=\"application/x-rtp,channels=(int)1,format=(string)S16LE,media=(string)audio,payload=(int)96,clock-rate=(int)16000,encoding-name=(string)L16\" ! rtpL16depay
. - Send audio output to local device by specifying
card
of audio output device toelement:pulsesink
and exportPULSE_SERVER
environment variable totcp:localhost:24713
before running C++ sample app.
- Receive audio input from UDP port 5000 by specifying
Playlist URL Support¶
The System Audio module supports playback of playlist URL from media streaming services (such as TuneIn) based on PlaylistParser
provided by AVS Device SDK. The current supported formats include M3U and PLS. Note that only the first playable entry will be played in the current implementation. Choosing a variant based on stream information or continuing playback of the second or later entry is not supported right now.
After the user asks Alexa to play on TuneIn, if Alexa acknowledges the request but says TuneIn is not available, the parser displays the following error:
2021-03-02 05:04:25.745 [AVS] E PlaylistParser:doDepthFirstSearch:url=http\://www.podtrac.com/pts/redirect.mp3/chtbl.com/track/5899E/traffic.megaphone.fm/HSW1953246087.mp3:getHeaderFailed
To avoid this error, provide a valid cacert.pem
to CURLOPT_CAINFO
in the Auto SDK configuration. Download the cacert.pem
file from here.
"libcurlUtils": {
"CURLOPT_CAPATH": "/path/to/certs",
"CURLOPT_CAINFO": "/path/to/cacert.pem"
}