From 21efc3c30bda086fed23bcaf9a6de4aff28be1d1 Mon Sep 17 00:00:00 2001 From: AlexanderPavlenko Date: Wed, 20 Oct 2021 20:28:45 +0300 Subject: [PATCH] open sourced --- duplex-ipad/.overmind.env => .overmind.env | 0 Brewfile | 3 + Brewfile.lock.json | 104 +++++++++++++++++++++ Procfile | 5 + README.md | 41 ++++++++ deploy.sh | 4 + duplex-ipad/Procfile | 5 - from-pi/Procfile | 3 - duplex-ipad/pi-socat.sh => iSH-socat.sh | 6 +- rc.local | 18 ++++ to-pi/Procfile | 3 - usb.sh | 37 ++++++++ 12 files changed, 215 insertions(+), 14 deletions(-) rename duplex-ipad/.overmind.env => .overmind.env (100%) create mode 100644 Brewfile create mode 100644 Brewfile.lock.json create mode 100644 Procfile create mode 100644 README.md create mode 100755 deploy.sh delete mode 100644 duplex-ipad/Procfile delete mode 100644 from-pi/Procfile rename duplex-ipad/pi-socat.sh => iSH-socat.sh (54%) create mode 100755 rc.local delete mode 100644 to-pi/Procfile create mode 100755 usb.sh diff --git a/duplex-ipad/.overmind.env b/.overmind.env similarity index 100% rename from duplex-ipad/.overmind.env rename to .overmind.env diff --git a/Brewfile b/Brewfile new file mode 100644 index 0000000..379c7cf --- /dev/null +++ b/Brewfile @@ -0,0 +1,3 @@ +brew "overmind" +brew "sox" +cask "blackhole-16ch" diff --git a/Brewfile.lock.json b/Brewfile.lock.json new file mode 100644 index 0000000..66106c4 --- /dev/null +++ b/Brewfile.lock.json @@ -0,0 +1,104 @@ +{ + "entries": { + "brew": { + "overmind": { + "version": "2.2.2", + "bottle": { + "rebuild": 0, + "root_url": "https://ghcr.io/v2/homebrew/core", + "files": { + "arm64_big_sur": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/overmind/blobs/sha256:00af66eeee076ae3bccba58a690dc73f908b6af7ea0bfebf1fc6b81c5a88c445", + "sha256": "00af66eeee076ae3bccba58a690dc73f908b6af7ea0bfebf1fc6b81c5a88c445" + }, + "big_sur": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/overmind/blobs/sha256:f0a2458bfe0cbe0a38ca8579b774e45262f68bf8a9f9d1d2ff70a9c388c21446", + "sha256": "f0a2458bfe0cbe0a38ca8579b774e45262f68bf8a9f9d1d2ff70a9c388c21446" + }, + "catalina": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/overmind/blobs/sha256:0d2b7a68b08aa6ce0a5cdfad5a90166248ee11fce70970d1e820918de612168a", + "sha256": "0d2b7a68b08aa6ce0a5cdfad5a90166248ee11fce70970d1e820918de612168a" + }, + "mojave": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/overmind/blobs/sha256:07036145d0ff5102e0a64607cb1d253a49e66aa6ceb5ea4b82780a4078910c04", + "sha256": "07036145d0ff5102e0a64607cb1d253a49e66aa6ceb5ea4b82780a4078910c04" + }, + "x86_64_linux": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/overmind/blobs/sha256:4c63f041aaf3949b972351ea2102a5405dc71d6c5e0de79cceb170745cf39d0a", + "sha256": "4c63f041aaf3949b972351ea2102a5405dc71d6c5e0de79cceb170745cf39d0a" + } + } + } + }, + "sox": { + "version": "14.4.2_3", + "bottle": { + "rebuild": 0, + "root_url": "https://ghcr.io/v2/homebrew/core", + "files": { + "arm64_big_sur": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:8070949420a9a02f3d5e1a99bd460d064e34c361798bae5c4554ac8e1aeb2d49", + "sha256": "8070949420a9a02f3d5e1a99bd460d064e34c361798bae5c4554ac8e1aeb2d49" + }, + "big_sur": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:e3f62a35b06c9e79516f575a923b3aafc5357f370f4ae5c2812c67c8862ae11c", + "sha256": "e3f62a35b06c9e79516f575a923b3aafc5357f370f4ae5c2812c67c8862ae11c" + }, + "catalina": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:fc412be07e577c2161763dfb509f4fb43f4fe3bca206a1b0b370687df0a264fa", + "sha256": "fc412be07e577c2161763dfb509f4fb43f4fe3bca206a1b0b370687df0a264fa" + }, + "mojave": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:4906207f83bd0f4ea1a67d040891711e9a9e8830216e451072f2957ca566b83d", + "sha256": "4906207f83bd0f4ea1a67d040891711e9a9e8830216e451072f2957ca566b83d" + }, + "high_sierra": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:c0bb4ba7ec922d9a8c71c2ba84e28c66c67e4fdeae970011ea45e937f43c18bd", + "sha256": "c0bb4ba7ec922d9a8c71c2ba84e28c66c67e4fdeae970011ea45e937f43c18bd" + }, + "sierra": { + "cellar": ":any", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:dc8c294bb96c0b7ebc3ade73476c6031664bb8e81a32ece87ce84f815deeced5", + "sha256": "dc8c294bb96c0b7ebc3ade73476c6031664bb8e81a32ece87ce84f815deeced5" + }, + "x86_64_linux": { + "cellar": ":any_skip_relocation", + "url": "https://ghcr.io/v2/homebrew/core/sox/blobs/sha256:812ddfd499335d3ff3e096b6153ef60e86326b5fb2cffb3e2ae02e8be6bc98c2", + "sha256": "812ddfd499335d3ff3e096b6153ef60e86326b5fb2cffb3e2ae02e8be6bc98c2" + } + } + } + } + }, + "cask": { + "blackhole-16ch": { + "version": "0.2.10", + "options": { + "full_name": "blackhole-16ch" + } + } + } + }, + "system": { + "macos": { + "big_sur": { + "HOMEBREW_VERSION": "3.2.17-63-g5a5a8d5", + "HOMEBREW_PREFIX": "/opt/homebrew", + "Homebrew/homebrew-core": "df940f25efdeaec9913a76c9119e6cb44b7632cf", + "CLT": "12.5.0.22.9", + "Xcode": "13.0", + "macOS": "11.6" + } + } + } +} diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..1793217 --- /dev/null +++ b/Procfile @@ -0,0 +1,5 @@ +host: sleep 3; sox -V1 -t coreaudio "BlackHole 16ch" -t wav -b 16 - remix 1 2 | nc 192.168.44.4 2150 | sox --input-buffer 500000 -V1 -t wav - -t coreaudio "BlackHole 16ch" remix 0 0 1 2 +pi: trap 'ssh -S none root@pi "killall nc arecord aplay"' EXIT > /dev/null; ssh -S none root@pi 'nice -n -20 arecord --disable-resample --disable-channels --disable-format --disable-softvol --format S24_3LE --rate 44100 --channels 2 --file-type wav - | nice -n -20 nc -l 2150 -I 3000000 -O 3000000 | nice -n -20 aplay --disable-resample --disable-channels --disable-format --disable-softvol -' + +# fixme: why sshd suddenly exits? +#ipad: trap 'ssh ipad "killall cat socat"' EXIT > /dev/null; ssh ipad ./pi-socat.sh \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..65155e6 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +This code allows to use Raspberry Pi Zero as a USB gadget +composite of Ethernet and Audio input/output. + +Alternatives: + +* [Dante AVIO Adapter](https://www.audinate.com/products/devices/dante-avio#USB) – seems cool and pricey +* Zoom H2N recorder – wired input only, analog line +* Apple IDAM – wired output only, lossless +* [Audreio](https://audre.io/) – seems outdated without Audiobus integration + +Credits: +* [iSticktoit.net - Composite USB gadgets on the Raspberry Pi Zero](https://www.isticktoit.net/?p=1383) + +Raspberry Pi bootstrap on macOS: +```shell +# export $SDCARD=diskX +# diskutil unmountDisk /dev/$SDCARD +# sudo dd bs=1m if=~/Downloads/2021-05-07-raspios-buster-armhf-lite.img of=/dev/r$SDCARD; sync +# sudo diskutil eject /dev/r$SDCARD + +# config.txt – add new line to the bottom: dtoverlay=dwc2 +# cmdline.txt – insert after rootwait: modules-load=dwc2,g_ether +# create empty file: touch ssh + +# on raspberry A+, maybe: dtoverlay=dwc2,dr_mode=peripheral +# https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README#L800 + +# to disable LED add to /boot/config.txt +dtparam=act_led_trigger=none +dtparam=act_led_activelow=on + +# to disable wireless add to /boot/config.txt +dtoverlay=disable-wifi +dtoverlay=disable-bt + +ping raspberrypi.local +ssh pi@169.254.X.Y +pass: raspberry + +# after deploy.sh change cmdline.txt: modules-load=dwc2,libcomposite +``` diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..0081304 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,4 @@ +#!/bin/zsh + +scp rc.local root@pi:/etc/rc.local +scp usb.sh root@pi:/root/usb.sh \ No newline at end of file diff --git a/duplex-ipad/Procfile b/duplex-ipad/Procfile deleted file mode 100644 index 4d93fce..0000000 --- a/duplex-ipad/Procfile +++ /dev/null @@ -1,5 +0,0 @@ - -host: sleep 2; sox -V1 -t coreaudio "BlackHole 16ch" -t wav -b 24 - remix 1 2 | nc 192.168.44.4 2150 | sox --input-buffer 1000000 -V1 -t wav - -t coreaudio "BlackHole 16ch" remix 0 0 1 2 -pi: ssh -S none root@pi-pad 'nice -n -20 arecord --disable-resample --disable-channels --disable-format --disable-softvol --format S24_3LE --rate 44100 --channels 2 --file-type wav - | nice -n -20 nc -l 2150 | nice -n -20 aplay --disable-resample --disable-channels --disable-format --disable-softvol -' - -# on exit? : killall nc arecord aplay \ No newline at end of file diff --git a/from-pi/Procfile b/from-pi/Procfile deleted file mode 100644 index 20b8f14..0000000 --- a/from-pi/Procfile +++ /dev/null @@ -1,3 +0,0 @@ - -host: sleep 2; nc 192.168.44.241 2150 | sox --input-buffer 1000000 -V1 -t wav - -t coreaudio "BlackHole 16ch" remix 0 0 1 2 -pi: ssh pi-w 'arecord --disable-resample --disable-channels --disable-format --disable-softvol -f cd - | nc -l 2150' diff --git a/duplex-ipad/pi-socat.sh b/iSH-socat.sh similarity index 54% rename from duplex-ipad/pi-socat.sh rename to iSH-socat.sh index 848f209..a7c479c 100644 --- a/duplex-ipad/pi-socat.sh +++ b/iSH-socat.sh @@ -1,5 +1,5 @@ #!/bin/sh -# run via iSH on iPad: -cat /dev/location > /dev/null & # allows to run in background +# run via https://ish.app +cat /dev/location > /dev/null & # granting "allow always" enables running in background socat TCP-LISTEN:2122,bind=0.0.0.0,fork,su=nobody,reuseaddr TCP:169.254.1.1:22 & -socat TCP-LISTEN:2150,bind=0.0.0.0,fork,su=nobody,reuseaddr TCP:169.254.1.1:2150 & +socat TCP-LISTEN:2150,bind=0.0.0.0,fork,su=nobody,reuseaddr TCP:169.254.1.1:2150 diff --git a/rc.local b/rc.local new file mode 100755 index 0000000..9fc2675 --- /dev/null +++ b/rc.local @@ -0,0 +1,18 @@ +#!/bin/sh -e +# +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +/root/usb.sh || echo "cannot setup usb?" + +tvservice -o || echo "cannot disable hdmi?" + +exit 0 diff --git a/to-pi/Procfile b/to-pi/Procfile deleted file mode 100644 index 03eedb3..0000000 --- a/to-pi/Procfile +++ /dev/null @@ -1,3 +0,0 @@ - -host: sleep 2; sox -V1 -t coreaudio "BlackHole 16ch" -t wav -b 16 - remix 1 2 | nc 192.168.44.241 2150 -pi: ssh pi-w 'nc -l 2150 | aplay --disable-resample --disable-channels --disable-format --disable-softvol -' diff --git a/usb.sh b/usb.sh new file mode 100755 index 0000000..e33c396 --- /dev/null +++ b/usb.sh @@ -0,0 +1,37 @@ +#!/usr/bin/bash + +cd /sys/kernel/config/usb_gadget/ || fail +mkdir -p lexi && cd lexi || fail + +echo 0x1d6b > idVendor # Linux Foundation +echo 0x0104 > idProduct # Multifunction Composite Gadget +echo 0x0100 > bcdDevice # v1.0.0 +echo 0x0200 > bcdUSB # USB2 +mkdir -p strings/0x409 +echo "fedcba9876543210" > strings/0x409/serialnumber +echo "Lexi" > strings/0x409/manufacturer +echo "Raspberry Pi Zero" > strings/0x409/product +mkdir -p configs/c.1/strings/0x409 +echo "ECM + UAC2" > configs/c.1/strings/0x409/configuration +echo 250 > configs/c.1/MaxPower + +# Ethernet +mkdir -p functions/ecm.usb0 +# first byte of address must be even +echo "48:6f:73:74:50:43" > functions/ecm.usb0/host_addr +echo "42:61:64:55:53:42" > functions/ecm.usb0/dev_addr +ln -s functions/ecm.usb0 configs/c.1/ + +# UAC2 audio +mkdir -p functions/uac2.usb0 +echo 3 > functions/uac2.usb0/c_ssize +echo 2 > functions/uac2.usb0/p_ssize +echo 44100 > functions/uac2.usb0/c_srate +echo 44100 > functions/uac2.usb0/p_srate +ln -s functions/uac2.usb0 configs/c.1/ + +# End functions +ls /sys/class/udc > UDC + +ifconfig usb0 169.254.1.1 netmask 255.255.0.0 up +route add -net default gw 169.254.1.2