Skip to content

Instantly share code, notes, and snippets.

@pccr10001
Last active January 19, 2022 09:06
Show Gist options
  • Save pccr10001/1fcc784138dd872e83fd424b65f912d7 to your computer and use it in GitHub Desktop.
Save pccr10001/1fcc784138dd872e83fd424b65f912d7 to your computer and use it in GitHub Desktop.
Spotify Connect client by Mediatek Linkit 7688 with WM8960
diff --git a/playback/Cargo.toml b/playback/Cargo.toml
index 4e8d19c..37a06eb 100644
--- a/playback/Cargo.toml
+++ b/playback/Cargo.toml
@@ -26,6 +26,7 @@ shell-words = "1.0.0"
tokio = { version = "1", features = ["sync"] }
zerocopy = { version = "0.3" }
thiserror = { version = "1" }
+atomic-shim = "*"
# Backends
alsa = { version = "0.5", optional = true }
diff --git a/playback/src/mixer/softmixer.rs b/playback/src/mixer/softmixer.rs
index cefc2de..ea5ebfd 100644
--- a/playback/src/mixer/softmixer.rs
+++ b/playback/src/mixer/softmixer.rs
@@ -1,4 +1,5 @@
-use std::sync::atomic::{AtomicU64, Ordering};
+use std::sync::atomic::{Ordering};
+use atomic_shim::AtomicU64;
use std::sync::Arc;
use super::AudioFilter;

Linkit 7688 Spotify Connect Player

Requirement

  • Mediatek Linkit 7688
  • Seeed Breakout for LinkIt Smart 7688
  • 2 x Speaker

Software environment

  • OpenWRT 21.02.1 based on Linux 5.4.154
  • Ubuntu 20.04 for development

Build OpenWRT image with WM8960 codec support

# download openwrt source
wget https://github.com/openwrt/openwrt/archive/refs/tags/v21.02.1.tar.gz -O openwrt-21.02.1.tar.gz

tar xf openwrt-21.02.1.tar.gz

# init openwrt build env
./scripts/feeds update -a
./scripts/feeds install -a

# download default build config from offical release
cd openwrt-21.02.1
wget https://downloads.openwrt.org/releases/21.02.1/targets/ramips/mt76x8/config.buildinfo -O .config

# put wm8960 driver into kernel
cd package/kernel
git clone https://github.com/redchenjs/mt762x-wm8960.git

# install device tree
cp mt762x-wm8960/examples/mt7628an_mediatek_linkit-smart-7688.dts ../../target/linux/ramips/dts/

# update config
## Change `Target Profile` to `MediaTek LinkIt Smart 7688` to increase building speed
## Enable `Kernel modules` --> `Sound Support` --> `kmod-sound-mt762x-wm8960`
## Uncheck `Global build settings` --> `Set build defaults for automatic builds (e.g. via buildbot)`
## Uncheck `Global build settings` --> `Enable signature checking in opkg`

make menuconfig

# Start to build
make -j12

Install new image

  • Factory reset device
firstboot
  • upgrade system with bin/targets/ramips/mt76x8/openwrt-21.02.1-ramips-mt76x8-mediatek_linkit-smart-7688-squashfs-sysupgrade.bin

Install packages

  • put bin/targets/ramips/mt76x8/packages to a web server or use pip -m SimpleHTTPServer 8080
  • Connect to luci
  • Select System -> Software
  • Click Configure opkg
  • Modify `/etc/opkg/distfeeds.conf
    • Change core repo to your local web server path
----- CORE_REPO -----
src/gz openwrt_core http://192.168.1.100:8080/bin/targets/ramips/mt76x8/packages
----- CORE_REPO -----

src/gz openwrt_base https://downloads.openwrt.org/releases/21.02.0/packages/mipsel_24kc/base
src/gz openwrt_luci https://downloads.openwrt.org/releases/21.02.0/packages/mipsel_24kc/luci
src/gz openwrt_packages https://downloads.openwrt.org/releases/21.02.0/packages/mipsel_24kc/packages
src/gz openwrt_routing https://downloads.openwrt.org/releases/21.02.0/packages/mipsel_24kc/routing
src/gz openwrt_telephony https://downloads.openwrt.org/releases/21.02.0/packages/mipsel_24kc/telephony
  • Click Update lists...
  • Install alsa-utils kmod-sound-mt762x-wm8960 sox

Build librespot

### ref: https://gist.github.com/Michcioperz/99b40b861b158e2cbff507288d804c6b

# setup env, `pwd` is your openwrt source dir
export STAGING_DIR=`pwd`/staging_dir
export PATH=`pwd`/staging_dir/toolchain-mipsel_24kc_gcc-8.4.0_musl/bin:/root/.cargo/bin:$PATH

# install rust
wget https://sh.rustup.rs -O rustup-init && chmod +x rustup-init && ./rustup-init --profile minimal -y

rustup target add mipsel-unknown-linux-musl

dpkg --add-architecture mipsel

# download librespot
wget https://github.com/librespot-org/librespot/archive/refs/tags/v0.3.1.tar.gz
tar xf v0.3.1.tar.gz

cd librespot-0.3.1

# patch `AtomicU64` issue
patch -p1 < softmixer.patch

# build librespot
cargo fetch --target mipsel-unknown-linux-musl --locked
mkdir .cargo && echo '[target.mipsel-unknown-linux-musl]\nlinker = "mipsel-openwrt-linux-gcc"' > .cargo/config
echo '\n[profile.release]\nlto = "thin"\ndebug = 0\npanic = "abort"\nincremental = false\ncodegen-units = 1\nopt-level = "s"' >> Cargo.toml
cargo build --release --target mipsel-unknown-linux-musl --locked --no-default-features
mipsel-openwrt-linux-strip target/mipsel-unknown-linux-musl/release/librespot

  • copy target/mipsel-unknown-linux-musl/release/librespot to device

Play music

/overlay/librespot -n Linkit7688 -b 160 --disable-audio-cache | aplay -f cd -
  • Use your Spotify client to play remotely

build cpulimit

  • Spotify use Vorbis to encode songs
  • Vorbis decoder on MT7688 costs average 75% CPU
  • librespot uses up to 100% CPU to decrypt music, it causes glitch when musin loading.
  • So use cpulimit to limit CPU usage of librespot and decode music data using sox
git clone https://github.com/opsengine/cpulimit
cd cpulimit

# patch `sys/sysctl.h` not found
sed -i 's/#include <sys\/sysctl.h>//g' src/cpulimit.c

# build
CC=mipsel-openwrt-linux-musl-gcc make
mipsel-openwrt-linux-strip src/cpulimit
  • copy src/cpulimit to device

Play with sox

  • no volume control remotely on Spotify client
  • no glitch
/overlay/cpulimit -e librespot -l 10 &
/overlay/librespot -n Linkit7688 -b 320 --disable-audio-cache --passthrough | play -f ogg -
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment