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 }