Commit Graph
19 Commits
Author SHA1 Message Date
NeilClack 2212cc9b78 Add audio device switching UI 2026-08-08 00:12:57 -05:00
NeilClack 3480e7594a Replace wpctl volume control with SDL_mixer VolumeMusic
Remove all PipeWire/wpctl system calls (SetDefaultSinkVolume,
listSinkIDs, listSinks, SetAllSinkVolumes, parseSinks, parseSinkLine,
Sink struct). Volume is now managed entirely through SDL_mixer's
VolumeMusic(), making audio fully system-agnostic.

Changes:
- mixer.go: delete ~170 lines of wpctl code; add SetVolume() public
  API using mix.VolumeMusic(math.Round(level * MAX_VOLUME))
- Init/Play/SwitchDevice set volume inline (they already hold the mutex)
- Play() now uses stored currentVolume instead of hardcoded MAX_VOLUME
- AudioOptions: SetAllSinkVolumes -> SetVolume
- mixer_test.go: add TestSetVolume (validation + error path coverage)
2026-07-29 14:58:15 -05:00
NeilClack 7a3b6a66b7 Remove wpctl parsing tests (TestParseSinkLine, TestParseSinks)
These tests cover parseSinkLine and parseSinks, which parse the output of
wpctl status. Both functions will be removed in the next commit as part of
migrating away from PipeWire/wpctl to pure SDL_mixer volume control.
2026-07-29 14:57:32 -05:00
NeilClack e090870b4d fix: SwitchDevice no longer passes 'system default' to SDL
- SwitchDevice: pass '' (empty string) for default device instead of 'system default'
- Fixes 'Device restore path passes invalid device name to SDL' in changelog
2026-07-12 18:16:18 -05:00
NeilClack c98b84a3a8 fix: active device highlight incorrect when using default device
- mixer.Init: convert database 'default' to '' for SDL default device
- AudioOptions.Init: fallback to first SDL device when current device is default
  and config stores 'default'

Fixes known issue from changelog.txt
2026-07-12 18:15:41 -05:00
NeilClack bb132ceeaf fix: resolve 4 critical audio mixer bugs (v0.5)
- SwitchDevice volume silently zeroed: Init uses cfg.SavedVolume,
  SwitchDevice restores saved volume after reopening device
- SwitchDevice not persisted to database: caller saves SelectedAudioDevice
- Device restore passes invalid 'system default' to SDL: now passes ''
- Stop() no-op when audio toggled off: removed AudioEnabled guard

Regression tests added for all 4 bugs. CI now runs go test before build.
2026-07-11 11:39:58 -05:00
NeilClack 72910e7006 fix: prevent Play() deadlock when device is not open
Play() held mu then called SwitchDevice() which also tried to acquire mu,
causing a deadlock. Replace with direct call to openDeviceLocked() which
does not lock.

Add regression test that verifies Play() returns an error (not deadlock)
when called on an uninitialized mixer.
2026-07-11 10:16:15 -05:00
NeilClack 9bc0fd6820 fix: restore SDL volume to MAX after device switch
Remove dead 'currentVolume' variable that was never written to, causing
SwitchDevice to always restore volume to 0 after switching audio devices.

- Remove currentVolume from package state
- SwitchDevice now sets mix.MAX_VOLUME after reopening device
- GetVolume128 now queries SDL directly instead of reading stale variable
- Fix parseSinkLine not stripping trailing ']' from [vol: X.XX] (caused
  volume to silently parse as 0 for sinks without MUTED tag)
- Fix flake.nix: make wayland/X11 buildInputs Linux-only for macOS compat
- Add unit tests for parseSinks, parseSinkLine, and ConvertVolume
- Add changelog.txt tracking all audio bug fixes
2026-07-10 14:00:33 -05:00
NeilClack 2bcb36669f fix: restore SDL volume to MAX after device switch
Remove dead 'currentVolume' variable that was never written to, causing
SwitchDevice to always restore volume to 0 after switching audio devices.

- Remove currentVolume from package state
- SwitchDevice now sets mix.MAX_VOLUME after reopening device
- GetVolume128 now queries SDL directly instead of reading stale variable
- Add unit tests for parseSinks, parseSinkLine, and ConvertVolume
- Add changelog.txt tracking all audio bug fixes
2026-07-10 13:56:06 -05:00
NeilClack 2735af5fbb refactor: remove cached AppConfig pointer and read configuration directly from DB
Replace in-memory atomic AppConfig caching with direct DB queries via db.GetConfig
across application and page layers. This simplifies state management and ensures
all components always operate on the latest persisted configuration.

Key changes:
- Remove Application.Config atomic cache and refreshCache mechanism
- Eliminate PageCtx.CfgPtr and pass DB handle instead
- Replace all cfg reads with db.GetConfig(app.DB)
- Update mixer, audio, UI pages, and initialization paths accordingly
- Explicitly set AppConfig table name to avoid GORM pluralization issues
- Reduce DB connection pooling (SetMaxIdleConns(1))
- Standardize application font to SpaceMonoNerdFont-Regular
- Lower default audio volume (1.0 → 0.2)
- Add Unicode checkmark glyph to font map

Behavioral impact:
- Configuration is no longer cached in memory
- Every config access now hits the DB (more consistent, slightly more overhead)
2026-06-26 22:51:32 -05:00
NeilClack 732bd7c9a0 Update audio options page to display outputs 2026-06-23 13:52:44 -05:00
NeilClack 3ea32e0eaa Add volume changing logic 2026-05-14 09:57:13 -05:00
NeilClack 10ba5df132 Force re-initialization of audio device when Play() is called 2026-04-23 17:29:21 -05:00
NeilClack c8756d0528 Recurse if inited but no deviceOpen 2026-04-23 17:29:21 -05:00
NeilClack 05a7098886 Remove devices list and device vector length check 2026-04-23 17:26:22 -05:00
NeilClack aea646f788 Set default volume to MAX
Set MAX volume for SDL2 Mixer, as well as the volume for all audio sinks via wpctl to 1.0.
This forces the computer to always be at absolute max volume, without creating scripts on the machine to run wpctl commands. Leaving the display or connected speakers to be in full control over the volume of music.
2026-03-30 00:08:52 -05:00
NeilClack 205b068fbf Fix audio bug 2026-03-25 17:17:22 -05:00
NeilClack 17c088cc2f Update Database
Database is more usable now.
All pages have been updated to use the database, and share an application configuration.
Page Stack has been removed, no more pages hanging around in memory. Replaced with a 'Router' which uses an Enum to determine which page should be displayed, destroys the old page and initializes the new page all in one go. No more push, pop, rollback, etc. No more holding instances of pages.
Logger has been updated with proper timestamps and sorting now works as expected."
2026-03-23 15:02:07 -05:00
NeilClack 403ec4db89 Initial release: RadiantWave v1.0 2026-03-12 08:05:10 -05:00