Fix audio bug

This commit is contained in:
NeilClack
2026-03-25 17:17:22 -05:00
parent 8763f70452
commit 205b068fbf
5 changed files with 33 additions and 57 deletions
+1
View File
@@ -100,6 +100,7 @@ func Run() {
AssetsDir: dataDir, AssetsDir: dataDir,
SystemLevel: "BASIC", SystemLevel: "BASIC",
SelectedAudioDevice: "default", SelectedAudioDevice: "default",
SelectedAudio: "audio.wav",
InitialFontSize: 128, InitialFontSize: 128,
StandardFontSize: 32, StandardFontSize: 32,
LinePattern: "fibonacci", LinePattern: "fibonacci",
+18 -22
View File
@@ -43,32 +43,27 @@ func Init(cfg *db.AppConfig, onUpdate func()) error {
refreshCacheCallback = onUpdate refreshCacheCallback = onUpdate
// Let SDL choose the best audio driver for the system
// Remove hardcoded ALSA preference to support PulseAudio, PipeWire, etc.
// Users can set SDL_AUDIODRIVER environment variable if needed
if err := sdl.InitSubSystem(sdl.INIT_AUDIO); err != nil { if err := sdl.InitSubSystem(sdl.INIT_AUDIO); err != nil {
return fmt.Errorf("SDL audio init failed: %w", err) return fmt.Errorf("SDL audio init failed: %w", err)
} }
// WAV-only does not require mix.Init(); add when you support OGG/MP3/etc. // FIX 1: Initialize MP3 and OGG decoders
err := mix.Init(mix.INIT_MP3 | mix.INIT_OGG)
if err != nil {
logger.Error("Failed to initialize MP3/OGG support: %v", err)
}
if err := openDeviceLocked(cfg.SelectedAudioDevice); err != nil { if err := openDeviceLocked(cfg.SelectedAudioDevice); err != nil {
// Clean up the subsystem on failure so callers can retry later.
sdl.QuitSubSystem(sdl.INIT_AUDIO) sdl.QuitSubSystem(sdl.INIT_AUDIO)
return err return err
} }
// TODO: Check if this logic is still needed; move to application // FIX 2: Actually set a default volume!
// if lastVolume < 0 { currentVolume = 128 // MAX_VOLUME
// lastVolume = int(mix.MAX_VOLUME) if cfg.LastVolume > 0 {
// currentVolume = lastVolume currentVolume = cfg.LastVolume
// if err := db.SetConfigValue("last_volume", strconv.Itoa(lastVolume)); err != nil { }
// } mix.VolumeMusic(currentVolume)
// } else {
// currentVolume = lastVolume
// }
// mix.VolumeMusic(currentVolume)
inited = true inited = true
return nil return nil
@@ -109,9 +104,11 @@ func Play(path string, loopForever bool, cfg *db.AppConfig) error {
defer mu.Unlock() defer mu.Unlock()
if !inited || !deviceOpen { if !inited || !deviceOpen {
logger.Error("audio mixer not initialized")
return errors.New("audio mixer not initialized") return errors.New("audio mixer not initialized")
} }
if path == "" { if path == "" {
logger.Error("empty audio path")
return errors.New("empty audio path") return errors.New("empty audio path")
} }
@@ -134,10 +131,7 @@ func Play(path string, loopForever bool, cfg *db.AppConfig) error {
currentLoops = 0 currentLoops = 0
} }
// Open the device // DELETE the openDeviceLocked block that was here!
if err := openDeviceLocked(deviceName); err != nil {
logger.Error("Failed to open device: %w", err)
}
// Apply remembered volume // Apply remembered volume
mix.VolumeMusic(currentVolume) mix.VolumeMusic(currentVolume)
@@ -145,6 +139,7 @@ func Play(path string, loopForever bool, cfg *db.AppConfig) error {
if err := currentMusic.Play(currentLoops); err != nil { if err := currentMusic.Play(currentLoops); err != nil {
currentMusic.Free() currentMusic.Free()
currentMusic = nil currentMusic = nil
logger.Error("music.Play failed: %v", err)
return fmt.Errorf("music.Play: %w", err) return fmt.Errorf("music.Play: %w", err)
} }
return nil return nil
@@ -331,8 +326,9 @@ func Shutdown() {
mix.CloseAudio() mix.CloseAudio()
deviceOpen = false deviceOpen = false
} }
// If you add mix.Init(decoderFlags) in the future, pair it with mix.Quit() here.
if inited { if inited {
mix.Quit() // Add this to clean up the decoders
sdl.QuitSubSystem(sdl.INIT_AUDIO) sdl.QuitSubSystem(sdl.INIT_AUDIO)
inited = false inited = false
} }
-26
View File
@@ -1,26 +0,0 @@
package netreq
import (
"fmt"
"testing"
"rhemawavetech.com/rhemawave/internal/db"
)
func TestGet(t *testing.T) {
url := "http://localhost:5173/api/v1/proclamations"
// Explicitly tell GetJSON to return a slice of db.Proclamation
proclamations, err := GetJSON[db.Proclamation](url)
if err != nil {
t.Fatalf("GetJSON failed: %v", err)
}
if len(proclamations) == 0 {
t.Fatal("GetJSON returned no records")
}
// You can now inspect the actual struct fields instead of raw strings
fmt.Printf("Fetched %d records. First ID: %s\n", len(proclamations), proclamations[0].ID)
}
+6 -6
View File
@@ -301,14 +301,14 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
} }
// Start audio playback // Start audio playback
selectedAudio := p.Base.Context.CfgPtr.SelectedAudio
// selectedAudio := p.Base.Context.CfgPtr.SelectedAudio
assetsDir := p.Base.Context.CfgPtr.AssetsDir assetsDir := p.Base.Context.CfgPtr.AssetsDir
audioFile := filepath.Join(assetsDir, "audio/audio.wav")
if selectedAudio == "" { logger.Info("Attempting to play %s", audioFile)
} else { if err := mixer.Play(audioFile, true, p.Base.Context.CfgPtr); err != nil {
if err := mixer.Play(filepath.Join(assetsDir, selectedAudio), true, p.Base.Context.CfgPtr); err != nil { logger.Error("Mixer returned an error: %v", err) // ADD THIS
}
} }
currentDevice := mixer.CurrentDevice() currentDevice := mixer.CurrentDevice()
+8 -3
View File
@@ -37,9 +37,12 @@ package mix
//} //}
//#endif //#endif
import "C" import "C"
import "unsafe" import (
import "reflect" "reflect"
import "github.com/veandco/go-sdl2/sdl" "unsafe"
"github.com/veandco/go-sdl2/sdl"
)
// Chunk is the internal format for an audio chunk. // Chunk is the internal format for an audio chunk.
// (https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_85.html) // (https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer_85.html)
@@ -212,6 +215,7 @@ func LoadWAV(file string) (chunk *Chunk, err error) {
chunk = (*Chunk)(unsafe.Pointer(C.Mix_LoadWAV_RW(C.SDL_RWFromFile(_file, _rb), 1))) chunk = (*Chunk)(unsafe.Pointer(C.Mix_LoadWAV_RW(C.SDL_RWFromFile(_file, _rb), 1)))
if chunk == nil { if chunk == nil {
err = sdl.GetError() err = sdl.GetError()
return nil, err
} }
return return
} }
@@ -224,6 +228,7 @@ func LoadMUS(file string) (mus *Music, err error) {
mus = (*Music)(unsafe.Pointer(C.Mix_LoadMUS(_file))) mus = (*Music)(unsafe.Pointer(C.Mix_LoadMUS(_file)))
if mus == nil { if mus == nil {
err = sdl.GetError() err = sdl.GetError()
return nil, err
} }
return return
} }