Reader small image

You're reading from  Hands-On Embedded Programming with C++17

Product typeBook
Published inJan 2019
Reading LevelIntermediate
PublisherPackt
ISBN-139781788629300
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Maya Posch
Maya Posch
author image
Maya Posch

Maya Posch is a senior C++ developer with more than 15 years of experience. Discovering the joys of programming early on, and later the joys of electronics, she has always expressed a profound interest in technology, a passion that she gladly shares with others. Describing herself as a C developer who happens to like C++ and Ada, she likes to seek the limits of what can be done with the minimum of code and hardware to accomplish everything that is cool, new, and exciting. She also enjoys FPGA development, AI, and robotics research, in addition to creative writing, music, and drawing.
Read more about Maya Posch

Right arrow

Chapter 8. Example - Linux-Based Infotainment System

This chapter provides an example of how to implement an infotainment system using a Linux-based single-board computer (SBC). It also shows how to connect to remote devices using Bluetooth, and how to use online streaming services. The resulting device will be able to play back audio from a variety of sources without a complex UI. In particular, we will be covering the following topics:

  • Developing for a Linux-based SBC
  • Using Bluetooth under Linux
  • Playing back audio from a variety of sources and recording audio
  • Using GPIO for both simple input and voice recognition
  • Connecting to online streaming audio services

One box that does everything


Infotainment systems have become a common feature in our daily lives, starting with in-car entertainment (ICE) systems (also known as In-Vehicle Infotainment or IVI), which evolved from the basic radios and cassette players to include features such as navigation and connecting to smartphones over Bluetooth for access to one's music library, and much more. Another big feature is to provide the driver with hands-free functionality so that they can start a phone call and control the radio without having to take their eyes off the road or their hands off the steering wheel.

 

As smartphones became more popular, providing their users with constant access to news, weather, and entertainment, the arrival of onboard assistants that use a voice-driven interface, both on smartphones and ICEs, ultimately led to the arrival of speech-driven infotainment systems aimed at in-home use. These usually consist of a speaker and microphone, along with the required hardware for the...

Hardware needed


For this project, any SBC that's capable of running Linux should work. It also needs to have the following features for a full implementation:

  • An internet connection (wireless or wired) to access online content.
  • Bluetooth functionality (built-in or as an add-on module) to allow the system to act as a Bluetooth speaker.
  • Free GPIO input to allow for buttons to be hooked up.
  • A functioning microphone input and audio output for the voice input and audio playback, respectively.
  • SATA connectivity or similar for connecting storage devices like hard-drives.
  • I2C bus peripheral for an I2C display.

For the example code in this chapter we only require the microphone input and audio output, along with some storage for local media files.

 

 

To the GPIO pins, we can connect a number of buttons that can be used to control the infotainment system without having to use the voice-activated system. This is convenient for situations where using the voice-activated system would be awkward, such as when...

Software requirements


For this project, we are assuming that Linux has been installed on the target SBC, and that the drivers for the hardware functionality, such as the microphone and audio output, have been installed and configured.

Since we use the Qt framework for this project, all dependencies there should be met as well. This means that the shared libraries should be present on the system on which the resulting binary for the project will be run. The Qt framework can be obtained via the package manager of the OS, or via the Qt website at http://qt.io/.

Note

In Chapter 10, Developing Embedded Systems with Qt, we will look at developing on embedded platforms with Qt in more detail. This chapter will briefly touch upon the use of Qt APIs.

Depending on whether we want to compile the application directly on the SBC or on our development PC, we might have to install the compiler toolchain and further dependencies on the SBC, or the cross-compiling toolchain for Linux on the target SBC (ARM,...

Bluetooth audio sources and sinks


Bluetooth is unfortunately a technology that, despite being ubiquitous, suffers from its proprietary nature. As a result, support for the full range of Bluetooth functionality (in the form of profiles) is lacking. The profile that we are interested in for this project is called Advanced Audio Distribution Profile (A2DP). This is the profile used by everything from Bluetooth headphones to Bluetooth speakers in order to stream audio.

Any device that implements A2DP can stream audio to an A2DP receiver or can themselves act as a receiver (depending on the BT stack implementation). Theoretically, this would allow someone to connect with a smartphone or similar device to our infotainment system and play back music on it, as they would with a standalone Bluetooth speaker.

A receiver in the A2DP profile is an A2DP sink, whereas the other side is the A2DP source. A Bluetooth headphone or speaker device would always be a sink device as they can only consume an audio...

Online streaming


There are a number of online streaming services which one could integrate into an infotainment system like the type which are looking at in this chapter. All of them use a similar streaming API (usually an HTTP-based REST API), which requires one to create an account with the service, using which one can obtain an application-specific token that gives one access to that API, allowing one to query it for specific artists, music tracks, albums, and so on.

Using an HTTP client, such as the one found in the Qt framework, it would be fairly easy to implement the necessary control flow. Due to the requirement of having a registered application ID for those streaming services, it was left out of the example code.

The basic sequence to stream from a REST API usually looks like this, with a simple wrapper class around the HTTP calls:

#include "soundFoo"
// Create a client object with your app credentials.
client = soundFoo.new('YOUR_CLIENT_ID');
// Fetch track to stream.
track = client...

Voice-driven user interface


This project employs a user interface that is fully controllable by voice commands. For this, it implements a voice-to-text interface powered by the PocketSphinx library (see https://cmusphinx.github.io/) that uses both keyword-spotting and a grammar search in order to recognize and interpret commands given to it.

We use the default US-English language model that comes with the PocketSphinx distribution. This means that any commands spoken should be pronounced with a US-English accent in order to be accurately understood. To change this, one can load a different language model aimed at different languages and accents. Various models are available via the PocketSphinx website, and it is possible to make one's own language model with some effort.

Usage scenarios


We don't want the infotainment system to be activated every single time that the voice user interface recognizes command words when they are not intended as such. The common way to prevent this from happening is by having a keyword that activates the command interface. If no command is recognized after the keyword within a certain amount of time, the system reverts to the keyword-spotting mode.

For this example project, we use the keyword computer. After the system spots this keyword, we can use the following commands:

Source code


This application has been implemented using the Qt framework, as a GUI application, so that we also get a graphical interface for ease of debugging. This debugging UI was designed using the Qt Designer of the Qt Creator IDE as a single UI file.

We start by creating an instance of the GUI application:

#include "mainwindow.h" 
#include <QApplication> 
 
int main(int argc, char *argv[]) { 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
     
    return a.exec(); 
} 

This creates an instance of the MainWindow class in which we have implemented the application, along with an instance of QApplication, which is a wrapper class used by the Qt framework.

Next, this is the MainWindow header:

#include <QMainWindow> 
 
#include <QAudioRecorder> 
#include <QAudioProbe> 
#include <QMediaPlayer> 
 
 
namespace Ui { 
    class MainWindow; 
} 
 
class MainWindow : public QMainWindow { 
    Q_OBJECT 
     
public: 
    explicit MainWindow(QWidget *parent...

Building the project


To build the project, the PocketSphinx project has to be built first. In the example project's source code that comes with this chapter, there are two Makefiles underneath the sphinx folder, one in the pocketsphinx folder and one in the sphinxbase folder. With these, the two libraries that form PocketSphinx will be built.

After this, one can build the Qt project, either from Qt Creator or from the command line, by executing the following command:

mkdir build
cd build
qmake ..
make

Extending the system


In addition to audio formats, one could also add the ability to play back videos and integrate the ability to make and respond to phone calls (using the Bluetooth API). One may want to extend the application to make it more flexible and modular, so that, for example, one could add a module that would add the voice commands and resulting actions.

Having voice output would be convenient as well, making it more aligned with the current commercial offerings. For this, one could use the text-to-speech API that's available in the Qt framework.

It would also be useful to add more information to the infotainment system by querying remote APIs for things such as the current weather, news updates, and maybe even running updates on a current football game. The voice-based UI could be used to set up timers and task reminders, integrate a calendar, and much more.

Finally, as can be seen in this chapter's example code, one cannot specify the name of the track that one wants to play,...

Summary


In this chapter, we looked at how one can fairly easily construct an SBC-based infotainment system, using voice-to-text to construct a voice-driven user interface. We also looked at ways that we could extend it to add even more functionality.

The reader is expected to be able to implement a similar system at this point, and to extend it to connect it to online and network-based services. The reader should also read up on the implementation of more advanced voice-driven user interfaces, the addition of text-to-speech, and the use of A2DP-based Bluetooth devices.

In the next chapter, we'll be taking a look at how to implement a building-wide monitoring and control system using microcontrollers and the local network.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Hands-On Embedded Programming with C++17
Published in: Jan 2019Publisher: PacktISBN-13: 9781788629300
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Maya Posch

Maya Posch is a senior C++ developer with more than 15 years of experience. Discovering the joys of programming early on, and later the joys of electronics, she has always expressed a profound interest in technology, a passion that she gladly shares with others. Describing herself as a C developer who happens to like C++ and Ada, she likes to seek the limits of what can be done with the minimum of code and hardware to accomplish everything that is cool, new, and exciting. She also enjoys FPGA development, AI, and robotics research, in addition to creative writing, music, and drawing.
Read more about Maya Posch

Command

Result

Play Bluetooth

Starts playing from any connected A2DP source device (unimplemented).

Stop Bluetooth

Stops playing from any Bluetooth device.

Play local

Plays the (hardcoded) local music file.

Stop local

Stops playing the local music file, if currently playing.

Play remote

Plays from an online streaming service or server (unimplemented).

Stop remote

Stops playing, if active.

Record message

Records a message. Records until a number of seconds of silence occurs...