Ver código fonte

fix: struct padding bug in viz loopback, overflow in stopped state

- viz/capture.go: waveFormatExtensibleEx now flat struct (not embedded)
  Go pads waveFormatEx to 20 bytes (uint32 alignment), but the Windows
  C struct is 18 bytes — embedding caused SubFormat to land at wrong
  offset, breaking float32 detection (float=false bug)
- server.go: clamp position/length values > 24h to 0
  Winamp returns 0xFFFFFFFF for these fields when stopped/no track loaded
- .gitignore: exclude winamp/ dir and runtime .dat files
- config.yaml: added (gitignored) pointing to winamp/winamp.exe

Tested: Winamp 5.9 portable in winamp/, IPC connection verified,
viz loopback correctly detects 48kHz float32 stereo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
master
Jan Svabenik 1 mês atrás
pai
commit
1219df3c27
3 arquivos alterados com 31 adições e 6 exclusões
  1. +10
    -0
      .gitignore
  2. +7
    -2
      internal/server/server.go
  3. +14
    -4
      internal/viz/capture.go

+ 10
- 0
.gitignore Ver arquivo

@@ -21,5 +21,15 @@ vendor/
.DS_Store
Thumbs.db

# Dev config (has local paths — use config.yaml.example as template)
config.yaml

# Config with secrets
config.local.yaml

# Portable Winamp (extracted locally for dev — not committed)
winamp/

# Runtime data files
killist.dat
resume.dat

+ 7
- 2
internal/server/server.go Ver arquivo

@@ -266,8 +266,13 @@ func (s *Server) statusMsg() ([]byte, error) {
msg.State = "stopped"
}
msg.Title = s.wa.GetTitle()
msg.Position = s.wa.GetPosition()
msg.Length = s.wa.GetLength()
// Winamp returns 0xFFFFFFFF when stopped/no track — clamp to 0.
pos := s.wa.GetPosition()
length := s.wa.GetLength()
if pos > 86400 { pos = 0 } // > 24h → garbage value
if length > 86400 { length = 0 }
msg.Position = pos
msg.Length = length
msg.PlaylistPos = s.wa.GetPlaylistPosition()
msg.PlaylistLength = s.wa.GetPlaylistLength()
msg.Version = s.wa.GetVersion()


+ 14
- 4
internal/viz/capture.go Ver arquivo

@@ -72,11 +72,21 @@ type waveFormatEx struct {
Size uint16
}

// waveFormatExtensibleEx is a flat representation of WAVEFORMATEXTENSIBLE.
// We cannot embed waveFormatEx because Go pads the struct to 20 bytes
// (alignment of largest field = uint32), but the C layout is 18 bytes —
// so SubFormat would land at the wrong offset if we used struct embedding.
type waveFormatExtensibleEx struct {
Format waveFormatEx
Samples uint16
ChannelMask uint32
SubFormat windows.GUID
FormatTag uint16
Channels uint16
SamplesPerSec uint32
AvgBytesPerSec uint32
BlockAlign uint16
BitsPerSample uint16
Size uint16
Samples uint16 // wValidBitsPerSample / wSamplesPerBlock
ChannelMask uint32
SubFormat windows.GUID // 16 bytes → total 40 bytes, matches C layout
}

// ── DLL procs ─────────────────────────────────────────────────────────────────


Carregando…
Cancelar
Salvar