In this chapter, USB peripherals are attached to the Beagle board so that it can be used for capturing image, video, and audio data using low-level Linux drivers and APIs. It describes Linux applications and tools that can be used to stream captured video and audio data to the internet. Open Source Computer Vision (OpenCV) image processing and computer vision approaches are investigated that enable the Beagle board to draw inferences from the information content of the captured image data. Capture and playback of audio streams are described, along with the use of Bluetooth audio. The chapter also covers some applications of audio on the Beagle board, including streaming audio, internet radio, and text-to-speech.
EQUIPMENT REQUIRED FOR THIS CHAPTER:
Further resources for this chapter are available at www.exploringbeaglebone.com/chapter14/
.
In this section, the Beagle board is used as a platform for capturing image and video data from USB webcams and saving the data on the board's file system. This is useful for Beagle board applications such as robotics, home security, home automation, and aeronautics, when networked image streaming is not an available option—for example, if the application is untethered and distant from a wireless network. With suitable peripherals, the board can be used to capture high-quality video streams, which can be viewed asynchronously. The durations of the video streams are limited only by the available storage on the board. (Chapter 3 describes an approach for mounting a high-capacity micro-SD card or USB memory device on the file system.) Alternatively, the video can be streamed to the network, which is discussed in the next section of this chapter.
The main focus in this section is USB webcams, as they are widely available and can be reused as a general-purpose desktop peripheral. The Logitech HD C270 ($26), HD C310 ($30), and HD Pro C920 ($70), shown in Figure 14-1, are chosen, as they are commonly available HD cameras that are known to function under Linux. In fact, for the following tests the three cameras are connected simultaneously to the Beagle board using the USB hub displayed in Chapter 1. It is not a powered USB hub, but the board is connected to a 5 V 2 A supply in this case.
When the three USB cameras are connected to the board at the same time using a USB hub, the “list USB devices” utility provides the following output:
debian@ebb:~$ lsusb
Bus 001 Device 002: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 005: ID 046d:081b Logitech, Inc. Webcam C310
The output lists the device IDs for the cameras, two USB sound adapters, and a Bluetooth adapter. The fact that “Logitech” is listed against the device IDs indicates that some level of Linux support is already present on the board for these devices. If this is not the case, then you will have to source proprietary Linux drivers from the webcam manufacturer. Typically, such drivers would be built and deployed on the board before the webcam could be used.
Full information about the modes that are available on the USB cameras can be displayed using the following:
debian@ebb:~$ lsusb -v | less
This command results in detailed and verbose output. In addition, the loadable kernel modules (LKMs) that are currently loaded against these peripherals can be listed using the following command:
debian@ebb:~$ lsmod
Module Size Used by
snd_usb_audio 184320 0
uvcvideo 90112 0
snd_hwdep 20480 1 snd_usb_audio
videobuf2_vmalloc 16384 1 uvcvideo
videobuf2_memops 16384 1 videobuf2_vmalloc
snd_rawmidi 32768 1 snd_usbmidi_lib
videobuf2_v4l2 24576 1 uvcvideo
videobuf2_core 45056 2 uvcvideo,videobuf2_v4l2 …
The uvcvideo
LKM supports UVC (USB video class) compliant devices, such as the webcam that is attached. The videobuf2_vmalloc
LKM is the memory allocator for the Video4Linux video buffer. If everything is working as expected, there should be new video and audio devices available, which can be listed using the following:
debian@ebb:~$ ls /dev/{vid,aud}*
/dev/audio /dev/audio2 /dev/video0 /dev/audio1 /dev/video2
/dev/audio3 /dev/video1
The device /dev/audio
is mapped to the HDMI audio device, which will appear only if the HDMI virtual cape is enabled. The other audio devices are mapped to USB audio adapters and USB webcams.
Video4Linux2 (V4L2) is a video capture driver framework that is tightly integrated with the Linux kernel and is supported by the uvcvideo
LKM. It provides drivers for video devices, such as webcams, PCI video capture cards, and TV (DVB-T/S) tuner cards/peripherals. V4L2 primarily supports video (and audio) devices through the following types of interfaces:
V4L2 provides support for many types of devices, and simply put, it is complex! In addition to supporting video input/output, the V4L2 API also has stubs for codec and video effect devices, which enable manipulation of the video stream data. The focus in this section is on the capture of video data from webcam devices using V4L2 by performing the following steps (not necessarily in this order):
The main source of documentation on V4L2 is available from www.kernel.org
at tiny.cc/beagle1402
, and the V4L2 API specification is available at tiny.cc/beagle1403
.
The first step is to install the V4L2 development libraries, abstraction layer, utilities, and a simple webcam application for V4L2-compatible devices. Always update the package lists to get information about the newest packages and their dependencies, before installing a system library:
debian@ebb:~$ sudo apt-get update
debian@ebb:~$ apt-cache search v4l2
libv4l-dev - Collection of video4linux support libraries..
Then, install the packages that are required for this section:
debian@ebb:~$ sudo apt-get install fswebcam
gpicview libav-tools libv4l-dev
The fswebcam application can then be used to test that the attached web camera is working correctly. It is a surprisingly powerful and easy-to-use application that is best used by writing a configuration file, as shown in Listing 14-1, which contains settings for choosing the device, capture resolution, output file type, and the addition of a title banner. It can even be used on a continuous loop by adding a loop
entry that specifies the time in seconds between frame captures.
The fswebcam application can be configured with these settings by passing it the configuration filename on execution:
…/chp14/fswebcam$ ls
fswebcam.conf
…/chp14/fswebcam$ sudo fswebcam -c fswebcam.conf
--- Opening /dev/video0… Trying source module v4l2…
/dev/video0 opened. --- Capturing frame… …
The image can then be viewed using gpicview
, which requires that you have attached a display to the Beagle board, such as a VNC connection:
…/chp14/fswebcam$ gpicview exploringBB.png
This will result in output like that in Figure 14-2(a). The image data has been modified to include a formatted bottom text banner, which contains a title and the date and time of image capture. Sample full-resolution capture images are available on the chapter web page.
Interestingly, the fswebcam application could be executed on a loop and combined with the Apache web server (as described in Chapter 11) to create a simple web camera, which uses a web page that links to the captured image file present on the Beagle board file system.
V4L2 provides a set of user-space utilities that can be used for obtaining information about connected V4L2-compatible devices. It is also possible to use the user-space utilities to change camera settings; however, it is possible that executed applications will be programmed to override such changes. The most important role of these tools is to verify that connected V4L2 devices are functioning correctly. You can list the available V4L2 devices using the following:
debian@ebb:~$ v4l2-ctl --list-devices
HD Pro Webcam C920 (usb-musb-hdrc.1-1): /dev/video0
The devices appear in the order in which they are attached to the USB hub. You can get information about a particular device by listing its modes (where -d 0
refers to the HD Pro C920 in this instance).
debian@ebb:~$ v4l2-ctl --all -d 0
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : HD Pro Webcam C920
Bus info : usb-musb-hdrc.1-1
Driver version: 4.14.54
Capabilities : 0x84200001 Video Capture Streaming
Certain controls can be used to configure a camera, which can be accessed using the --list-ctrls
option, as follows:
debian@ebb:~$ v4l2-ctl --list-ctrls -d 0
brightness (int) : min=0 max=255 step=1 default=128 value=128
contrast (int) : min=0 max=255 step=1 default=128 value=128
saturation (int) : min=0 max=255 step=1 default=128 value=128
white_balance_temperature_auto (bool) : default=1 value=1
gain (int) : min=0 max=255 step=1 default=0 value=255 …
For the C920, other controls include white balance, color temperature, sharpness, backlight compensation, exposure (auto or absolute), focus, zoom, and support for pan/tilt. For example, to change the brightness on device 0 to 100 (currently 128 as shown in the preceding snippet), you can use the following:
debian@ebb:~$ v4l2-ctl --set-ctrl=brightness=100 -d 0
debian@ebb:~$ v4l2-ctl --list-ctrls -d 0 | grep brightness
brightness (int) : min=0 max=255 step=1 default=128 value=100
You can also list the modes of the cameras. In this case, there are three different video capture pixel formats, with fourcc color space video codes: YUYV
(a common broadcast format with one luminance and two chrominance channels), H264
(a common modern interframe video compression format), and MJPG
(a common, but older, intraframe-only motion JPEG video compression format). The listing is obtained using the following:
debian@ebb:~$ v4l2-ctl --list-formats -d 0
ioctl: VIDIOC_ENUM_FMT
Index : 0 Type : Video Capture
Pixel Format: 'YUYV' Name : YUYV 4:2:2
Index : 1 Type : Video Capture
Pixel Format: 'H264' (compressed) Name : H.264
Index : 2 Type : Video Capture
Pixel Format: 'MJPG' (compressed) Name : Motion-JPEG
The C270 and C310 cameras do not have H.264 mode, but they both have YUYV
and MJPG
compressed pixel formats at indices 0
and 1
, respectively. It is possible to explicitly set the resolution and pixel format of a camera as follows:
~$ v4l2-ctl --set-fmt-video=width=1920,height=1080,pixelformat=1 -d 0
~$ v4l2-ctl --all -d 0
Driver Info (not using libv4l2):
Driver name : uvcvideo
Card type : HD Pro Webcam C920
Bus info : usb-musb-hdrc.1-1
Driver version: 4.14.54 …
Capabilities : 0x84000001 Video Capture Streaming
Format Video Capture:
Width/Height : 1920/1080 Pixel Format : 'H264'
Field : None Bytes per Line : 3840
Size Image : 4147200 Colorspace : SRGB
Crop Capability Video Capture:
Bounds : Left 0, Top 0, Width 1920, Height 1080
Default : Left 0, Top 0, Width 1920, Height 1080
Pixel Aspect : 1/1
Video input : 0 (Camera 1: ok)
Streaming Parameters Video Capture:
Capabilities : timeperframe Frames per second: 30.000 (30/1)
Read buffers : 0 Priority: 2
This output provides useful state information, such as the resolution, video frame image size, frame rate, and so on.
As with other devices in Linux (e.g., SPI in Chapter 8), it is possible to send data to and receive data from a video device by opening its /dev/videoX
file system entry by using a call to file open()
. Unfortunately, such an approach would not provide the level of control or performance that is required for video devices. Instead, low-level input/output control (ioctl()
) calls are required to configure the settings of the device, and memory map (mmap()
) calls are used to perform image frame memory copy, rather than using a byte-by-byte serial transfer.
The Git repository contains programs in the /chp14/v4l2/
directory that use V4L2 and its low-level ioctl()
calls to perform video frame capture and video capture tasks.
grabber.c
: Grabs raw image frame data from a webcam into memory using libv4l2. The images can be written to the file system.capture.c
: Grabs raw video data to a stream or file. It does this quickly enough to be used for real-time video capture.These code examples are almost entirely based on the samples that are provided by the V4L2 project team. The code is too long to display here, but you can view it in the Git repository. To build and execute the code examples, use the following steps:
~/exploringbb/chp14/v4l2$ sudo apt install libv4l-dev
…/chp14/v4l2$ ls *.c
capture.c grabber.c
…/chp14/v4l2$ gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` →
grabber.c -o grabber
…/chp14/v4l2$ gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` →
capture.c -o capture
…/chp14/v4l2$ ./grabber
…/chp14/v4l2$ ls *.ppm
grabber000.ppm grabber005.ppm grabber010.ppm grabber015.ppm …
…/chp14/v4l2$ gpicview grabber000.ppm
The .ppm
file format describes an uncompressed color image format, which gpicview will display. You can use the “forward” button on gpicview to step through the 20 image frames. To capture data using the capture.c
program, use a selection of the following options:
…/chp14/v4l2$ ./capture -h
Usage: ./capture [options]
Version 1.3 Options:
-d | --device name Video device name [/dev/video0] …
-f | --format Force format to 640x480 YUYV
-F | --formatH264 Force format to 1920x1080 H264
-c | --count Number of frames to grab [100] - use 0 for infinite
Example usage: capture -F -o -c 300 > output.raw
Captures 300 frames of H264 at 1920x1080. Use raw2mpg4 script to convert to mpg4
If you have the C920 camera, you can capture 100 frames of H.264 data using the first of the following commands. A second command then converts the .raw
file to a .mp4
file format, which can be played on a desktop machine.
…/chp14/v4l2$ ./capture -d /dev/video0 -F -o -c 100 > output.raw
Force Format 2
…………………………………………………………….
…/chp14/v4l2$ avconv -f h264 -i output.raw -vcodec copy output.mp4
…/chp14/v4l2$ ls -l output*
-rw-r--r-- 1 debian debian 1355695 Sep 3 22:23 output.mp4
-rw-r--r-- 1 debian debian 1353801 Sep 3 22:23 output.raw
The file sizes are almost identical because the video data is actually captured in a raw H.264 format. The conversion is performed using the avconv
(Libav) utility, which is a fork of the FFmpeg project that is well supported by the Debian Linux distribution. The -vcodec copy
option enables the video to be copied without transcoding the video data format.
The capture.c
program can also be used with cameras such as the C270 and C310, which do not have hardware H.264 functionality; however, the capabilities are more limited.
…$ v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=1 -d 1
…$ v4l2-ctl --all -d 1
Format Video Capture: Width/Height:1280/720 Pixel Format:'MJPG'
…/chp14/v4l2$ ./capture -d /dev/video1 -o -c 100 > output.raw
Force Format 0 ………………………………………………
…/chp14/v4l2$ ls -l output.raw
-rw-r--r-- 1 debian debian 4476448 Sep 3 01:58 output.raw
…/chp14/v4l2$ avconv -f mjpeg -i output.raw output.mp4
…/chp14/v4l2$ ls -l output.mp4
-rw-r--r-- 1 debian debian 1456040 Sep 3 02:06 output.mp4
True video conversion using avconv can take quite some time on the Beagle board! In this example, you can see that the H.264 video file requires significantly less space than the MJPEG file, as it is a more efficient interframe video-encoding format.
It is possible to use a Beagle board to capture and stream live video. The Logitech C920 is particularly useful for this purpose, as it has a built-in H.264 hardware encoder. The raw 1080p H.264 data can be passed directly from the camera stream to the network stream without transcoding, which means that the computational load on the Beagle board is reasonably low. Streaming scripts are available in the /chp14/v4l2/
repository directory. For example, Listing 14-2 provides a script for sending H.264 video data over UDP to a desktop PC at 192.168.7.1 using the C920 webcam.
This script pipes the raw video output from the capture program to the avconv application, which “copies” the raw data to the network stream using RTP. There is an additional script to multicast the video stream to multiple network points (streamVideoMulti
) using the broadcast network address 226.0.0.1
. A full video on my YouTube channel describes the steps involved in detail: tiny.cc/beagle1404
.
You can execute this script directly, but you must also copy the text highlighted here from its output and paste it into a new text file (you can name this new file stream.sdp
) and place it on your host machine.
debian@ebb:~/exploringbb/chp14/v4l2$ ./streamVideo
Frame rate set to 15.000 fps
Force Format 2 …
Output #0, rtp, to 'rtp://192.168.7.1:8090/':
Metadata:
encoder : Lavf57.56.101
Stream #0:0: Video: h264 (Constrained Baseline), yuvj420p(pc, prog),
1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 30 fps, 30 tbr, 90k tbn, 30 tbc
SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 192.168.7.1
t=0 0
a=tool:libavformat 57.56.101
m=video 8090 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-
sets=Z0JAKLtAPAES8uAokAAAAwAQAAADA8YEAALcbAAtx73vheEQjUA=,aM44gA==;
profile-level-id=424028
Stream mapping:
Stream #0:0 -> #0:0 (copy)…
frame= 1120 fps= 34 q=-1.0 Lsize=13901kB … bitrate=3052.5kbits/s
video:13756kB audio:0kB subtitle:0kB other streams:0kB …
You can then open this file stream.sdp
using a media player such as VLC, whereupon you will see a live video stream from the Beagle board on which the streamVideo
script is executed.
It is possible to build a custom Qt application that can receive the video stream on a desktop computer. This can be combined with the Qt client/server applications in Chapter 11 to provide network control and support for video streaming. Further details are available at tiny.cc/beagle1405
.
A second Beagle board can be used to receive the network video stream; however, it does not have sufficient capability to render the HD video stream to a display in real time. Interestingly, it is possible to use a Raspberry Pi 2/3 to capture the UDP stream and display it using a video player that takes advantage of the Raspberry Pi's H.264 hardware decoder. For example, the OMXplayer supports hardware decoding, and it can be used to open the network broadcast stream using the following:
molloyd@raspberryPI$ omxplayer -o hdmi udp://226.0.0.1:123
The Raspberry Pi can decode the C920 video stream and display it live on a monitor, albeit with a varying degree of latency.
Once a USB camera or camera cape is attached to the Beagle board, it is possible to capture images and process them using a comprehensive high-level library called Open Source Computer Vision (OpenCV). OpenCV (www.opencv.org
) provides a cross-platform library of functions for computer vision, such as gesture recognition, motion understanding, motion tracking, augmented reality, and structure-from-motion. It also provides supporting libraries for applications such as artificial neural networks, support vector machines, classification, and decision tree learning. OpenCV is written in C/C++ and is optimized for real-time applications, including support for multicore programming. The OpenCV libraries can be installed using this:
debian@ebb ~ $ sudo apt install libopencv-dev
OpenCV supports V4L2 and provides a high-level interface for capturing image data, which can be used instead of the grabber.c
program. Listing 14-3 is an OpenCV application that captures data from a webcam and filters it using some simple image processing techniques. The steps that it performs are as follows:
OpenCV uses a file-naming convention whereby an .hpp
file extension is used for header files that contain C++ code. This convention enables a C version of a header file (e.g., opencv.h
) to coexist alongside a C++ header file (e.g., opencv.hpp
). Because OpenCV mixes both C and C++ code, this is an appropriate way to distinguish one form from the other.
This example can be built and executed as follows, which results in the output displayed in Figure 14-3:
…/chp14/openCV$ g++ -O2 `pkg-config --cflags --libs opencv` →
boneCV.cpp -o boneCV
…/chp14/openCV$ ./boneCV
Started Processing - Capturing Image
Processing - Performing Image Processing
Finished Processing - Saving images
…/chp14/openCV$ ls *.png
capture.png edges.png grayscale.png
…/chp14/openCV$ gpicview capture.png
…/chp14/openCV$ gpicview edges.png
A second example application in the same directory can be used to test the performance of using OpenCV for image processing. In each iteration, it performs an image capture at a 640 × 480 resolution, converts the image to grayscale form, and performs an edge detection operation. The program performs 100 iterations, after which the execution time is measured.
debian@ebb:~/exploringbb/chp14/openCV$ ./boneCVtiming
It took 12.3263 seconds to process 100 frames
Capturing and processing 8.11274 frames per second
During this test the application uses 95 percent of CPU and 6 percent of memory capacity.
Image processing involves manipulating images by filters (e.g., smoothing, contrast enhancement) or transformations (e.g., scaling, rotation, stretching) for purposes such as enhancing or even reducing the information content of digital images. Image processing is one tool that is used in computer vision, which often has the goal of “understanding” the information content within digital images.
Computer vision applications often try to replicate the capabilities of human vision by drawing inferences, making decisions, and taking actions based on visual data. For example, the OpenCV application described in this section uses the BeagleBone to process image data and apply computer vision techniques to determine whether a human face is present in a webcam image frame or an image file. Importantly, the approach is designed for face detection, not face recognition. Face detection can be used for applications such as security and photography; however, the processing required has a significant computational overhead and is not suitable for high frame rates on a Beagle board.
Listing 14-4 provides an example computer vision application that uses OpenCV for face detection. It uses a Harr feature-based cascade classifier, which uses a characterization of adjacent rectangular image regions to identify regions of interest—for example, in human faces the region near the eyes has a darker intensity than the region containing the cheeks. Human faces can be detected using such observations. Usefully, OpenCV provides some codified rules for detecting human faces, which have been used in this example.
Computer vision is an entire research domain, and it requires a significant time investment before you will be able to perform some of its more complex operations. The “Further Reading” section provides links to resources to get you started.
The face detection example can be built and executed using the following commands:
…/chp14/openCV$ g++ -O2 `pkg-config --cflags --libs opencv` face.cpp -o face
…/chp14/openCV$ ./face
Starting face detection application
Capturing from the webcam
Successfully captured a frame.
Face at: (697,470) Face at: (470,152) Face at: (82,192) Face at: (966,296)
…/chp14/openCV$ ./face Lena.png
Starting face detection application
Loading the image Lena.png
Face at: (217,201)
When executed, it results in the display of the image in Figure 14-4(a) (if an X Window session is configured), with ellipses identifying any faces that are detected in the image.
There is a myriad of OpenCV3 examples available in the source code repositories and at tiny.cc/beagle1408
. The examples can be built and executed on the Beagle board as follows:
…/chp14/openCV3$ g++ -O2 `pkg-config --cflags --libs opencv` edge.cpp -o edge
…/chp14/openCV3$ ls
build edge edge.cpp fruits.jpg
…/chp14/openCV3$ ./edge fruits.jpg
This directly results in the interactive threshold edge detection windows in Figure 14-4(b).
Similar to OpenCV, Boost (www.boost.org
) provides a comprehensive free library of C++ source code that can be used for many applications on the Beagle board. There are libraries for multithreading, data structures, algorithms, regular expressions, memory management, mathematics, and more. The range of libraries available is too exhaustive to detail here, but a full listing is available at www.boost.org/doc/libs/
. Boost can be installed on the board using the following:
debian@ebb:~$ sudo apt install libboost-dev
… Unpacking libboost-dev:armhf (1.62.0.1) …
Listing 14-5 provides an example of usage of the Boost library for calculating the geometric distance between two 2-D points.
Similarly to OpenCV, it utilizes an .hpp
extension form. It also makes extensive use of C++ namespaces. The preceding code can be built and executed using the following:
debian@ebb:~/exploringbb/chp14/boost$ g++ testBoost.cpp -o testBoost
debian@ebb:~/exploringbb/chp14/boost$ ./testBoost
Distance between points is: 2.82843
There are several approaches to utilizing audio inputs and outputs with Beagle boards, including the following:
It is also possible to use the built-in ADC inputs to capture audio events at low sample rates. For example, the SparkFun electret microphone breakout board (BOB-09964) can be connected via an op-amp circuit to the Beagle board ADC (with a 10 kΩ potentiometer on the GND line) and used for tasks such as impact detection (e.g., a door knock). The sample rate of such a microphone circuit could be improved by using an external ADC that has an SPI interface, such as the low-cost ($3) MCP3008, which has eight 10-bit ADCs. In addition, the TI ADS8326 16-bit 250 kS/s SPI out could be interfaced to the PRU-ICSS, which is described in Chapter 15.
In this section, the most common approaches are examined, as is software that enables you to perform basic audio input/output tasks.
The following tools are used in this section of the book:
aplay
/arecord
utilities for the playback and recording of audio streams, the amixer
tool for controlling volume levels, and the speaker-test
utility.avconv
is a fast video and audio conversion tool that can also be used to capture audio data from devices or to stream data to the network (see libav.org/avconv.html
).To install these tools, ensure that your package lists are up-to-date and install the tools as follows:
debian@ebb:~$ sudo apt-get update
debian@ebb:~$ sudo apt-get install mplayer alsa-utils libav-tools
After you have the core software installed, the next step is to utilize an audio device that is connected to a Beagle board. In this section, an example is used in which several audio devices are attached simultaneously to the Beagle board—the HDMI audio interface, a webcam, and two USB audio adapters. Remember that the HDMI virtual cape must be enabled to utilize the HDMI audio output.
Figure 14-5(a) illustrates the USB hub with three USB devices attached—the two USB audio adapters and the Bluetooth adapter. When the three webcams are also attached to the Velleman USB hub, then a call to lsusb
results in the following:
Linux ebb 4.14.54-ti-rt-r63 #1 SMP PREEMPT RT …
debian@ebb:~$ lsusb
Bus 001 Device 005: ID 0d8c:013c C-Media Elec CM108 Audio Controller
Bus 001 Device 004: ID 041e:30d3 Creative Tech, Sound Blaster Play!
Bus 001 Device 006: ID 0a5c:2198 Broadcom Corp. Bluetooth 3.0 Device
Bus 001 Device 003: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
Bus 001 Device 002: ID 1a40:0201 Terminus TechFE 2.1 7-port Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The USB hub in Figure 14-5(a) is not a powered hub; however, the board is powered via the 5V connector using a 2 A power supply, which provides sufficient power to use all these devices simultaneously. The Sound Blaster ($20) and Dynamode ($5) USB adapters are illustrated in Figure 14-5(b) and (c), respectively. These adapters can be hot-plugged into the board, where their LKMs can be dynamically loaded and unloaded during Linux execution.
When the various adapters are connected to the Beagle board, you can obtain information about them as follows:
debian@ebb:~$ cat /proc/asound/pcm
00-00: davinci-mcasp.0-i2s-hifi i2s-hifi-0 : : playback 1
01-00: USB Audio : USB Audio : capture 1
02-00: USB Audio : USB Audio : playback 1 : capture 1
03-00: USB Audio : USB Audio : playback 1 : capture 1
In this case, the HDMI adapter is capable of playback only, the two USB adapters are capable of playback and capture, and the USB webcam is capable only of capture. An alternative approach is to use the aplay
utility to list the available playback devices.
debian@ebb:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Black [TI BeagleBone Black], device 0: davinci-mcasp.0-i2s-hifi …
Subdevices: 0/1
Subdevice #0: subdevice #0
card 2: U0x41e0x30d3 [USB Device 0x41e:0x30d3], device 0: USB Audio …
Subdevices: 0/1
Subdevice #0: subdevice #0
card 3: Device [USB PnP Sound Device], device 0: USB Audio …
Subdevices: 0/1
Subdevice #0: subdevice #0
Once you have identified the devices, you can play back an audio file on the Dynamode and Creative Sound Blaster USB adapters, respectively, using the mplayer
and aplay
utilities, as follows:
…/chp14/audio$ mplayer -ao alsa:device=hw=2 320sample.mp3
…/chp14/audio$ mplayer -ao alsa:device=hw=3 320sample.mp3
…/chp14/audio$ aplay -D plughw:2,0 cheering.wav
The sound quality is audibly richer on the Sound Blaster adapter (card 2) than the Dynamode adapter (card 3). However, the quality of the Dynamode adapter is good for its price, and its manual volume control feature is useful.
The HDMI device adapter can also be used, either by connecting a Beagle board directly to an HDMI receiver or HDMI television (or a monitor with built-in speakers) or by using a VGA adapter to extract the HDMI audio channel to a 3.5 mm stereo audio jack. The quality of the audio that is extracted from the latter devices can be quite variable and can suffer from auto-gain line noise when no audio stream is being played back.
To test an output device, you can use the speaker-test
utility (where -c2
indicates two channels are to be tested).
../chp14/audio$ speaker-test -D plughw:2,0 -c2
The ALSA utilities also provide you with detailed information about the capabilities of a USB device. For example, amixer
can be used to get and set an adapter's available properties. Using amixer
on the Sound Blaster device provides its current state information:
debian@ebb:~/exploringbb/chp14/audio$ amixer -c 2
Simple mixer control 'Speaker',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 151
Mono: Front Left: Playback 44 [29%] [-20.13dB] [on]
Front Right: Playback 44 [29%] [-20.13dB] [on]
Simple mixer control 'Mic',0
Capabilities: pvolume pvolume-joined cvolume cvolume-joined pswitch
pswitch-joined cswitch cswitch-joined
Playback channels: Mono Capture channels: Mono
Limits: Playback 0 - 32 Capture 0 - 16
Mono: Playback 23 [72%] [34.36dB] [off] Capture 0 [0%] [0.00dB] [on]
Simple mixer control 'Auto Gain Control',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono Mono: Playback [on]
To get its available control settings, use the following:
debian@ebb:~/exploringbb/chp14/audio$ amixer -c 2 controls
numid=3,iface=MIXER,name='Mic Playback Switch'
numid=4,iface=MIXER,name='Mic Playback Volume'
numid=7,iface=MIXER,name='Mic Capture Switch'
numid=8,iface=MIXER,name='Mic Capture Volume' …
Therefore, to control the Speaker Playback Volume setting, you can use this:
…$ amixer -c 2 cset iface=MIXER,name='Speaker Playback Volume' 10,10
numid=6,iface=MIXER,name='Speaker Playback Volume'
; type=INTEGER,access=rw---R--,values=2,min=0,max=151,step=0
: values=10,10 | dBminmax-min=-28.37dB,max=-0.06dB
This adjusts the volume on the speaker output of the Sound Blaster USB card—the 10,10
values are the left and right volume percentage settings, so 0,30
would turn off the left channel and set the volume level at 30 percent for the right channel.
You can play internet radio channels using the same mplayer
application. For example, by using www.internet-radio.com
, you can search for a radio station of your preference to determine its IP address. You can then stream the audio to your USB adapter using the following:
…/chp14/audio$ mplayer -ao alsa:device=hw=2 http://178.18.137.246:80
MPlayer 1.3.0 (Debian), built with gcc-6.2.1 (C) 2000-2016 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.
Playing http://178.18.137.246:80.
Resolving 178.18.137.246 for AF_INET6…
Couldn't resolve name for AF_INET6: 178.18.137.246
Connecting to server 178.18.137.246[178.18.137.246]: 80…
Name : Pinguin Radio Genre : Alternative
Website: http://www.pinguinradio.com
Public : yes Bitrate: 320kbit/s
Cache size set to 320 Kbytes Cache fill: 0.00% (0 bytes)
ICY Info: StreamTitle='Placebo & David Bowie - Without You I'm Nothing
';StreamUrl='http://www.pinguinradio.com'; …
This stream runs at 10 percent CPU and 5 percent memory usage on a BBB with good sound quality (regardless of what you might think of the music itself!). In fact, with multiple sound output devices, there is no difficulty in configuring a Beagle board to connect to multiple internet radio streams simultaneously and streaming audio to separate audio adapters.
The USB adapters and the USB webcams can be used to capture audio directly to the Beagle board file system. You can use the arecord
utility to provide a list of the available devices—for example, with one webcam and the two USB audio adapters connected:
debian@ebb:~$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: C920 [HD Pro Webcam C920], device 0: USB Audio [USB Audio]
Subdevices: 1/1 Subdevice #0: subdevice #0
card 2: U0x41e0x30d3 [USB Device 0x41e:0x30d3], device 0: USB Audio …
Subdevices: 1/1 Subdevice #0: subdevice #0
card 3: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1 Subdevice #0: subdevice #0
These devices are also indexed at the following /proc
location:
debian@ebb:~$ cat /proc/asound/cards
0 [Black ]: TI_BeagleBone_B - TI BeagleBone Black
1 [C920 ]: USB-Audio - HD Pro Webcam C920
2 [U0x41e0x30d3 ]: USB-Audio - USB Device 0x41e:0x30d3
3 [Device ]: USB-Audio - USB PnP Sound Device
You can record audio from each of the audio capture devices using the arecord
utility and the device's address. Interestingly, the LED does not light on the webcams described when they are recording only audio!
debian@ebb:~/tmp$ arecord -f cd -D plughw:2,0 -d 20 test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz
The waveform audio file format (WAV) stores uncompressed audio data, which will quickly consume your file storage free space. To avoid this, you can compress WAV files into the popular MP3 compressed format using the LAME MP3 encoder, as follows:
debian@ebb:~$ sudo apt install lame
debian@ebb:/tmp$ lame test.wav output.mp3
LAME 3.99.5 32bits (http://lame.sf.net)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding test.wav to output.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3
Frame | CPU time/estim | REAL time/estim | play/CPU | ETA
767/767(100%)| 0:09/ 0:09| 0:09/ 0:09| 2.1909x| 0:00
A recording test was performed on the BBB that uses each of the two USB adapters. A Zoom H1 Handy Recorder (www.zoom.co.jp
) was used to capture my voice. The analog stereo line output of the Zoom H1 was connected to the analog stereo line in of each adapter, and the following steps were used to record the audio for each adapter:
…/audio/testMicrophone$ arecord -f cd -D plughw:2,0 -d 45 testX.wav
…/chp14/audio/testMicrophone$ lame -b 128 testX.wav testX.mp3
A digital copy of the audio (i.e., digitally copied off the Zoom H1) is also provided in the Git repository for comparison. All three files are encoded at a sampling rate of 44.1 kS/sec with a bit rate of 128 Kb/sec. You can play these files directly on your desktop computer using the address tiny.cc/beagle1407
.
…/chp14/audio/testMicrophone$ ls
ZoomH1DigitalSource.mp3 testCreative.mp3 testDynamode.mp3
Line noise is audible in both versions when compared to the original digital audio data, but there is not a significant difference in the quality of the audio recording from each USB audio adapter.
Earlier in this chapter, a description is provided of video streaming to the network using avconv
. It is also possible to use the same application to stream audio as it is captured by an audio device, live to the network. For example, here is the command required to stream audio from a device attached to the address 2,0
using UDP to a desktop computer (at 192.168.7.1):
debian@ebb:/tmp$ avconv -ac 1 -f alsa -i hw:2,0 -acodec libmp3lame →
-ab 32k -ac 1 -f mp3 udp://192.168.7.1:12345
ffmpeg version 3.2.12-1~deb9u1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516 …
Guessed Channel Layout for Input Stream #0.0 : mono
Input #0, alsa, from 'hw:2,0':
Duration: N/A, start: 1536103924.360745, bitrate: 768 kb/s
Stream #0:0: Audio: pcm_s16le, 48000 Hz, mono, s16, 768 kb/s
Output #0, mp3, to 'udp://192.168.7.1:12345':
Metadata: TSSE : Lavf57.56.101
Stream #0:0: Audio: mp3 (libmp3lame), 48000 Hz, mono, s16p, 32 kb/s
Metadata: encoder : Lavc57.64.101 libmp3lame
Stream mapping: Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
size= 73kB time=00:00:18.52 bitrate= 32.1kbits/s speed=0.993x
A desktop player such as VLC can be used to open the network UDP stream. For example, in VLC use Media → Open Network Stream and set the network URL to be: udp://@:12345
.
The use of a Bluetooth adapter is first introduced in Chapter 12 for general-purpose serial communication. It is used again in Chapter 13 to attach peripherals to the BBB. Here again, Bluetooth can be used with a Beagle board—this time to communicate with audio devices.
One of the most common uses of the Bluetooth wireless communication system is for the connection of smartphones to in-car audio systems or to home entertainment centers. For this purpose, the Bluetooth Advanced Audio Distribution Profile (A2DP) can be used to stream high-quality stereo audio from a media source to a media sink. The source device (SRC) acts as the source of a digital audio stream (e.g., Bluetooth headset, smartphone media player), which is sent in a compressed format to a sink device (SNK) (e.g., Bluetooth headphones, stereo receiver, in-car receiver).
When connected to a USB Bluetooth adapter, the Beagle board can be configured to act as an A2DP SRC or SNK. In this example, the board is configured as the SRC that is connected to a Hi-Fi system and Windows PC SNK. There are many low-cost A2DP audio receivers available that provide audio output on a 3.5 mm stereo jack, which can be used to retrospectively add A2DP capability to Hi-Fi systems. However, the Sony Hi-Fi system that is used as the test platform has built-in A2DP support.
After a Bluetooth adapter is attached to the board, the first step is to install the necessary packages, configure it to support A2DP, and test that the Bluetooth audio SNKs are visible.
debian@ebb:~$ hcitool scan
Scanning … 40:E2:30:13:CA:09 HOMEOFFICE-PC
00:1D:BA:2E:BC:36 CMT-HX90BTR
00:21:04:F9:35:8E S68H
The board has detected the desktop PC, a Samsung device, and the Sony Hi-Fi system (CMT-HX90BTR).
An additional Linux service called PulseAudio, a background process that reroutes all audio streams, is required for recent A2DP services. It aims to support legacy devices, as well as to provide support for network audio (e.g., for VNC). PulseAudio is installed by default on the latest BeagleBoard.org Debian images. It provides useful user-interface tools, such as pavucontrol, which can be installed using the following:
debian@ebb:~$ sudo apt install pulseaudio pavucontrol →
pulseaudio-module-bluetooth
debian@ebb:~$ pulseaudio --version
pulseaudio 10.0
debian@ebb:~$ pulseaudio --dump-modules
PulseAudio can be configured as follows:
debian@ebb:/etc/pulse$ sudo nano default.pa
The service can be started and stopped using the following (note: no sudo
):
debian@ebb:~$ pulseaudio --kill
debian@ebb:~$ pulseaudio --start
One of the best ways to debug problems with PulseAudio is to kill the service and start the service using pulseaudio -v
to get a verbose output.
Once you have ensure that PulseAudio is working correctly, you can execute it in daemon mode and begin the process of pairing the board with the Bluetooth device.
debian@ebb:~$ pulseaudio -D
debian@ebb:~$ sudo bluetoothctl
[bluetooth]# scan on
Discovery started …
[CHG] Device 00:1D:BA:2E:BC:36 Name: CMT-HX90BTR
[CHG] Device 00:1D:BA:2E:BC:36 Alias: CMT-HX90BTR
[CHG] Device 00:1D:BA:2E:BC:36 LegacyPairing: yes
You can then connect to the SNKs using the following commands (you will likely have to enter a code [e.g., 0000] on both devices to pair the devices in the first step):
[bluetooth]# pair 00:1D:BA:2E:BC:36
Attempting to pair with 00:1D:BA:2E:BC:36
[CHG] Device 00:1D:BA:2E:BC:36 Connected: yes
[CHG] Device 00:1D:BA:2E:BC:36 Paired: yes
[bluetooth]# trust 00:1D:BA:2E:BC:36
[CHG] Device 00:1D:BA:2E:BC:36 Trusted: yes
Changing 00:1D:BA:2E:BC:36 trust succeeded
[bluetooth]# paired-devices
Device 00:1D:BA:2E:BC:36 CMT-HX90BTR
[bluetooth]# info 00:1D:BA:2E:BC:36
Device 00:1D:BA:2E:BC:36
Name: CMT-HX90BTR Alias: CMT-HX90BTR
Class: 0x240428 Icon: audio-card
Paired: yes Trusted: yes
Blocked: no Connected: no
LegacyPairing: yes UUID: Audio Sink …
[bluetooth]# connect 00:1D:BA:2E:BC:36
Attempting to connect to 00:1D:BA:2E:BC:36
[CHG] Device 00:1D:BA:2E:BC:36 Connected: yes
Connection successful
Now if you use the PulseAudio sound configuration tool, pacmd
, you can see that the Bluetooth device is now available as a sound sink.
debian@ebb:~$ pacmd
Welcome to PulseAudio 10.0! Use "help" for usage information.
>>> list-sinks
3 sink(s) available …
index: 2 name: <bluez_sink.00_1D_BA_2E_BC_36> …
>>> set-default-sink 2
You can then play audio files to the Bluetooth device by using PulseAudio as the device.
debian@ebb:~/exploringbb/chp14/audio$ aplay -D pulse cheering.wav
Playing WAVE 'cheering.wav' : Unsigned 8 bit, Rate 11025 Hz, Mono
Once you have a working playback adapter connected to your Beagle board, you can then utilize Linux tools and online services to perform some interesting audio applications. One such application is text-to-speech (TTS)—it is possible to generate audio from text using tools such as eSpeak, FestVox Festival, and pico2wave. Currently, pico2wave must be built from source, but eSpeak and Festival are available in binary form in the Debian distribution.
You can install and get eSpeak to output audio to the aplay application as follows:
debian@ebb:~$ sudo apt install espeak
debian@ebb:~$ espeak "Hello Pocket Beagle" --stdout | aplay -D plughw:2,0
Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 22050 Hz, Mono
You can install Festival and use it to output a text file to a WAV format file as follows:
debian@ebb:~$ sudo apt install festival festival-freebsoft-utils
debian@ebb:~$ nano hello.txt
debian@ebb:~$ more hello.txt
Hello Pocket Beagle
debian@ebb:~$ text2wave hello.txt -o hello.wav
debian@ebb:~$ ls -l *.wav
-rw-r--r-- 1 debian debian 52528 Sep 5 02:05 hello.wav
debian@ebb:~$ aplay -D plughw:2,0 hello.wav
Playing WAVE 'hello.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
Text can be piped to the text2wave
application as follows:
debian@ebb:~$ echo 'Hello Beagle' | text2wave -o test.wav
debian@ebb:~$ aplay -D plughw:2,0 test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
TTS engines can be integrated into your own applications. For example, you can use the output from a binary application as follows for the date application to provide dynamic speech output:
debian@ebb:~$ echo $(date +"It is %M minutes past %l %p") | →
text2wave -o test.wav
debian@ebb:~$ aplay -D plughw:2,0 test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
debian@ebb:~$ lame test.wav test.mp3
debian@ebb:~$ mplayer -ao alsa:device=hw=2 test.mp3
debian@ebb:~$ ls -l test*
-rw-r--r-- 1 debian debian 7992 Sep 5 02:09 test.mp3
-rw-r--r-- 1 debian debian 0 Apr 5 01:46 test.txt
-rw-r--r-- 1 debian debian 81966 Sep 5 02:08 test.wav
Finally, it is also possible to install the CMU Sphinx Speech Recognition Toolkit on the Beagle board. Open-source speech recognition tools are notoriously difficult to train when compared to commercial offerings such as Nuance's Dragon NaturallySpeaking. However, with some time investment, PocketSphinx can be trained to provide good results.
After completing this chapter, you should be able to do the following:
There are many links to websites and documents provided throughout this chapter. Additional links and further information on the topics are provided at www.exploringbeaglebone.com/chapter14/
and the following:
tiny.cc/beagle1402
tiny.cc/beagle1403
theboostcpplibraries.com
tiny.cc/beagle1409
tiny.cc/beagle1410
3.14.15.94