diff --git a/catnip.go b/catnip.go index 08b11a2..580b7d6 100644 --- a/catnip.go +++ b/catnip.go @@ -63,6 +63,7 @@ func catnip(cfg *config) error { SampleSize: cfg.sampleSize, ChannelCount: cfg.channelCount, FrameRate: cfg.frameRate, + InvertDraw: cfg.invertDraw, Buffers: inputBuffers, Analyzer: dsp.NewAnalyzer(anlzConfig), Smoother: dsp.NewSmoother(anlzConfig), @@ -233,6 +234,7 @@ func doFlags(cfg *config) bool { parser.Int(&cfg.spaceSize, "sw", "space", "space width [0, +Inf)") parser.Int(&cfg.drawType, "dt", "draw", "draw type (1, 2, 3, 4, 5, 6)") parser.Bool(&cfg.useThreaded, "t", "threaded", "use the threaded processor") + parser.Bool(&cfg.invertDraw, "i", "invert", "invert the direction of bin drawing") fg, bg, center := graphic.DefaultStyles().AsUInt16s() parser.UInt16(&fg, "fg", "foreground", diff --git a/config.go b/config.go index 51682c8..762998b 100644 --- a/config.go +++ b/config.go @@ -41,6 +41,8 @@ type config struct { combine bool // Use threaded processor useThreaded bool + // Invert the order of bin drawing + invertDraw bool // DrawType is the draw type styles graphic.Styles } diff --git a/graphic/display.go b/graphic/display.go index c0b7d15..5638c82 100644 --- a/graphic/display.go +++ b/graphic/display.go @@ -259,28 +259,28 @@ func (d *Display) fillStyleBuffer(left, center, right int) { } // Draw takes data and draws. -func (d *Display) Draw(bufs [][]float64, channels, count int, scale float64) error { +func (d *Display) Draw(bufs [][]float64, channels, count int, scale float64, invert bool) error { d.wg.Add(channels) switch d.drawType { case DrawUp: - d.DrawUp(bufs, count, scale) + d.DrawUp(bufs, count, scale, invert) case DrawUpDown: - d.DrawUpDown(bufs, count, scale) + d.DrawUpDown(bufs, count, scale, invert) case DrawDown: - d.DrawDown(bufs, count, scale) + d.DrawDown(bufs, count, scale, invert) case DrawLeft: - d.DrawLeft(bufs, count, scale) + d.DrawLeft(bufs, count, scale, invert) case DrawLeftRight: - d.DrawLeftRight(bufs, count, scale) + d.DrawLeftRight(bufs, count, scale, invert) case DrawRight: - d.DrawRight(bufs, count, scale) + d.DrawRight(bufs, count, scale, invert) default: return nil @@ -384,7 +384,7 @@ func sizeAndCap(value float64, space int, zeroBase bool, baseRune rune) (int, ru // DRAWING METHODS // DrawUp will draw up. -func (d *Display) DrawUp(bins [][]float64, count int, scale float64) { +func (d *Display) DrawUp(bins [][]float64, count int, scale float64, invert bool) { barSpace := intMax(d.termHeight-d.baseSize, 0) scale = float64(barSpace) / scale @@ -400,6 +400,11 @@ func (d *Display) DrawUp(bins [][]float64, count int, scale float64) { for xBar := 0; xBar < count; xBar++ { xBin := (xBar * (1 - xSet)) + (((count - 1) - xBar) * xSet) + + if invert { + xBin = count - 1 - xBin + } + start, bCap := sizeAndCap(chBins[xBin]*scale, barSpace, true, BarRuneV) xCol := (xBar * d.binSize) + (channelWidth * xSet) + edgeOffset @@ -420,7 +425,7 @@ func (d *Display) DrawUp(bins [][]float64, count int, scale float64) { } // DrawUpDown will draw up and down. -func (d *Display) DrawUpDown(bins [][]float64, count int, scale float64) { +func (d *Display) DrawUpDown(bins [][]float64, count int, scale float64, invert bool) { centerStart := intMax((d.termHeight-d.baseSize)/2, 0) centerStop := centerStart + d.baseSize @@ -440,7 +445,12 @@ func (d *Display) DrawUpDown(bins [][]float64, count int, scale float64) { rCap = BarRune } - xCol := xBar*d.binSize + edgeOffset + xCol := xBar + if invert { + xCol = count - 1 - xCol + } + + xCol = xCol*d.binSize + edgeOffset lCol := intMin(xCol+d.barSize, d.termWidth) for ; xCol < lCol; xCol++ { @@ -462,7 +472,7 @@ func (d *Display) DrawUpDown(bins [][]float64, count int, scale float64) { } // DrawDown will draw down. -func (d *Display) DrawDown(bins [][]float64, count int, scale float64) { +func (d *Display) DrawDown(bins [][]float64, count int, scale float64, invert bool) { barSpace := intMax(d.termHeight-d.baseSize, 0) scale = float64(barSpace) / scale @@ -478,6 +488,11 @@ func (d *Display) DrawDown(bins [][]float64, count int, scale float64) { for xBar := 0; xBar < count; xBar++ { xBin := (xBar * (1 - xSet)) + (((count - 1) - xBar) * xSet) + + if invert { + xBin = count - 1 - xBin + } + stop, bCap := sizeAndCap(chBins[xBin]*scale, barSpace, false, BarRune) if stop += d.baseSize; stop >= d.termHeight { stop = d.termHeight @@ -501,7 +516,7 @@ func (d *Display) DrawDown(bins [][]float64, count int, scale float64) { } } -func (d *Display) DrawLeft(bins [][]float64, count int, scale float64) { +func (d *Display) DrawLeft(bins [][]float64, count int, scale float64, invert bool) { barSpace := intMax(d.termWidth-d.baseSize, 0) scale = float64(barSpace) / scale @@ -516,6 +531,11 @@ func (d *Display) DrawLeft(bins [][]float64, count int, scale float64) { for xBar := 0; xBar < count; xBar++ { xBin := (xBar * (1 - xSet)) + (((count - 1) - xBar) * xSet) + + if invert { + xBin = count - 1 - xBin + } + start, bCap := sizeAndCap(chBins[xBin]*scale, barSpace, true, BarRune) xRow := (xBar * d.binSize) + (channelWidth * xSet) + edgeOffset @@ -536,7 +556,7 @@ func (d *Display) DrawLeft(bins [][]float64, count int, scale float64) { } // DrawLeftRight will draw left and right. -func (d *Display) DrawLeftRight(bins [][]float64, count int, scale float64) { +func (d *Display) DrawLeftRight(bins [][]float64, count int, scale float64, invert bool) { centerStart := intMax((d.termWidth-d.baseSize)/2, 0) centerStop := centerStart + d.baseSize @@ -558,7 +578,13 @@ func (d *Display) DrawLeftRight(bins [][]float64, count int, scale float64) { rCap = BarRuneH } - xRow := xBar*d.binSize + edgeOffset + xRow := xBar + if invert { + xRow = count - 1 - xRow + } + + xRow = xRow*d.binSize + edgeOffset + lRow := intMin(xRow+d.barSize, d.termHeight) for ; xRow < lRow; xRow++ { @@ -578,7 +604,7 @@ func (d *Display) DrawLeftRight(bins [][]float64, count int, scale float64) { } } -func (d *Display) DrawRight(bins [][]float64, count int, scale float64) { +func (d *Display) DrawRight(bins [][]float64, count int, scale float64, invert bool) { barSpace := intMax(d.termWidth-d.baseSize, 0) scale = float64(barSpace) / scale @@ -593,6 +619,11 @@ func (d *Display) DrawRight(bins [][]float64, count int, scale float64) { for xBar := 0; xBar < count; xBar++ { xBin := (xBar * (1 - xSet)) + (((count - 1) - xBar) * xSet) + + if invert { + xBin = count - 1 - xBin + } + stop, bCap := sizeAndCap(chBins[xBin]*scale, barSpace, false, BarRuneH) if stop += d.baseSize; stop >= d.termWidth { stop = d.termWidth diff --git a/processor/processor.go b/processor/processor.go index 4aabf2a..2a2d444 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -37,7 +37,7 @@ type Smoother interface { type Display interface { Bars(...int) int - Draw([][]float64, int, int, float64) error + Draw([][]float64, int, int, float64, bool) error } type Processor interface { @@ -51,6 +51,7 @@ type Config struct { SampleSize int // number of samples per buffer ChannelCount int // number of channels FrameRate int // target framerate + InvertDraw bool // invert the direction of bin drawing Buffers [][]input.Sample // sample buffers Analyzer Analyzer // audio analyzer Smoother Smoother // time smoother @@ -63,6 +64,8 @@ type processor struct { bars int + invertDraw bool + slowWindow *util.MovingWindow fastWindow *util.MovingWindow @@ -88,6 +91,7 @@ func New(cfg Config) *processor { vis := &processor{ channelCount: cfg.ChannelCount, frameRate: cfg.FrameRate, + invertDraw: cfg.InvertDraw, slowWindow: util.NewMovingWindow(slowSize), fastWindow: util.NewMovingWindow(fastSize), fftBufs: make([][]complex128, cfg.ChannelCount), @@ -177,7 +181,7 @@ func (vis *processor) Process(ctx context.Context, kickChan chan bool, mu *sync. } } - vis.disp.Draw(vis.barBufs, vis.channelCount, vis.bars, scale) + vis.disp.Draw(vis.barBufs, vis.channelCount, vis.bars, scale, vis.invertDraw) select { case <-ctx.Done(): diff --git a/processor/threaded.go b/processor/threaded.go index dbcb7ca..6a6c2dc 100644 --- a/processor/threaded.go +++ b/processor/threaded.go @@ -16,6 +16,8 @@ type threadedProcessor struct { bars int + invertDraw bool + slowWindow *util.MovingWindow fastWindow *util.MovingWindow @@ -45,6 +47,7 @@ func NewThreaded(cfg Config) *threadedProcessor { vis := &threadedProcessor{ channelCount: cfg.ChannelCount, + invertDraw: cfg.InvertDraw, slowWindow: util.NewMovingWindow(slowSize), fastWindow: util.NewMovingWindow(fastSize), fftBufs: make([][]complex128, cfg.ChannelCount), @@ -161,5 +164,5 @@ func (vis *threadedProcessor) Process(ctx context.Context, kickChan chan bool, m } } - vis.disp.Draw(vis.barBufs, vis.channelCount, vis.bars, scale) + vis.disp.Draw(vis.barBufs, vis.channelCount, vis.bars, scale, vis.invertDraw) }