feat: Audio Preview Player — browse and play WAV samples via Web Audio API

Issue: #9

Backend:
- GET /api/list-wavs?dir=<path> — lists .wav files in a directory
- GET /wavs/<file> — static file serving from ./output/wavs

Web UI:
- WAV Browser section with path input + Browse button
- AudioContext-based playback (zero deps) — progress bar, time display
- WAV file grid with Play buttons, active item highlighting

Tests:
- 3 new tests for handleListWavs (wav files, empty dir, nonexistent dir)
- Fix TestFindAkaiutil: add t.Chdir(tmp) so relative path lookups don't
  accidentally find the repo's third_party/akaiutil/akaiutil binary
This commit is contained in:
2026-06-22 00:01:15 -07:00
parent 120993fb02
commit cf53912a33
6 changed files with 349 additions and 0 deletions
+7
View File
@@ -99,6 +99,8 @@ func TestFindAkaiutil(t *testing.T) {
}()
t.Run("env var set to missing file", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
_ = os.Setenv("AKAIUTIL", "/nonexistent/akaiutil")
os.Args[0] = "/some/binary"
_, err := findAkaiutil()
@@ -109,6 +111,7 @@ func TestFindAkaiutil(t *testing.T) {
t.Run("env var set to existing file", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
f := tmp + "/myutil"
fd, _ := os.Create(f)
defer func() { _ = fd.Close() }()
@@ -124,6 +127,7 @@ func TestFindAkaiutil(t *testing.T) {
t.Run("finds binary next to argv[0]", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
exe := tmp + "/mybinary"
fd, _ := os.Create(exe)
defer func() { _ = fd.Close() }()
@@ -143,6 +147,7 @@ func TestFindAkaiutil(t *testing.T) {
t.Run("finds binary in third_party relative to argv[0]", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
exe := tmp + "/somebin"
fd, _ := os.Create(exe)
defer func() { _ = fd.Close() }()
@@ -166,6 +171,7 @@ func TestFindAkaiutil(t *testing.T) {
t.Run("env var takes priority over path candidates", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
envFile := tmp + "/envutil"
pathFile := tmp + "/pathutil"
fd1, _ := os.Create(envFile)
@@ -185,6 +191,7 @@ func TestFindAkaiutil(t *testing.T) {
t.Run("no akaiutil found returns error", func(t *testing.T) {
tmp := t.TempDir()
t.Chdir(tmp)
exe := tmp + "/nobinaryhere"
fd, _ := os.Create(exe)
defer func() { _ = fd.Close() }()