blob: f099b303d37fc0be7943ceb76d2b79dd01cc6506 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
\documentclass{report}
\author{xengineering}
\title{soundbox documentation}
\usepackage{graphicx}
\graphicspath{ {./diagrams/} }
\usepackage{hyperref}
\usepackage{parskip}
\begin{document}
\maketitle
\newpage
\tableofcontents
\newpage
\listoffigures
\newpage
\chapter{Introduction}
\label{chap:introduction}
\texttt{soundbox} is a device to connect classic audio systems to the network.
\section{Versioning}
This device is versioned with Semantic
Versioning\footnote{\href{https://semver.org}{https://semver.org}}. The
resulting version numbers have the format \texttt{<major>.<minor>.<patch>} like
e.g. \texttt{2.0.3}. While Semantic Versioning is usually targeted at software
only it is here used for the whole device. This includes mechanical, electronic
and software aspects as shown in figure \ref{diagram:device-semver}.
\begin{figure}[h]
\centering
\includegraphics[width=\textwidth]{device-semver.pdf}
\caption{API for a device versioned with Semantic Versioning}
\label{diagram:device-semver}
\end{figure}
This versioning makes sure that users do not have to care about the device
internals at all. Devices can be seen as atomic from a user's perspective. This
level of granularity is choosen because users are not expected to disassemble
devices or to care about the software internals.
%\section{Licensing}
\chapter{User guide}
In addition to \autoref{chap:introduction} `\nameref{chap:introduction}` the
following sections document everything required to use \texttt{soundbox}
devices.
%\section{Device setup}
\section{Playing audio} \label{playing-audio}
For a simple audio streaming test the following commands from the FFmpeg
streaming
guide\footnote{\href{https://trac.ffmpeg.org/wiki/StreamingGuide\#StreamingasimpleRTPaudiostreamfromFFmpeg}{https://trac.ffmpeg.org/wiki/StreamingGuide\#StreamingasimpleRTPaudiostreamfromFFmpeg}}
can be used. The following command has to be executed on the soundbox to start
listening on port \texttt{5316} of a local multicast IPv4 address for incoming
audio streams. Since multicast is used, this can be executed on multiple
soundbox devices to stream to all of them.
\begin{verbatim}
ffplay udp://224.0.0.99:5316
\end{verbatim}
As soon as the soundbox is listening the stream can be send from another
computer in the same network with this command:
\begin{verbatim}
ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" \
-acodec libmp3lame -f matroska udp://224.0.0.99:5316
\end{verbatim}
It will send a simple sine wave with 400~Hz to the soundbox device.
Alternatively a MP3 file can be sent like this:
\begin{verbatim}
ffmpeg -re -i <file-path> \
-acodec libmp3lame -f matroska udp://224.0.0.99:5316
\end{verbatim}
These commands allow to test the \texttt{soundbox} device setup.
\chapter{Production}
The given chapter contains documentation about how to produce a
\texttt{soundbox} device.
%\section{Printing mechanical parts}
\section{Alpine Linux installation on a Raspberry Pi}
Alpine Linux for the Raspberry Pi can be downloaded from the Alpine
Linux\footnote{\href{https://alpinelinux.org/}{https://alpinelinux.org/}}
download page. This section describes the installation procedure for the
variant targeting the AArch64 architecture provided as a compressed tar
archive. It can be downloaded and verified against a checksum with the
\texttt{wget} and \texttt{sha256sum} utilities.
\begin{verbatim}
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases\
/aarch64/alpine-rpi-3.19.0-aarch64.tar.gz
wget https://dl-cdn.alpinelinux.org/alpine/v3.19/releases\
/aarch64/alpine-rpi-3.19.0-aarch64.tar.gz.sha256
sha256sum -c alpine-rpi-3.19.0-aarch64.tar.gz.sha256
\end{verbatim}
The image has to be flashed to a SD card which will be inserted into the
Raspberry Pi. This SD card has to be put into a Linux PC first. In Linux every
SD card is represented as a block device like \texttt{sda} or \texttt{sdb} with
a file path like \texttt{/dev/sda}. Possibly existing partitions on the SD card
are represented with that path and a number as suffix like in
\texttt{/dev/sda1}. The program \texttt{lsblk} gives an overview of the
currently connected block devices. The correct device name for the SD card can
be identified by its size.
\begin{verbatim}
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 59,5G 0 disk
`-sda1 8:1 1 59,5G 0 part
\end{verbatim}
The SD card has to be formatted with a single bootable FAT32 partition. This
can be achieved with the command line program \texttt{parted}. First a
\texttt{msdos} partition table has to be created followed by a partition taking
the full size of the SD card. The boot flag of the partition is enabled and a
FAT32 file system is created with \texttt{mkfs.vfat}. All of these operations
require \texttt{root} privileges.
\textbf{Warning:} These operations might cause data loss if the wrong device is
specified. It has to be asserted that not the wrong block device (e.g. the PC
disk) is chosen.
\begin{verbatim}
parted /dev/<name> mklabel msdos
parted /dev/<name> mkpart primary fat32 0% 100%
parted /dev/<name> toggle 1 boot
mkfs.vfat /dev/<name>1
\end{verbatim}
After the file system is created the downloaded Alpine Linux tar archive has to
be extracted to it. A temporary mount point can be created with
\texttt{mktemp}. After mounting with \texttt{mount} the archive can be
extracted with \texttt{tar}. Finally the file system is unmounted and it is
waited for all buffered write operations to the SD card with \texttt{sync}.
Also these command require \texttt{root} privileges.
\begin{verbatim}
mountpoint=$(mktemp -d)
mount /dev/<name>1 "$mountpoint"
tar -C "$mountpoint" -xf alpine-rpi-3.19.0-aarch64.tar.gz
umount /dev/<name>1
sync
\end{verbatim}
Afterwards the SD card can be inserted into the Raspberry Pi. To do initial
configuration it should be connected to a screen via HDMI. Also a keyboard has
to be connected via USB. A mouse is not required. Finally the Pi should be
powered up by connecting a USB power supply to the corresponding USB power
input of the Raspberry Pi. Text from the boot process should be displayed on
the screen.
After logging in with the username \texttt{root} and no password basic system
configuration on Alpine Linux can be done interactively with
\texttt{setup-alpine}. The Alpine Linux installation
guide\footnote{\href{https://wiki.alpinelinux.org/wiki/Installation}{https://wiki.alpinelinux.org/wiki/Installation}}
contains further details. When a diskless installation is chosen the
configuration changes have to be made persistent with the \texttt{lbu} command.
Otherwise they will be lost on the next reboot.
\begin{verbatim}
setup-alpine
lbu commit -d
\end{verbatim}
With this setup the Alpine Linux installation is completed.
\section{Configure Alpine Linux for soundbox}
soundbox requires packages from the Alpine Linux community package repository.
Since this is not enabled by default it has to be done manually. This can be
done by editing the \texttt{/etc/apk/repositories} file with an editor like
\texttt{vi}. The hash sign \texttt{\#} in front of the URL to the community
repository has to be removed. Instead also \texttt{sed} can remove this sign on
a fresh installation quite easily since the community repository is the only
one with such a sign in front of it.
\begin{verbatim}
sed -i 's/^#//g' /etc/apk/repositories
\end{verbatim}
With an enabled community repository all required packages for soundbox can be
installed. The list with required packages can be written to the
\texttt{/etc/apk/world} file with \texttt{echo}. Running \texttt{apk add} after
it will install all of these packages including their dependencies and removes
everything else. This makes sure that always exactly the same set of packages
is used for a soundbox device.
\begin{verbatim}
echo 'alpine-base
alsa-utils
alsaconf
busybox-mdev-openrc
chrony
ffplay
iw
openssh
openssl
wpa_supplicant' > /etc/apk/world
apk add
\end{verbatim}
The only user on a soundbox device is \texttt{root}. Even that super user has
to be added to the \texttt{audio} group to be able to play sound via ALSA. This
can be achieved with \texttt{addgroup}.
\begin{verbatim}
addgroup root audio
\end{verbatim}
soundbox uses the HiFiBerry shield to output high-quality audio. This shield
needs to be enabled as an audio output by specifying a Devicetree overlay in
the Raspberry Pi configuration file with \texttt{echo}. Since this file is
stored on the SD card only which is mounted as read-only it has to be remounted
with the read-write option first.
\begin{verbatim}
mount -o remount,rw /media/mmcblk0p1
echo 'dtoverlay=hifiberry-dac' >> /media/mmcblk0p1/config.txt
\end{verbatim}
If the builtin audio of e.g. a Raspberry Pi 4 should be used another Devicetree
option has to be inserted instead:
\begin{verbatim}
echo 'dtparam=audio=on' >> /media/mmcblk0p1/config.txt
\end{verbatim}
Since a diskless Alpine Linux installation is preferred for soundbox the
changes have to be made persistent with \texttt{lbu}. Rebooting after it makes
sure the SD card is again mounted in read-only mode and all Kernel-affecting
changes can be applied.
\begin{verbatim}
lbu commit -d
reboot
\end{verbatim}
After this reboot the soundbox device should be able to play audio like
described in section~\ref{playing-audio}.
%\section{Final assembly}
%\chapter{Device internals}
%\section{Mechanical design}
%\section{Electronics}
%\section{Operating system}
%\section{Software}
\end{document}
|