Files
playback/internal/ui/waveform/render.go
2026-01-25 17:13:15 -06:00

78 lines
1.8 KiB
Go

package waveform
// Block characters for waveform rendering (bottom to top)
var blocks = []rune{' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}
// RenderWaveform converts normalized samples (0-1) to block characters
func RenderWaveform(samples []float64, width int) string {
if len(samples) == 0 {
return ""
}
result := make([]rune, width)
for i := 0; i < width; i++ {
// Map position to sample index
sampleIdx := i * len(samples) / width
if sampleIdx >= len(samples) {
sampleIdx = len(samples) - 1
}
// Get sample value and map to block character
value := samples[sampleIdx]
if value < 0 {
value = 0
}
if value > 1 {
value = 1
}
blockIdx := int(value * float64(len(blocks)-1))
result[i] = blocks[blockIdx]
}
return string(result)
}
// RenderWaveformWithNeedle renders the waveform with a position indicator
func RenderWaveformWithNeedle(samples []float64, width int, position float64) (string, int) {
waveform := RenderWaveform(samples, width)
// Calculate needle position
needlePos := int(position * float64(width))
if needlePos < 0 {
needlePos = 0
}
if needlePos >= width {
needlePos = width - 1
}
return waveform, needlePos
}
// RenderWithColors returns the waveform with the needle position marked
// Returns: left part, needle char, right part
func RenderWithColors(samples []float64, width int, position float64) (string, string, string) {
waveform := []rune(RenderWaveform(samples, width))
if len(waveform) == 0 {
return "", "|", ""
}
needlePos := int(position * float64(len(waveform)))
if needlePos < 0 {
needlePos = 0
}
if needlePos >= len(waveform) {
needlePos = len(waveform) - 1
}
left := string(waveform[:needlePos])
needle := "|"
right := ""
if needlePos+1 < len(waveform) {
right = string(waveform[needlePos+1:])
}
return left, needle, right
}