Add exponential smoothing and interpolation

Signed-off-by: Skylar "The Cobra" Widulski <cobra@vern.cc>
This commit is contained in:
Skylar "The Cobra" Widulski 2023-12-22 10:18:15 -05:00
parent 357df0bbfa
commit 454c940ab0
Signed by: cobra
GPG Key ID: 4FD8F812083FF6F9
3 changed files with 51 additions and 13 deletions

View File

@ -24,10 +24,15 @@ Below is a list of values and what they do
* `bgcolor`: Background color
* `queue-size`: The size of the queue (minimum of 1), delays displaying bars by `queue-size` frames. Useful if desync is noticed
* `fft`: Whether or not to perform a fourier transform to show frequencies (like `spectrum` mode in most other visualizers)
* `fft-interpolation`: Number of points to interpolate between fft values. <1 means disable
* `smoothing`: Smoothing mode. Possible values are:
* `#f`: No smoothing
* `moving-average`: Moving average
* `#f`: No smoothing or interpolation. Disregards `fft-interpolation`
* `'none`: No smoothing
* `'moving-average`: Moving average
* `'exponential`: Simple (basic) exponential smoothing
* `moving-average-block-size`: Size of the moving average window. Higher is smoother.
* `exponential-factor`: Exponential smoothing factor, lower is more smooth.
* `exponential-init-factor`: The first value of the exponentially smoothed list is multiplied by this
# Running
Either install libyammer.so and yammer.h to their respective systemwide locations, or do the following:
@ -42,7 +47,7 @@ guile -L . yammer.scm
# Wishlist
* Native PulseAudio and PipeWire sources
* More smoothing modes
* More smoothing modes (one that actually works would be nice)
* Average over `resolution`
* Offload some calculations to the GPU

View File

@ -7,5 +7,8 @@
(define bgcolor #x2e2016ff)
(define queue-size 1)
(define fft #f)
(define smoothing-mode 'moving-average)
(define fft-interpolation 0)
(define smoothing-mode 'none)
(define moving-average-block-size 25)
(define exponential-factor 0.5)
(define exponential-init-factor 10)

View File

@ -112,9 +112,10 @@
(make-rect
(floor i) 0
(* (ceiling/ x (length plst)) resolution)
;; Math to make scale a sane value
(- y-mid (abs (round/ (* y (car (list-ref plst j)))
(/ 76800 scale)))))
;; Math to make `scale' a sane value
(exact
(- y-mid (abs (round/ (* y (car (list-ref plst j)))
(/ 76800 scale))))))
bgcolor)
;; This value is used twice, define in let statement
(let ((n (abs (round/ (* y (cadr (list-ref plst j)))
@ -122,9 +123,10 @@
(fill-rect
surf
(make-rect
(floor i) (+ y-mid n)
(floor i) (exact (+ y-mid n))
(* (ceiling/ x (length plst)) resolution)
(- y-mid n))
(exact
(- y-mid n)))
bgcolor)))))
;; Create texture from surface
(define texture (surface->texture ren surf))
@ -137,18 +139,46 @@
;; Smooth non-chunked list `lst' with mode `type'
(define (smooth lst type)
(define input lst)
(define ret '())
(define window 0)
(if (> fft-interpolation 0)
;; Interpolate FFT values
(begin
(set! input '())
(do ((i 0 (1+ i)))
((>= (1+ i) (length lst)))
(set! input (append input (list (list-ref lst i))))
(do ((j 0 (1+ j)))
((> j fft-interpolation))
(let ((n (- (list-ref lst (1+ i)) (list-ref lst i))))
(set! input (append input (list (* (expt (1+ j) (/ n 100000))
(list-ref lst i))))))))))
(cond
((eq? type 'moving-average)
(do ((i 1 (1+ i)))
((>= i (- (length lst) moving-average-block-size)))
(set! window (list-ref lst (- i 1)))
((>= i (- (length input) moving-average-block-size)))
(set! window (list-ref input (- i 1)))
(do ((j 0 (1+ j)))
((>= j moving-average-block-size))
(set! window (+ window (list-ref lst (+ i j)))))
(set! window (+ window (list-ref input (+ i j)))))
(set! window (round/ window moving-average-block-size))
(set! ret (append ret (list window))))))
(set! ret (append ret (list window)))))
((eq? type 'exponential)
(do ((i 0 (1+ i)))
((>= i (length input)))
(if (= i 0)
(set! ret (list (* exponential-init-factor (car input))))
(set! ret
(append
ret
(list
(/ (+ (list-ref ret (1- i))
(* exponential-factor
(- (list-ref input i)
(list-ref ret (1- i)))))
(/ (log (log (expt i 2))) (log 3)))))))))
(else (set! ret input)))
ret)
;; Run loop