@ -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 ) )