Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a17da67
digital parts
napowderly Sep 6, 2025
8ded63a
checkin layout
napowderly Sep 8, 2025
dad4443
checkin
napowderly Sep 12, 2025
8d276de
tidy up
napowderly Sep 12, 2025
0e92cfe
remove some local packages
nickkrstevski Sep 12, 2025
7d8fb90
layout checkin
napowderly Sep 13, 2025
7ea31c2
Merge remote-tracking branch 'refs/remotes/origin/dsp-1u' into dsp-1u
napowderly Sep 13, 2025
e482242
ethernet layout
napowderly Sep 13, 2025
d0903a0
building with dsp
nickkrstevski Sep 13, 2025
aad9773
Merge branch 'dsp-1u' of github.com:atopile/dsp into dsp-1u
nickkrstevski Sep 13, 2025
3760c31
organized local packages, imported in ato yaml
nickkrstevski Sep 19, 2025
a002aa2
wiggly in place
nickkrstevski Sep 20, 2025
1a6e18d
layout progress
nickkrstevski Sep 20, 2025
9a17b00
almost done with layout
nickkrstevski Sep 20, 2025
ab8e970
almost done layout, 90%
nickkrstevski Sep 20, 2025
4f1188a
all connections made
nickkrstevski Sep 20, 2025
f9590e0
layout ready to generate manufacturing outputs
nickkrstevski Sep 22, 2025
5d0eede
fix all f a b r y k _ c o n v e r t errors in parts
nickkrstevski Oct 4, 2025
6f7b330
repour after build
nickkrstevski Oct 4, 2025
fe32dfa
changes complete, ready for review
nickkrstevski Oct 6, 2025
eeac213
cleanup layout and fix pads
napowderly Oct 7, 2025
2d12260
shipped board
napowderly Oct 8, 2025
b6eb068
Firmware: Base starting point
iopapamanoglou Nov 7, 2025
9b46d46
sigma project
iopapamanoglou Nov 7, 2025
2a2c3e1
checkin before breaking layout
nickkrstevski Nov 8, 2025
828008e
Merge branch 'dsp-1u' of github.com:atopile/dsp into dsp-1u
nickkrstevski Nov 8, 2025
a3cd07f
fw
iopapamanoglou Nov 14, 2025
7a2fa38
webserver wip
iopapamanoglou Nov 14, 2025
e74bcd9
fix ad1938
iopapamanoglou Nov 14, 2025
b897c1f
fix selfhost
iopapamanoglou Nov 14, 2025
c78af07
enable spi in config
iopapamanoglou Nov 14, 2025
7650db1
setup volume control
iopapamanoglou Nov 15, 2025
d417903
new fw
iopapamanoglou Nov 17, 2025
d12ba4d
publish ti drv-135 and xlr-connector packages, upgrade dependencies t…
nickkrstevski Jan 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
900 changes: 372 additions & 528 deletions .cursor/rules/ato.mdc

Large diffs are not rendered by default.

899 changes: 371 additions & 528 deletions .windsurf/rules/ato.md

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions TDM/measure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

set -e
HOST=nonos-4

DIR=$(dirname $0)
NAME=$1

if [ -z "$NAME" ]; then
NAME=in
fi

Fs=48000
T=60
FMT=S32_LE
DEV="CARD=sndrpigooglevoi,DEV=0"
CH=2

Tr=$((T - 5))

TMPWAV=/tmp/tone.wav
TMPIN=/tmp/in.wav

sox -n -r $Fs -b 32 -c $CH $DIR/tone.wav synth $T sine 996.826 vol -3dB
rsync $DIR/tone.wav $HOST:$TMPWAV

ssh $HOST "aplay -D hw:$DEV -r $Fs -f $FMT -c $CH $TMPWAV" &
ssh $HOST "arecord -D hw:$DEV -r $Fs -f $FMT -c $CH -d $Tr $TMPIN"

rsync $HOST:$TMPIN $DIR/$NAME.wav

uv run --script measure_tdm.py $DIR/$NAME.wav
110 changes: 110 additions & 0 deletions TDM/measure_tdm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!uv run --script
# /// script
# dependencies = [
# "numpy",
# "soundfile",
# "typer",
# ]
# ///

"""
Measure THD+N of a captured audio file.
"""

from pathlib import Path
import numpy as np
import soundfile as sf
import typer


def thd_thdn(x, fs, f0_hint=1000.0, bw=(20, 20000), max_h=10, nb=5):
# x can be (N,) or (N,C)
x = np.asarray(x)
if x.ndim == 2:
rms = np.sqrt(np.mean(x**2, axis=0))
x = x[:, int(np.argmax(rms))]
assert np.isfinite(x).all(), "Input has NaNs/Inf"
x = x - np.mean(x)

# pick N (power of two, not larger than input)
N = 1 << (len(x) - 1).bit_length()
if N > len(x):
N >>= 1
x = x[:N]
if N < 4096:
raise ValueError("Not enough samples")

w = np.hanning(N)
X = np.fft.rfft(x * w)
freqs = np.fft.rfftfreq(N, 1 / fs)
P = np.abs(X) ** 2 # consistent power units for ratios

# bandlimit
bw_lo, bw_hi = bw[0], (bw[1] if bw[1] is not None else fs / 2)
inband = (freqs >= max(20, freqs[1])) & (freqs <= bw_hi)

# find fundamental near hint (±5%)
kband = (freqs >= 0.95 * f0_hint) & (freqs <= 1.05 * f0_hint)
if not np.any(kband):
kband = inband
k0 = np.flatnonzero(kband)[np.argmax(P[kband])]

# integrate the fundamental mainlobe (±nb bins)
kf0_lo = max(0, k0 - nb)
kf0_hi = min(len(P), k0 + nb + 1)
V1p = np.sum(P[kf0_lo:kf0_hi])
if V1p <= 1e-24:
raise ValueError("Fundamental too small or not found.")

# THD: sum power in harmonic mainlobes (within Nyquist & band)
harm_p = 0.0
f0 = freqs[k0]
for k in range(2, max_h + 1):
fk = k * f0
if fk >= fs / 2 or fk > bw_hi:
break
hk = np.argmin(np.abs(freqs - fk))
lo = max(0, hk - nb)
hi = min(len(P), hk + nb + 1)
harm_p += np.sum(P[lo:hi])

THD = np.sqrt(harm_p) / np.sqrt(V1p)

# THD+N: everything in band except the fundamental mainlobe
residual = inband.copy()
residual[kf0_lo:kf0_hi] = False
# (optional) notch mains:
for hz in (50, 60, 100, 120, 150, 180):
j = np.argmin(np.abs(freqs - hz))
residual[max(0, j - 1) : min(len(P), j + 2)] = False

THDN = np.sqrt(np.sum(P[residual])) / np.sqrt(V1p)

thd_db = -np.inf if THD == 0 else 20 * np.log10(THD)
thdn_db = -np.inf if THDN == 0 else 20 * np.log10(THDN)

fund_dbfs = 20 * np.log10(
np.sqrt(np.sum(np.abs(X[kf0_lo:kf0_hi]) ** 2))
/ (np.sqrt(np.sum(np.abs(X) ** 2)) + 1e-20)
)
noise_dbfs = 20 * np.log10(
np.sqrt(np.sum(P[residual])) / (np.sqrt(np.sum(np.abs(X) ** 2)) + 1e-20)
)
print(f"Fund ~{fund_dbfs:.1f} dBFS, Residual ~{noise_dbfs:.1f} dBFS")

sinad_db = -20 * np.log10(THDN) # same bandwidth as THD+N
enob = (sinad_db - 1.76) / 6.02
print(f"SINAD {sinad_db:.1f} dB, ENOB {enob:.2f} bits")

return THD, thd_db, THDN, thdn_db


def main(file: Path):
x, fs = sf.read(file, always_2d=True)
x = x[:, 0]
THD, thd_db, THDN, thdn_db = thd_thdn(x, fs, f0_hint=997.0, bw=(20, 20000))
print(THD, thd_db, THDN, thdn_db)


if __name__ == "__main__":
typer.run(main)
22 changes: 0 additions & 22 deletions ato.yaml

This file was deleted.

29 changes: 29 additions & 0 deletions firmware/dsp_server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Setup

```bash
# rsync nonos_server to nonos
rsync -a dsp_server nonos:
ssh <pi_hostname> "cd dsp_server && ./setup.sh"
```

## Bluetooth

Enable `FastConnectable=y` in `/etc/bluetooth/main.conf`
Make pairable and trust all devices:

Not sure about those:

```
[General]
AutoEnable=true
Class = 0x200414
DiscoverableTimeout = 0
PairableTimeout = 0
JustWorksRepairing = always
```

# Broken

- bluetooth only works after login with ssh
- vnc stuff, see setup.sh (needs manual vncpasswd set)

Loading
Loading