137 lines
4.1 KiB
Python
137 lines
4.1 KiB
Python
import os
|
|
|
|
try:
|
|
from adafruit_shell import Shell
|
|
from clint.textui import colored
|
|
except ImportError:
|
|
raise RuntimeError("The library 'adafruit_shell' was not found. To install, try typing: sudo pip3 install adafruit-python-shell")
|
|
|
|
shell = Shell()
|
|
|
|
BLACKLIST = "/etc/modprobe.d/raspi-blacklist.conf"
|
|
PRODUCT_NAME = "I2S Amplifier"
|
|
|
|
def driver_loaded(driver_name):
|
|
return shell.run_command(f"lsmod | grep -q '{driver_name}'", suppress_message=True)
|
|
|
|
def main():
|
|
reboot = False
|
|
shell.clear()
|
|
if not shell.is_raspberry_pi():
|
|
shell.bail("Non-Raspberry Pi board detected.")
|
|
print("\nThis script will install everything needed to use\n"
|
|
f"{PRODUCT_NAME}.\n")
|
|
print(colored.red("--- Warning ---"))
|
|
print("\nAlways be careful when running scripts and commands\n"
|
|
"copied from the internet. Ensure they are from a\n"
|
|
"trusted source.\n")
|
|
if not shell.prompt("Do you wish to continue?"):
|
|
print("\nAborting...")
|
|
shell.exit()
|
|
|
|
print("\nChecking hardware requirements...")
|
|
|
|
# Enable I2S overlay
|
|
config = "/boot/firmware/config.txt"
|
|
if not os.path.exists(config):
|
|
config = "/boot/config.txt"
|
|
if not os.path.exists(config):
|
|
shell.bail("No Device Tree Detected, not supported")
|
|
|
|
print(f"\nAdding Device Tree Entry to {config}")
|
|
|
|
if shell.pattern_search(config, "^dtoverlay=max98357a$"):
|
|
print("dtoverlay already active")
|
|
else:
|
|
shell.write_text_file(config, "dtoverlay=max98357a")
|
|
reboot = True
|
|
|
|
if os.path.exists(BLACKLIST):
|
|
print("\nCommenting out Blacklist entry in", BLACKLIST)
|
|
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a.*", "#blacklist snd_soc_max98357a")
|
|
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a_i2c.*", "#blacklist snd_soc_max98357a_i2c")
|
|
shell.pattern_replace(BLACKLIST, "^blacklist[[:space:]]*snd_soc_max98357a.*", "#blacklist snd_soc_max98357a")
|
|
|
|
print("Configuring sound output")
|
|
if os.path.exists("/etc/asound.conf"):
|
|
if os.path.exists("/etc/asound.conf.old"):
|
|
shell.remove("/etc/asound.conf.old")
|
|
shell.move("/etc/asound.conf", "/etc/asound.conf.old")
|
|
shell.write_text_file("~/asound.conf",
|
|
"""
|
|
pcm.speakerbonnet {
|
|
type hw card 0
|
|
}
|
|
|
|
pcm.dmixer {
|
|
type dmix
|
|
ipc_key 1024
|
|
ipc_perm 0666
|
|
slave {
|
|
pcm "speakerbonnet"
|
|
period_time 0
|
|
period_size 1024
|
|
buffer_size 8192
|
|
rate 44100
|
|
channels 2
|
|
}
|
|
}
|
|
|
|
ctl.dmixer {
|
|
type hw card 0
|
|
}
|
|
|
|
pcm.softvol {
|
|
type softvol
|
|
slave.pcm "dmixer"
|
|
control.name "PCM"
|
|
control.card 0
|
|
}
|
|
|
|
ctl.softvol {
|
|
type hw card 0
|
|
}
|
|
|
|
pcm.!default {
|
|
type plug
|
|
slave.pcm "softvol"
|
|
}
|
|
""")
|
|
shell.move("~/asound.conf", "/etc/asound.conf")
|
|
|
|
|
|
print("Installing aplay systemd unit")
|
|
shell.write_text_file("/etc/systemd/system/aplay.service", """
|
|
[Unit]
|
|
Description=Invoke aplay from /dev/zero at system start.
|
|
|
|
[Service]
|
|
ExecStart=/usr/bin/aplay -D default -t raw -r 44100 -c 2 -f S16_LE /dev/zero
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target""", append=False)
|
|
|
|
shell.run_command("sudo systemctl daemon-reload")
|
|
shell.run_command("sudo systemctl disable aplay")
|
|
print("\nYou can optionally activate '/dev/zero' playback in\n"
|
|
"the background at boot. This will remove all\n"
|
|
"popping/clicking but does use some processor time.\n\n")
|
|
if shell.prompt("Activate '/dev/zero' playback in background? [RECOMMENDED]\n", default="y"):
|
|
shell.run_command("sudo systemctl enable aplay")
|
|
reboot = True
|
|
|
|
if driver_loaded("max98357a"):
|
|
print(f"\nWe can now test your {PRODUCT_NAME}")
|
|
shell.warn("Set your speakers at a low volume if possible!")
|
|
if shell.prompt("Do you wish to test your system now?"):
|
|
print("Testing...")
|
|
shell.run_command("speaker-test -l5 -c2 -t wav")
|
|
print("\n" + colored.green("All done!"))
|
|
print("\nEnjoy your new $productname!")
|
|
if reboot:
|
|
shell.prompt_reboot()
|
|
|
|
# Main function
|
|
if __name__ == "__main__":
|
|
shell.require_root()
|
|
main()
|