visualizers

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package visualizers holds the pluggable Visualizer implementations rendered on top of the now-playing view when the user toggles on the visualizer pane.

The Visualizer interface

Each visualizer implements Visualizer: a small contract of Init (new track), Advance (per-frame tick), and View (render). Optional capability interfaces extend what a visualizer can see:

  • AudioAware receives per-frame FrequencyData from the FFT pipeline.
  • ProgressAware receives playback progress in ms (for time-aligned visuals like lyrics scroll).
  • ImageAware receives the current track's album art (for AlbumArt).
  • LyricsAware receives the track's lyric lines (for Lyrics).

A visualizer opts in by implementing the matching capability interface; the ui package's visualizerModel pushes data to everything that opts in.

Current implementations

Album art and lyrics panels work without an audio source. Spectrum, Oscillogram, Spectrogram, VU meter, Starfield, and the four Milkdrop-style shaders (Spiral, Tunnel, Kaleidoscope, Ripple) need real-time PCM, so they're only useful when librespot + pipe backend is active.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MusicNoteFallback

func MusicNoteFallback() image.Image

Types

type AlbumArt

type AlbumArt struct {
	// contains filtered or unexported fields
}

func NewAlbumArt

func NewAlbumArt() *AlbumArt

func (*AlbumArt) Advance

func (a *AlbumArt) Advance()

func (*AlbumArt) Init

func (a *AlbumArt) Init(seed string, durationMs int)

func (*AlbumArt) SetImage

func (a *AlbumArt) SetImage(img image.Image)

func (*AlbumArt) View

func (a *AlbumArt) View(width, height int) string

type AudioAware

type AudioAware interface {
	SetAudioData(data *audio.FrequencyData)
}

AudioAware is implemented by visualizers that consume real-time frequency data.

type BeatDetector added in v0.1.1

type BeatDetector struct {
	TempoMul float64 // 0.4–1.6, maps BPM to speed multiplier
	Pulse    float64 // 1.0 on beat, decays toward 0
	// contains filtered or unexported fields
}

BeatDetector uses spectral flux with an adaptive threshold to detect beats and estimate tempo. Embed in any visualizer that needs tempo-aware behavior.

func (*BeatDetector) Reset added in v0.1.1

func (bd *BeatDetector) Reset()

Reset clears all beat state. Call on track change or Init.

func (*BeatDetector) Tick added in v0.1.1

func (bd *BeatDetector) Tick(bands *[audio.NumBands]float32, progressMs int32)

Tick decays the pulse and processes a new frame of frequency bands. Call once per frame with the full band data and playback progress.

type ImageAware

type ImageAware interface {
	SetImage(img image.Image)
}

type Lyrics

type Lyrics struct {
	// contains filtered or unexported fields
}

func NewLyrics

func NewLyrics() *Lyrics

func (*Lyrics) Advance

func (l *Lyrics) Advance()

func (*Lyrics) Init

func (l *Lyrics) Init(seed string, durationMs int)

func (*Lyrics) SetInstrumental

func (l *Lyrics) SetInstrumental()

func (*Lyrics) SetLyrics

func (l *Lyrics) SetLyrics(lines []string)

func (*Lyrics) SetProgress

func (l *Lyrics) SetProgress(progressMs int)

func (*Lyrics) View

func (l *Lyrics) View(width, height int) string

type LyricsAware

type LyricsAware interface {
	SetLyrics(lines []string)
	SetInstrumental()
}

LyricsAware is implemented by visualizers that display lyrics.

type MilkdropPreset

type MilkdropPreset struct {
	// contains filtered or unexported fields
}

MilkdropPreset is a Milkdrop-style visualizer driven by a pluggable warp function. Use the NewMilkdrop* constructors to create specific presets.

func NewMilkdropKaleidoscope

func NewMilkdropKaleidoscope() *MilkdropPreset

NewMilkdropKaleidoscope creates a Milkdrop preset that folds the framebuffer into mirror-symmetric sectors. Bass shifts the number of segments.

func NewMilkdropRipple

func NewMilkdropRipple() *MilkdropPreset

NewMilkdropRipple creates a Milkdrop preset that displaces pixels along radial sine waves, creating expanding concentric ripples.

func NewMilkdropSpiral

func NewMilkdropSpiral() *MilkdropPreset

NewMilkdropSpiral creates a Milkdrop preset that warps the framebuffer in a rotating spiral. Bass tightens the spiral; time adds a slow drift.

func NewMilkdropTunnel

func NewMilkdropTunnel() *MilkdropPreset

NewMilkdropTunnel creates a Milkdrop preset using inverse-radius mapping to produce an infinite tunnel rushing toward the viewer.

func (*MilkdropPreset) Advance

func (m *MilkdropPreset) Advance()

func (*MilkdropPreset) Init

func (m *MilkdropPreset) Init(seed string, durationMs int)

func (*MilkdropPreset) SetAudioData

func (m *MilkdropPreset) SetAudioData(data *audio.FrequencyData)

func (*MilkdropPreset) View

func (m *MilkdropPreset) View(w, h int) string

type Oscillogram

type Oscillogram struct {
	// contains filtered or unexported fields
}

func NewOscillogram

func NewOscillogram() *Oscillogram

func (*Oscillogram) Advance

func (o *Oscillogram) Advance()

func (*Oscillogram) Init

func (o *Oscillogram) Init(seed string, durationMs int)

func (*Oscillogram) SetAudioData

func (o *Oscillogram) SetAudioData(data *audio.FrequencyData)

func (*Oscillogram) View

func (o *Oscillogram) View(width, height int) string

type ProgressAware

type ProgressAware interface {
	SetProgress(progressMs int)
}

ProgressAware is implemented by visualizers that need real-time playback progress.

type Spectrogram added in v0.3.0

type Spectrogram struct {
	// contains filtered or unexported fields
}

func NewSpectrogram added in v0.3.0

func NewSpectrogram() *Spectrogram

func (*Spectrogram) Advance added in v0.3.0

func (s *Spectrogram) Advance()

Advance appends the current frame to the ring buffer. With live audio we mix the new bands into the previous frame via EMA so frame-to-frame noise doesn't drive the quadrant ranker into visible flicker. Without audio we push a decayed copy so the image keeps scrolling with a visible fade instead of freezing.

func (*Spectrogram) Init added in v0.3.0

func (s *Spectrogram) Init(seed string, durationMs int)

func (*Spectrogram) SetAudioData added in v0.3.0

func (s *Spectrogram) SetAudioData(data *audio.FrequencyData)

func (*Spectrogram) View added in v0.3.0

func (s *Spectrogram) View(width, height int) string

type Spectrum

type Spectrum struct {
	// contains filtered or unexported fields
}

Spectrum renders a classic spectrum analyzer with vertical bars and peak hold indicators.

func NewSpectrum

func NewSpectrum() *Spectrum

func (*Spectrum) Advance

func (s *Spectrum) Advance()

func (*Spectrum) Init

func (s *Spectrum) Init(seed string, durationMs int)

func (*Spectrum) SetAudioData

func (s *Spectrum) SetAudioData(data *audio.FrequencyData)

func (*Spectrum) View

func (s *Spectrum) View(width, height int) string

type Starfield

type Starfield struct {
	// contains filtered or unexported fields
}

func NewStarfield

func NewStarfield() *Starfield

func (*Starfield) Advance

func (sf *Starfield) Advance()

func (*Starfield) Init

func (sf *Starfield) Init(seed string, durationMs int)

func (*Starfield) SetAudioData

func (sf *Starfield) SetAudioData(data *audio.FrequencyData)

func (*Starfield) View

func (sf *Starfield) View(width, height int) string

type VUMeter added in v0.5.0

type VUMeter struct {
	// contains filtered or unexported fields
}

VUMeter renders two analog-style VU meters (LEFT and RIGHT) driven by FrequencyData.LeftLevel / RightLevel. Needle ballistics approximate the classic IEC ~300 ms integration time. The dB scale is −20…+3 mapped piecewise so the positive segment occupies more angular space than its dB range alone would warrant; cell color follows the same green→purple sweep that the band visualizers use.

func NewVUMeter added in v0.5.0

func NewVUMeter() *VUMeter

func (*VUMeter) Advance added in v0.5.0

func (v *VUMeter) Advance()

func (*VUMeter) Init added in v0.5.0

func (v *VUMeter) Init(seed string, durationMs int)

func (*VUMeter) SetAudioData added in v0.5.0

func (v *VUMeter) SetAudioData(data *audio.FrequencyData)

func (*VUMeter) View added in v0.5.0

func (v *VUMeter) View(width, height int) string

type Visualizer

type Visualizer interface {
	Init(seed string, durationMs int)
	Advance()
	View(width, height int) string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL