-
Notifications
You must be signed in to change notification settings - Fork 160
/
spectro.sh
273 lines (241 loc) · 8.13 KB
/
spectro.sh
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
268
269
270
271
272
273
#!/bin/bash
# INSTALLER SCRIPT FOR ADAFRUIT SPECTRO PROJECT
if [ $(id -u) -ne 0 ]; then
echo "Installer must be run as root."
echo "Try 'sudo bash $0'"
exit 1
fi
clear
echo "This script installs software for the Adafruit"
echo "Spectro project for Raspberry Pi."
echo "Steps include:"
echo "- Update package index files (apt-get update)"
echo "- Install prerequisite software"
echo "- Install Spectro software"
echo "- Configure hardware and boot options"
echo "Run time ~10 minutes."
echo
echo "EXISTING INSTALLATION, IF ANY, WILL BE OVERWRITTEN."
echo "If you've edited any Spectro-related files, cancel"
echo "the installation and back up those files first."
echo
echo -n "CONTINUE? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
# FEATURE PROMPTS ----------------------------------------------------------
# Installation doesn't begin until after all user input is taken.
MATRIX_SIZE=0
SLOWDOWN_GPIO=0
ENABLE_MIC=0
ENABLE_ACCEL=0
HDMI_SIZE=0
OPTION_NAMES=(NO YES)
MATRIX_WIDTHS=(64 32)
MATRIX_HEIGHTS=(32 16)
SIZE_OPTS=( \
"${MATRIX_WIDTHS[0]} x ${MATRIX_HEIGHTS[0]}" \
"${MATRIX_WIDTHS[1]} x ${MATRIX_HEIGHTS[1]}" \
)
SLOWDOWN_OPTS=( \
"0" \
"1" \
"2" \
"3" \
"4" \
)
HDMI_OPTS=( \
"640x480" \
"320x240" \
)
# Given a list of strings representing options, display each option
# preceded by a number (1 to N), display a prompt, check input until
# a valid number within the selection range is entered.
selectN() {
args=("${@}")
# If first item in list is the literal number '0', make the list
# indexed from 0 rather than 1. This is to avoid confusion when
# entering the GPIO slowdown setting (e.g. entering '1' for a
# value of '0' is awkward). In all other cases, list is indexed
# from 1 as this is more human.
if [[ ${args[0]} = "0" ]]; then
OFFSET=0
else
OFFSET=1
fi
for ((i=0; i<$#; i++)); do
echo $((i+$OFFSET)). ${args[$i]}
done
echo
REPLY=""
let LAST=$#+$OFFSET-1
while :
do
echo -n "SELECT $OFFSET-$LAST: "
read
if [[ $REPLY -ge $OFFSET ]] && [[ $REPLY -le $LAST ]]; then
let RESULT=$REPLY-$OFFSET
return $RESULT
fi
done
}
echo
echo "What size LED matrix are you using with Spectro?"
selectN "${SIZE_OPTS[@]}"
MATRIX_SIZE=$?
echo
echo "Faster Pi boards require dialing back GPIO speed"
echo "to work with the LED matrix. For Raspberry Pi 4,"
echo "this usually means the max '4' slowdown setting."
echo "For Pi 2 or 3, try the '1' or '2' settings. There"
echo "is no hard-set rule to this, it can vary with"
echo "matrix and cabling as well. If the Spectro display"
echo "is glitchy, just re-run this installer, selecting"
echo "a higher setting until you find a stable value."
echo "GPIO slowdown setting:"
selectN "${SLOWDOWN_OPTS[@]}"
SLOWDOWN_GPIO=$?
echo
echo -n "OPTIONAL: Enable USB microphone support? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
ENABLE_MIC=1
fi
echo
echo -n "OPTIONAL: Enable LIS3DH accelerometer support? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
ENABLE_ACCEL=1
fi
# HDMI resolution selection might be handled later; right now nothing
# requires it. But in the future if anything relies on fb2matrix.py,
# HDMI resolution ultimately determines the frame rate that's possible,
# flipside being that some monitors can't handle extremely low resolutions.
# So an option might be presented here, set to 320x240 or 640x480 (the
# latter being the minimum resolution some displays can support).
# VERIFY SELECTIONS BEFORE CONTINUING --------------------------------------
echo
echo "LED matrix size: ${SIZE_OPTS[$MATRIX_SIZE]}"
echo "GPIO slowdown: ${SLOWDOWN_OPTS[$SLOWDOWN_GPIO]}"
echo "Enable USB microphone support: ${OPTION_NAMES[$ENABLE_MIC]}"
echo "Enable LIS3DH support: ${OPTION_NAMES[$ENABLE_ACCEL]}"
#echo "HDMI resolution: ${HDMI_OPTS[$HDMI_SIZE]}"
echo
echo -n "CONTINUE? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Canceled."
exit 0
fi
# Check whether RGB matrix library is present.
# If not, offer to download and run that script first (then return here).
echo
echo "Updating package index files..."
apt-get update
apt-get -qq install python3-pip python-pip
echo -n "Checking for RGB matrix library..."
pip3 freeze | grep rgbmatrix > /dev/null
if [ $? -eq 0 ]; then
echo "OK."
else
echo "not present."
echo "Would you like to download and install the RGB matrix"
echo "library (required by Spectro) first? If so, DO NOT REBOOT"
echo "when prompted. You’ll return to this script for more"
echo "Spectro configuration."
echo -n "Run RGB matrix installer? [y/N] "
read
if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/rgb-matrix.sh -O rgb-matrix.sh
bash rgb-matrix.sh
echo
echo "You are now back in the main Spectro installer script."
echo "When prompted about reboot again, now it's OK!"
fi
fi
# START INSTALL ------------------------------------------------------------
# All selections are validated at this point...
# Given a filename, a regex pattern to match and a replacement string,
# perform replacement if found, else append replacement to end of file.
# (# $1 = filename, $2 = pattern to match, $3 = replacement)
reconfig() {
grep $2 $1 >/dev/null
if [ $? -eq 0 ]; then
# Pattern found; replace in file
sed -i "s/$2/$3/g" $1 >/dev/null
else
# Not found; append (silently)
echo $3 | sudo tee -a $1 >/dev/null
fi
}
# Same as above, but skips if pattern not found
reconfig2() {
grep $2 $1 >/dev/null
if [ $? -eq 0 ]; then
# Pattern found; replace in file
sed -i "s/$2/$3/g" $1 >/dev/null
fi
}
echo
echo "Starting installation..."
# Although Spectro is all Python3-ready, user additions might rely on
# Python2, so we'll install the prerequisite libraries for both 2 and 3...
echo "Downloading prerequisites..."
pip3 install psutil RPi.GPIO
pip install psutil RPi.GPIO
apt-get install -y --allow-unauthenticated python3-dev python3-pillow python2.7-dev python-pillow
if [ $ENABLE_MIC -ne 0 ]; then
apt-get install -y --allow-unauthenticated python3-pyaudio python3-numpy python-pyaudio python-numpy
fi
if [ $ENABLE_ACCEL -ne 0 ]; then
pip3 install adafruit-circuitpython-busdevice adafruit-circuitpython-lis3dh
pip install adafruit-circuitpython-busdevice adafruit-circuitpython-lis3dh
fi
echo "Downloading Spectro software..."
curl -L https://github.com/adafruit/Adafruit_Spectro_Pi/archive/master.zip -o Adafruit_Spectro_Pi.zip
unzip -q -o Adafruit_Spectro_Pi.zip
rm Adafruit_Spectro_Pi.zip
mv Adafruit_Spectro_Pi-master Adafruit_Spectro_Pi
chown -R pi:pi Adafruit_Spectro_Pi
# CONFIG -------------------------------------------------------------------
echo "Configuring system..."
if [ $ENABLE_MIC -ne 0 ]; then
# Change ALSA settings to allow USB mic use
reconfig2 /usr/share/alsa/alsa.conf "^defaults.ctl.card.*0" "defaults.ctl.card 1"
reconfig2 /usr/share/alsa/alsa.conf "^defaults.pcm.card.*0" "defaults.pcm.card 1"
fi
if [ $ENABLE_ACCEL -ne 0 ]; then
# Enable I2C for accelerometer
raspi-config nonint do_i2c 0
fi
# Make default GIFs directory
mkdir /boot/gifs
# Set up LED columns, rows and slowdown in selector.py script
reconfig2 ./Adafruit_Spectro_Pi/selector.py "^FLAGS.*$" "FLAGS\ =\ [\"--led-cols=${MATRIX_WIDTHS[$MATRIX_SIZE]}\",\ \"--led-rows=${MATRIX_HEIGHTS[$MATRIX_SIZE]}\",\ \"--led-slowdown-gpio=${SLOWDOWN_OPTS[$SLOWDOWN_GPIO]}\"]"
# Force HDMI out so /dev/fb0 exists
reconfig /boot/config.txt "^.*hdmi_force_hotplug.*$" "hdmi_force_hotplug=1"
#reconfig /boot/config.txt "^.*hdmi_group.*$" "hdmi_group=2"
#reconfig /boot/config.txt "^.*hdmi_mode.*$" "hdmi_mode=87"
# Auto-start selector.py on boot
grep selector.py /etc/rc.local >/dev/null
if [ $? -ne 0 ]; then
# Insert selector.py into rc.local before final 'exit 0'
sed -i "s/^exit 0/cd \/home\/pi\/Adafruit_Spectro_Pi\;python3 selector.py \&\\nexit 0/g" /etc/rc.local >/dev/null
fi
# PROMPT FOR REBOOT --------------------------------------------------------
echo "Done."
echo
echo "Settings take effect on next boot."
echo "For proper clock time, set the time zone with raspi-config."
echo
echo -n "REBOOT NOW? [y/N] "
read
if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then
echo "Exiting without reboot."
exit 0
fi
echo "Reboot started..."
reboot
sleep infinity