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 * `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 * `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`: 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: * `smoothing`: Smoothing mode. Possible values are:
* `#f`: No smoothing * `#f`: No smoothing or interpolation. Disregards `fft-interpolation`
* `moving-average`: Moving average * `'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. * `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 # Running
Either install libyammer.so and yammer.h to their respective systemwide locations, or do the following: 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 # Wishlist
* Native PulseAudio and PipeWire sources * Native PulseAudio and PipeWire sources
* More smoothing modes * More smoothing modes (one that actually works would be nice)
* Average over `resolution` * Average over `resolution`
* Offload some calculations to the GPU * Offload some calculations to the GPU

View File

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

View File

@ -112,9 +112,10 @@
(make-rect (make-rect
(floor i) 0 (floor i) 0
(* (ceiling/ x (length plst)) resolution) (* (ceiling/ x (length plst)) resolution)
;; Math to make scale a sane value ;; Math to make `scale' a sane value
(- y-mid (abs (round/ (* y (car (list-ref plst j))) (exact
(/ 76800 scale))))) (- y-mid (abs (round/ (* y (car (list-ref plst j)))
(/ 76800 scale))))))
bgcolor) bgcolor)
;; This value is used twice, define in let statement ;; This value is used twice, define in let statement
(let ((n (abs (round/ (* y (cadr (list-ref plst j))) (let ((n (abs (round/ (* y (cadr (list-ref plst j)))
@ -122,9 +123,10 @@
(fill-rect (fill-rect
surf surf
(make-rect (make-rect
(floor i) (+ y-mid n) (floor i) (exact (+ y-mid n))
(* (ceiling/ x (length plst)) resolution) (* (ceiling/ x (length plst)) resolution)
(- y-mid n)) (exact
(- y-mid n)))
bgcolor))))) bgcolor)))))
;; Create texture from surface ;; Create texture from surface
(define texture (surface->texture ren surf)) (define texture (surface->texture ren surf))
@ -137,18 +139,46 @@
;; Smooth non-chunked list `lst' with mode `type' ;; Smooth non-chunked list `lst' with mode `type'
(define (smooth lst type) (define (smooth lst type)
(define input lst)
(define ret '()) (define ret '())
(define window 0) (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 (cond
((eq? type 'moving-average) ((eq? type 'moving-average)
(do ((i 1 (1+ i))) (do ((i 1 (1+ i)))
((>= i (- (length lst) moving-average-block-size))) ((>= i (- (length input) moving-average-block-size)))
(set! window (list-ref lst (- i 1))) (set! window (list-ref input (- i 1)))
(do ((j 0 (1+ j))) (do ((j 0 (1+ j)))
((>= j moving-average-block-size)) ((>= 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! 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) ret)
;; Run loop ;; Run loop