No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

i2samp.sh 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. #!/bin/bash
  2. : <<'DISCLAIMER'
  3. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  4. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  5. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  6. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  7. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  8. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  9. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  10. OTHER DEALINGS IN THE SOFTWARE.
  11. This script is licensed under the terms of the MIT license.
  12. Unless otherwise noted, code reproduced herein
  13. was written for this script.
  14. - The Pimoroni Crew - (modified by Adafruit!)
  15. DISCLAIMER
  16. # script control variables
  17. productname="i2s amplifier" # the name of the product to install
  18. scriptname="i2samp" # the name of this script
  19. spacereq=1 # minimum size required on root partition in MB
  20. debugmode="no" # whether the script should use debug routines
  21. debuguser="none" # optional test git user to use in debug mode
  22. debugpoint="none" # optional git repo branch or tag to checkout
  23. forcesudo="no" # whether the script requires to be ran with root privileges
  24. promptreboot="no" # whether the script should always prompt user to reboot
  25. mininstall="no" # whether the script enforces minimum install routine
  26. customcmd="yes" # whether to execute commands specified before exit
  27. armhfonly="yes" # whether the script is allowed to run on other arch
  28. armv6="yes" # whether armv6 processors are supported
  29. armv7="yes" # whether armv7 processors are supported
  30. armv8="yes" # whether armv8 processors are supported
  31. raspbianonly="no" # whether the script is allowed to run on other OSes
  32. osreleases=( "Raspbian" ) # list os-releases supported
  33. oswarning=( "Debian" "Kano" "Mate" "PiTop" "Ubuntu" ) # list experimental os-releases
  34. osdeny=( "Darwin" "Kali" ) # list os-releases specifically disallowed
  35. FORCE=$1
  36. DEVICE_TREE=true
  37. ASK_TO_REBOOT=false
  38. CURRENT_SETTING=false
  39. UPDATE_DB=false
  40. BOOTCMD=/boot/cmdline.txt
  41. CONFIG=/boot/config.txt
  42. APTSRC=/etc/apt/sources.list
  43. INITABCONF=/etc/inittab
  44. BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
  45. LOADMOD=/etc/modules
  46. DTBODIR=/boot/overlays
  47. # function define
  48. confirm() {
  49. if [ "$FORCE" == '-y' ]; then
  50. true
  51. else
  52. read -r -p "$1 [y/N] " response < /dev/tty
  53. if [[ $response =~ ^(yes|y|Y)$ ]]; then
  54. true
  55. else
  56. false
  57. fi
  58. fi
  59. }
  60. prompt() {
  61. read -r -p "$1 [y/N] " response < /dev/tty
  62. if [[ $response =~ ^(yes|y|Y)$ ]]; then
  63. true
  64. else
  65. false
  66. fi
  67. }
  68. success() {
  69. echo -e "$(tput setaf 2)$1$(tput sgr0)"
  70. }
  71. inform() {
  72. echo -e "$(tput setaf 6)$1$(tput sgr0)"
  73. }
  74. warning() {
  75. echo -e "$(tput setaf 1)$1$(tput sgr0)"
  76. }
  77. newline() {
  78. echo ""
  79. }
  80. progress() {
  81. count=0
  82. until [ $count -eq $1 ]; do
  83. echo -n "..." && sleep 1
  84. ((count++))
  85. done
  86. echo
  87. }
  88. sudocheck() {
  89. if [ $(id -u) -ne 0 ]; then
  90. echo -e "Install must be run as root. Try 'sudo ./$scriptname'\n"
  91. exit 1
  92. fi
  93. }
  94. sysclean() {
  95. sudo apt-get clean && sudo apt-get autoclean
  96. sudo apt-get -y autoremove &> /dev/null
  97. }
  98. sysupdate() {
  99. if ! $UPDATE_DB; then
  100. echo "Updating apt indexes..." && progress 3 &
  101. sudo apt-get update 1> /dev/null || { warning "Apt failed to update indexes!" && exit 1; }
  102. echo "Reading package lists..."
  103. progress 3 && UPDATE_DB=true
  104. fi
  105. }
  106. sysupgrade() {
  107. sudo apt-get upgrade
  108. sudo apt-get clean && sudo apt-get autoclean
  109. sudo apt-get -y autoremove &> /dev/null
  110. }
  111. sysreboot() {
  112. warning "Some changes made to your system require"
  113. warning "your computer to reboot to take effect."
  114. newline
  115. if prompt "Would you like to reboot now?"; then
  116. sync && sudo reboot
  117. fi
  118. }
  119. arch_check() {
  120. IS_ARMHF=false
  121. IS_ARMv6=false
  122. if uname -m | grep "armv.l" > /dev/null; then
  123. IS_ARMHF=true
  124. if uname -m | grep "armv6l" > /dev/null; then
  125. IS_ARMv6=true
  126. fi
  127. fi
  128. }
  129. os_check() {
  130. IS_RASPBIAN=false
  131. IS_MACOSX=false
  132. IS_SUPPORTED=false
  133. IS_EXPERIMENTAL=false
  134. if [ -f /etc/os-release ]; then
  135. if cat /etc/os-release | grep "Raspbian" > /dev/null; then
  136. IS_RASPBIAN=true && IS_SUPPORTED=true
  137. fi
  138. if command -v apt-get > /dev/null; then
  139. for os in ${osreleases[@]}; do
  140. if cat /etc/os-release | grep $os > /dev/null; then
  141. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  142. fi
  143. done
  144. for os in ${oswarning[@]}; do
  145. if cat /etc/os-release | grep $os > /dev/null; then
  146. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  147. fi
  148. done
  149. for os in ${osdeny[@]}; do
  150. if cat /etc/os-release | grep $os > /dev/null; then
  151. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  152. fi
  153. done
  154. fi
  155. fi
  156. if [ -d ~/.kano-settings ] || [ -d ~/.kanoprofile ]; then
  157. IS_RASPBIAN=false
  158. for os in ${oswarning[@]}; do
  159. if [ $os == "Kano" ]; then
  160. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  161. fi
  162. done
  163. for os in ${osdeny[@]}; do
  164. if [ $os == "Kano" ]; then
  165. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  166. fi
  167. done
  168. fi
  169. if [ -f ~/.pt-dashboard-config ] || [ -d ~/.pt-dashboard ] || [ -d ~/.pt-os-dashboard ]; then
  170. IS_RASPBIAN=false
  171. for os in ${oswarning[@]}; do
  172. if [ $os == "PiTop" ]; then
  173. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  174. fi
  175. done
  176. for os in ${osdeny[@]}; do
  177. if [ $os == "PiTop" ]; then
  178. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  179. fi
  180. done
  181. fi
  182. if [ -d ~/.config/ubuntu-mate ]; then
  183. for os in ${osdeny[@]}; do
  184. if [ $os == "Mate" ]; then
  185. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  186. fi
  187. done
  188. fi
  189. if uname -s | grep "Darwin" > /dev/null; then
  190. IS_MACOSX=true
  191. for os in ${osdeny[@]}; do
  192. if [ $os == "Darwin" ]; then
  193. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  194. fi
  195. done
  196. fi
  197. }
  198. raspbian_check() {
  199. IS_SUPPORTED=false
  200. IS_EXPERIMENTAL=false
  201. if [ -f /etc/os-release ]; then
  202. if cat /etc/os-release | grep "/sid" > /dev/null; then
  203. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  204. elif cat /etc/os-release | grep "stretch" > /dev/null; then
  205. IS_SUPPORTED=false && IS_EXPERIMENTAL=true
  206. elif cat /etc/os-release | grep "jessie" > /dev/null; then
  207. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  208. elif cat /etc/os-release | grep "wheezy" > /dev/null; then
  209. IS_SUPPORTED=true && IS_EXPERIMENTAL=false
  210. else
  211. IS_SUPPORTED=false && IS_EXPERIMENTAL=false
  212. fi
  213. fi
  214. }
  215. : <<'MAINSTART'
  216. Perform all global variables declarations as well as function definition
  217. above this section for clarity, thanks!
  218. MAINSTART
  219. # checks and init
  220. arch_check
  221. os_check
  222. if [ $debugmode != "no" ]; then
  223. echo "USER_HOME is $USER_HOME" && newline
  224. echo "IS_RASPBIAN is $IS_RASPBIAN"
  225. echo "IS_MACOSX is $IS_MACOSX"
  226. echo "IS_SUPPORTED is $IS_SUPPORTED"
  227. echo "IS_EXPERIMENTAL is $IS_EXPERIMENTAL"
  228. newline
  229. fi
  230. if ! $IS_ARMHF; then
  231. warning "This hardware is not supported, sorry!"
  232. warning "Config files have been left untouched"
  233. newline && exit 1
  234. fi
  235. if $IS_ARMv8 && [ $armv8 == "no" ]; then
  236. warning "Sorry, your CPU is not supported by this installer"
  237. newline && exit 1
  238. elif $IS_ARMv7 && [ $armv7 == "no" ]; then
  239. warning "Sorry, your CPU is not supported by this installer"
  240. newline && exit 1
  241. elif $IS_ARMv6 && [ $armv6 == "no" ]; then
  242. warning "Sorry, your CPU is not supported by this installer"
  243. newline && exit 1
  244. fi
  245. if [ $raspbianonly == "yes" ] && ! $IS_RASPBIAN;then
  246. warning "This script is intended for Raspbian on a Raspberry Pi!"
  247. newline && exit 1
  248. fi
  249. if $IS_RASPBIAN; then
  250. raspbian_check
  251. if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
  252. newline && warning "--- Warning ---" && newline
  253. echo "The $productname installer"
  254. echo "does not work on this version of Raspbian."
  255. echo "Check https://github.com/$gitusername/$gitreponame"
  256. echo "for additional information and support"
  257. newline && exit 1
  258. fi
  259. fi
  260. if ! $IS_SUPPORTED && ! $IS_EXPERIMENTAL; then
  261. warning "Your operating system is not supported, sorry!"
  262. newline && exit 1
  263. fi
  264. if $IS_EXPERIMENTAL; then
  265. warning "Support for your operating system is experimental. Please visit"
  266. warning "forums.adafruit.com if you experience issues with this product."
  267. newline
  268. fi
  269. if [ $forcesudo == "yes" ]; then
  270. sudocheck
  271. fi
  272. newline
  273. echo "This script will install everything needed to use"
  274. echo "$productname"
  275. newline
  276. warning "--- Warning ---"
  277. newline
  278. echo "Always be careful when running scripts and commands"
  279. echo "copied from the internet. Ensure they are from a"
  280. echo "trusted source."
  281. newline
  282. echo "If you want to see what this script does before"
  283. echo "running it, you should run:"
  284. echo " \curl -sS github.com/adafruit/Raspberry-Pi-Installer-Scripts/$scriptname"
  285. newline
  286. if confirm "Do you wish to continue?"; then
  287. newline
  288. echo "Checking hardware requirements..."
  289. if [ -e $CONFIG ] && grep -q "^device_tree=$" $CONFIG; then
  290. DEVICE_TREE=false
  291. fi
  292. if $DEVICE_TREE; then
  293. newline
  294. echo "Adding Device Tree Entry to $CONFIG"
  295. if [ -e $CONFIG ] && grep -q "^dtoverlay=hifiberry-dac$" $CONFIG; then
  296. echo "dtoverlay already active"
  297. else
  298. echo "dtoverlay=hifiberry-dac" | sudo tee -a $CONFIG
  299. ASK_TO_REBOOT=true
  300. fi
  301. if [ -e $CONFIG ] && grep -q "^dtoverlay=i2s-mmap$" $CONFIG; then
  302. echo "i2s mmap dtoverlay already active"
  303. else
  304. echo "dtoverlay=i2s-mmap" | sudo tee -a $CONFIG
  305. ASK_TO_REBOOT=true
  306. fi
  307. if [ -e $BLACKLIST ]; then
  308. newline
  309. echo "Commenting out Blacklist entry in "
  310. echo "$BLACKLIST"
  311. sudo sed -i -e "s|^blacklist[[:space:]]*i2c-bcm2708.*|#blacklist i2c-bcm2708|" \
  312. -e "s|^blacklist[[:space:]]*snd-soc-pcm512x.*|#blacklist snd-soc-pcm512x|" \
  313. -e "s|^blacklist[[:space:]]*snd-soc-wm8804.*|#blacklist snd-soc-wm8804|" $BLACKLIST &> /dev/null
  314. fi
  315. else
  316. newline
  317. echo "No Device Tree Detected, not supported"
  318. newline
  319. exit 1
  320. fi
  321. if [ -e $CONFIG ] && grep -q -E "^dtparam=audio=on$" $CONFIG; then
  322. bcm2835off="no"
  323. newline
  324. echo "Disabling default sound driver"
  325. sudo sed -i "s|^dtparam=audio=on$|#dtparam=audio=on|" $CONFIG &> /dev/null
  326. if [ -e $LOADMOD ] && grep -q "^snd-bcm2835" $LOADMOD; then
  327. sudo sed -i "s|^snd-bcm2835|#snd-bcm2835|" $LOADMOD &> /dev/null
  328. fi
  329. ASK_TO_REBOOT=true
  330. elif [ -e $LOADMOD ] && grep -q "^snd-bcm2835" $LOADMOD; then
  331. bcm2835off="no"
  332. newline
  333. echo "Disabling default sound module"
  334. sudo sed -i "s|^snd-bcm2835|#snd-bcm2835|" $LOADMOD &> /dev/null
  335. ASK_TO_REBOOT=true
  336. else
  337. newline
  338. echo "Default sound driver currently not loaded"
  339. bcm2835off="yes"
  340. fi
  341. echo "Configuring sound output"
  342. if [ -e /etc/asound.conf ]; then
  343. if [ -e /etc/asound.conf.old ]; then
  344. sudo rm -f /etc/asound.conf.old
  345. fi
  346. sudo mv /etc/asound.conf /etc/asound.conf.old
  347. fi
  348. cat > ~/asound.conf << 'EOL'
  349. pcm.speakerbonnet {
  350. type hw card 0
  351. }
  352. pcm.dmixer {
  353. type dmix
  354. ipc_key 1024
  355. ipc_perm 0666
  356. slave {
  357. pcm "speakerbonnet"
  358. period_time 0
  359. period_size 1024
  360. buffer_size 8192
  361. rate 44100
  362. channels 2
  363. }
  364. }
  365. ctl.dmixer {
  366. type hw card 0
  367. }
  368. pcm.softvol {
  369. type softvol
  370. slave.pcm "dmixer"
  371. control.name "PCM"
  372. control.card 0
  373. }
  374. ctl.softvol {
  375. type hw card 0
  376. }
  377. pcm.!default {
  378. type plug
  379. slave.pcm "softvol"
  380. }
  381. EOL
  382. sudo mv ~/asound.conf /etc/asound.conf
  383. newline
  384. echo "Installing aplay systemd unit"
  385. sudo sh -c 'cat > /etc/systemd/system/aplay.service' << 'EOL'
  386. [Unit]
  387. Description=Invoke aplay from /dev/zero at system start.
  388. [Service]
  389. ExecStart=/usr/bin/aplay -D default -t raw -r 44100 -c 2 -f S16_LE /dev/zero
  390. [Install]
  391. WantedBy=multi-user.target
  392. EOL
  393. sudo systemctl daemon-reload
  394. sudo systemctl disable aplay
  395. newline
  396. echo "You can optionally activate '/dev/zero' playback in"
  397. echo "the background at boot. This will remove all"
  398. echo "popping/clicking but does use some processor time."
  399. newline
  400. if confirm "Activate '/dev/zero' playback in background? [RECOMMENDED]"; then
  401. newline
  402. sudo systemctl enable aplay
  403. ASK_TO_REBOOT=true
  404. fi
  405. if [ $bcm2835off == "yes" ]; then
  406. newline
  407. echo "We can now test your $productname"
  408. warning "Set your speakers at a low volume if possible!"
  409. if confirm "Do you wish to test your system now?"; then
  410. echo "Testing..."
  411. speaker-test -l5 -c2 -t wav
  412. fi
  413. fi
  414. newline
  415. success "All done!"
  416. newline
  417. echo "Enjoy your new $productname!"
  418. newline
  419. if [ $promptreboot == "yes" ] || $ASK_TO_REBOOT; then
  420. sysreboot
  421. fi
  422. else
  423. newline
  424. echo "Aborting..."
  425. newline
  426. fi
  427. exit 0