fix: add portaudio to LD_LIBRARY_PATH and add flake lockfile
Move LD_LIBRARY_PATH out of env block and include portaudio so audio devices are discoverable at runtime. Add flake.lock and a quick microphone test script. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Generated
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1779786838,
|
||||
"narHash": "sha256-0geHoGiR5f8qiXg+gO4rSF6Up6Var+kKqiOv9AO/uUc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "f44f7788c891fbe5542177df78374f8cdab10e8f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -21,11 +21,10 @@
|
||||
cudaPackages.cudatoolkit
|
||||
];
|
||||
|
||||
env = {
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
|
||||
pkgs.cudaPackages.cudatoolkit
|
||||
];
|
||||
};
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [
|
||||
pkgs.portaudio
|
||||
pkgs.cudaPackages.cudatoolkit
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
"""Quick microphone tests. Run: uv run python test_mic.py"""
|
||||
|
||||
import numpy as np
|
||||
import sounddevice as sd
|
||||
import sys
|
||||
import time
|
||||
|
||||
SAMPLE_RATE = 16000
|
||||
|
||||
|
||||
def test_device_info():
|
||||
"""Show which device will be used for recording."""
|
||||
default_input = sd.default.device[0]
|
||||
info = sd.query_devices(default_input)
|
||||
print(f"Default input device [{default_input}]: {info['name']}")
|
||||
print(f" Max input channels: {info['max_input_channels']}")
|
||||
print(f" Default sample rate: {info['default_samplerate']}")
|
||||
assert info["max_input_channels"] > 0, "Default device has no input channels!"
|
||||
print(" PASS\n")
|
||||
|
||||
|
||||
def test_record_1s():
|
||||
"""Record 1 second and check we got non-silent audio."""
|
||||
print("Recording 1 second... (speak or make noise!)")
|
||||
audio = sd.rec(SAMPLE_RATE, samplerate=SAMPLE_RATE, channels=1, dtype="float32")
|
||||
sd.wait()
|
||||
audio = audio.flatten()
|
||||
|
||||
peak = np.max(np.abs(audio))
|
||||
rms = np.sqrt(np.mean(audio ** 2))
|
||||
print(f" Samples: {len(audio)}")
|
||||
print(f" Peak amplitude: {peak:.4f}")
|
||||
print(f" RMS: {rms:.6f}")
|
||||
|
||||
assert len(audio) == SAMPLE_RATE, f"Expected {SAMPLE_RATE} samples, got {len(audio)}"
|
||||
assert peak > 0, "All zeros — mic not capturing anything"
|
||||
if peak < 0.001:
|
||||
print(" WARNING: Very low signal — mic might be muted or too far away")
|
||||
else:
|
||||
print(" Signal level looks good")
|
||||
print(" PASS\n")
|
||||
|
||||
|
||||
def test_record_levels():
|
||||
"""Record 3 seconds in 1-second chunks, show live levels."""
|
||||
print("Recording 3 seconds — speak during seconds 2-3 for comparison...")
|
||||
for i in range(3):
|
||||
audio = sd.rec(SAMPLE_RATE, samplerate=SAMPLE_RATE, channels=1, dtype="float32")
|
||||
sd.wait()
|
||||
audio = audio.flatten()
|
||||
rms = np.sqrt(np.mean(audio ** 2))
|
||||
peak = np.max(np.abs(audio))
|
||||
bar = "#" * int(min(peak * 200, 50))
|
||||
print(f" Second {i+1}: peak={peak:.4f} rms={rms:.6f} |{bar}")
|
||||
print(" PASS\n")
|
||||
|
||||
|
||||
def test_stream_callback():
|
||||
"""Test that InputStream callback fires correctly."""
|
||||
frames_received = []
|
||||
|
||||
def callback(indata, frames, time_info, status):
|
||||
if status:
|
||||
print(f" Status: {status}")
|
||||
frames_received.append(len(indata))
|
||||
|
||||
print("Testing InputStream callback for 1 second...")
|
||||
with sd.InputStream(samplerate=SAMPLE_RATE, channels=1, dtype="float32",
|
||||
callback=callback, blocksize=800):
|
||||
time.sleep(1)
|
||||
|
||||
total_frames = sum(frames_received)
|
||||
expected = SAMPLE_RATE
|
||||
print(f" Callbacks fired: {len(frames_received)}")
|
||||
print(f" Total frames: {total_frames} (expected ~{expected})")
|
||||
print(f" Blocksize per callback: {frames_received[0] if frames_received else 'N/A'}")
|
||||
assert len(frames_received) > 0, "No callbacks received!"
|
||||
assert abs(total_frames - expected) < expected * 0.2, f"Frame count off by >20%"
|
||||
print(" PASS\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Microphone Tests ===\n")
|
||||
test_device_info()
|
||||
test_record_1s()
|
||||
test_record_levels()
|
||||
test_stream_callback()
|
||||
print("All tests passed!")
|
||||
Reference in New Issue
Block a user