wip: park audio-crackle investigation + haptic/OLED defaults + debug tooling
Preserves in-progress work that had been sitting uncommitted in the working tree (predates this session) so it is protected in git history. This is NOT a verified/shipped fix — it is parked. Audio path is unverified on hardware and still carries debug instrumentation. - src/audio.cpp: drop the 512->480 resampler and retime the 0x36 frame to a true 10ms/100Hz grid (SAMPLE_SIZE 64->60, 480-sample buffer) to chase the ~45kHz-vs-48kHz speaker underrun theory behind the crackle; dynamic speaker sub-report offset; debug printf + Opus-frame-dump instrumentation. - src/config.cpp: default audio_buffer_length 64->16; auto_haptics_enable default 1 (Fallback) -> 0 (Off). - src/oled.cpp: chunked non-blocking SPI flush (issue #7 OLED-stall angle) and a battery-% midpoint display tweak. - scripts/: audio debug helpers (opus-dump decode, pi audio test, sine ch1/2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
71cead401d
commit
84393c00e8
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Send a 440 Hz sine wave on channels 1+2 only (speaker), silence on 3+4 (haptic).
|
||||
|
||||
Usage: python3 scripts/sine_ch12.py [seconds]
|
||||
"""
|
||||
import subprocess, struct, math, sys, re
|
||||
|
||||
RATE = 48000
|
||||
FREQ = 440
|
||||
DURATION = int(sys.argv[1]) if len(sys.argv) > 1 else 5
|
||||
CHANNELS = 4
|
||||
SAMPLES = RATE * DURATION
|
||||
|
||||
# Generate 4-channel S16_LE: sine on ch1+ch2, silence on ch3+ch4
|
||||
data = bytearray()
|
||||
for i in range(SAMPLES):
|
||||
val = int(6000 * math.sin(2 * math.pi * FREQ * i / RATE)) # ~-15 dBFS (was 32767 / 0 dBFS) — clipping test
|
||||
s = struct.pack('<h', val)
|
||||
data += s + s + b'\x00\x00' + b'\x00\x00' # L, R, hapL=0, hapR=0
|
||||
|
||||
# Auto-detect the dongle's ALSA card — it enumerates as "DualSense Wireless
|
||||
# Controller", and the card number shifts across reboots, so never hardcode it.
|
||||
def find_dualsense_card():
|
||||
out = subprocess.check_output(['aplay', '-l'], text=True)
|
||||
for line in out.splitlines():
|
||||
m = re.match(r'card (\d+):', line)
|
||||
if m and 'DualSense' in line:
|
||||
return int(m.group(1))
|
||||
return None
|
||||
|
||||
card = find_dualsense_card()
|
||||
if card is None:
|
||||
print("DualSense dongle not found in `aplay -l` — paired and enumerated?", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
device = f'hw:{card},0'
|
||||
print(f"Playing to {device} (DualSense dongle)")
|
||||
|
||||
proc = subprocess.Popen(
|
||||
['aplay', '-D', device, '-f', 'S16_LE', '-c', '4', '-r', '48000', '-'],
|
||||
stdin=subprocess.PIPE
|
||||
)
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.close()
|
||||
proc.wait()
|
||||
print(f"Played {DURATION}s of {FREQ} Hz sine on ch1+ch2 (speaker only)")
|
||||
Reference in New Issue
Block a user