Browse Source

Normalize audio after recording

* Discovered problem where recording device is sampled at a higher
  rate than playback device. I'll need to resample in order to
  playback properly
* Added some missing audio-close places
* Monkey now moves forward/backward depending on loudness of sample
pitch-detection
Macoy Madson 3 years ago
parent
commit
2d8eef273b
  1. 67
      test/src/VocalGame.cake

67
test/src/VocalGame.cake

@ -47,13 +47,15 @@
;; Sawtooth
;; (set mono-sample (mod (/ i 4) 255))
;; Sine
;; Map to 0-255
;; (set mono-sample (+ 127 (* 127
;; ;; Map to -1 to +1
;; (sin
;; ;; Map from position in buffer to 2pi range
;; (/ (* i 2 pi) (type-cast samples-per-channel float))))))
;; (set mono-sample
;; ;; Map to 0-255
;; (+ 127 (* 127
;; ;; Map to -1 to +1
;; (sin
;; ;; Map from position in buffer to 2pi range
;; (/ (* i 2 pi) (type-cast samples-per-channel float))))))
;; Loop playback
(if audio-is-recording
(set mono-sample 127) ;; Silence
(block ;; Else, play the recording
@ -70,6 +72,7 @@
(set i (+ i num-channels)))
(set audio-input-read-head (mod (+ audio-input-read-head samples-per-channel) (array-size audio-input-buffer))))
;; TODO: If input is sampled at a different rate, playback will be at a lower pitch
(defun-local audio-input-callback (userdata (* void) stream (* Uint8) stream-length int)
(unless audio-is-recording
(return))
@ -232,8 +235,8 @@
(defun-local sdl-audio-close (output-device SDL_AudioDeviceID
input-device SDL_AudioDeviceID)
(SDL_CloseAudioDevice output-device)
(SDL_CloseAudioDevice input-device))
(when (>= output-device 2) (SDL_CloseAudioDevice output-device))
(when (>= input-device 2) (SDL_CloseAudioDevice input-device)))
(defun main (&return int)
(var window (* SDL_Window) null)
@ -243,6 +246,8 @@
(var output-device SDL_AudioDeviceID 0)
(var input-device SDL_AudioDeviceID 0)
(unless (initialize-audio (addr output-device) (addr input-device))
(sdl-shutdown window)
(sdl-audio-close output-device input-device)
(return 1))
;; Ogre uses exceptions for error handling, so we can't gracefully close without getting all that
@ -287,7 +292,40 @@
(when (at SDL_SCANCODE_DOWN currentKeyStates)
(set (at 1 delta-position) (- (at 1 delta-position) move-speed)))
(var prev-recording-value bool audio-is-recording)
(set audio-is-recording (at SDL_SCANCODE_SPACE currentKeyStates))
(when (and (!= prev-recording-value audio-is-recording)
(not audio-is-recording))
;; Normalize audio
;; Note: peak in both low and high, never greater than range / 2
(var highest-peak Uint8 0)
(var i int 0)
(while (< i (array-size audio-input-buffer))
(var current-value int (- (type-cast (at i audio-input-buffer) int) 127))
(when (< highest-peak (abs current-value))
(set highest-peak (abs current-value)))
(incr i))
(when highest-peak
;; Get within 90% of the peak, to avoid clipping
(var desired-high-peak (const int) (* (/ 256 2) 0.9f))
(var scaling-factor float (/ desired-high-peak (type-cast highest-peak float)))
(printf "Scaling recording %.4f because desired = %d and highest was %d\n"
scaling-factor desired-high-peak highest-peak)
(var scaling-limit float 6.f)
;; If there's only silence, you don't want to go crazy with boosting it
(when (> scaling-factor scaling-limit)
(printf "scaling limited to %f\n" scaling-limit)
(set scaling-factor scaling-limit))
(when scaling-factor
(set i 0)
(while (< i (array-size audio-input-buffer))
(var current-value int (- (type-cast (at i audio-input-buffer) int) 127))
(set (at i audio-input-buffer) (type-cast
;; Map back to 0-255
(+ 127.f
(* current-value scaling-factor))
Uint8))
(incr i)))))
(var current-counter-ticks Uint64 (SDL_GetPerformanceCounter))
(var frame-diff-ticks Uint64 (- current-counter-ticks last-frame-perf-count))
@ -295,13 +333,20 @@
(type-cast counter-num-ticks-per-second float)))
;; (printf "%lu %f\n" frame-diff-ticks delta-time)
(var read-head float (* 20.f
;; Visualize audio playback
(var audio-read-head-to-world float (* 20.f
(/ audio-input-read-head
(type-cast (array-size audio-input-buffer) float))))
(var audio-volume-to-world float (* 7.f
(/ (- (at audio-input-read-head audio-input-buffer) 127)
127.f)))
(set x (+ x (* delta-time (at 0 delta-position))))
(set y (+ y (* delta-time (at 1 delta-position))))
(set z (+ z (* delta-time (at 2 delta-position))))
(ogre-node-set-position (addr monkey-node) (+ read-head x) y z)
(ogre-node-set-position (addr monkey-node) (+ audio-read-head-to-world x)
y
(+ audio-volume-to-world z))
(set last-frame-perf-count (SDL_GetPerformanceCounter))

Loading…
Cancel
Save