Browse Source

Close audio devices, gnuplot audio

* Make sure to close audio devices, else the operating system will
think the device is still busy, and no other apps will play audio
* Removed unused code and comments which are likely to get out of sync
* Added audio-dump-recorded-buffer, which outputs in a format gnuplot
can easily read
* Added configuration for a pretty plot of the audio data
master
Macoy Madson 1 month ago
parent
commit
207d1e695a
4 changed files with 84 additions and 37 deletions
  1. +2
    -1
      .gitignore
  2. +44
    -0
      test/AudioPlot.gnuplot
  3. +3
    -0
      test/ViewAudioOutput.sh
  4. +35
    -36
      test/src/VocalGame.cake

+ 2
- 1
.gitignore View File

@ -50,4 +50,5 @@ Dependencies/SDL/
test/100000000PixelShader_ps.glsl
test/100000000VertexShader_vs.glsl
test/SDLOgreApp
test/SDLOgreApp
test/out.dat

+ 44
- 0
test/AudioPlot.gnuplot View File

@ -0,0 +1,44 @@
# set textcolor '#cccccc'
# set the color and font of the text of the axis
text_color = '#c7ae95'
background_color = '#1c2023'
grid_color = '#ff0000'
my_font = "Ubuntu Regular, 12"
my_axis_width = "1.5"
set terminal qt enhanced size 1920,1080 persist title "Vocal Game Audio" ctrl
set xtics textcolor rgb text_color font my_font
set ytics textcolor rgb text_color font my_font
set ztics textcolor rgb text_color font my_font
set title "Vocal Game Audio" textcolor rgb text_color font my_font
set xlabel "Sample index (44.1kHz)" textcolor rgb text_color font my_font
set ylabel "Sample value" textcolor rgb text_color font my_font
# set zlabel "Z Label (unit)" textcolor rgb text_color font my_font
set border 31 lw @my_axis_width lc rgb text_color
# set the text color and font for the label
set label textcolor rgb text_color font my_font
# set the color and width of the axis border
# set border 31 lw @my_axis_width lc rgb text_color
# set key options
# set key outside box width 2 height 2 enhanced spacing 2
set key textcolor rgb text_color
# set grid color
#set grid lc rgb grid_color
# Hack to make QT have programmable background color
# from https://stackoverflow.com/questions/27269578/gnuplot-change-background-color
set object rectangle from screen 0,0 to screen 1,1 behind fillcolor rgb background_color fillstyle solid noborder
set yrange [0:255]
plot 'out.dat' with lines
# Let the user interact with it, e.g. right click drag to zoom in
pause mouse close

+ 3
- 0
test/ViewAudioOutput.sh View File

@ -0,0 +1,3 @@
#!/bin/sh
gnuplot AudioPlot.gnuplot

+ 35
- 36
test/src/VocalGame.cake View File

@ -9,7 +9,7 @@
(add-c-search-directory ".")
(c-import "SDL.h" "SDL_syswm.h" "SDL_timer.h"
"<math.h>")
"<math.h>" "<stdio.h>")
;; TODO: Somehow inherit this from SDL.cake?
(module-use-sdl-build-options)
@ -18,6 +18,18 @@
(var audio-input-write-head int 0)
(var audio-input-read-head int 0)
(defun-local audio-dump-recorded-buffer ()
(var i int 0)
(var dest-file (* FILE) (fopen "out.dat" "w"))
(unless dest-file
(printf "Could not open file to write data\n")
(return))
(while (< i (array-size audio-input-buffer))
(fprintf dest-file "%d %d\n" i (at i audio-input-buffer))
(incr i))
(fclose dest-file))
(defun-local audio-output-callback (userdata (* void) stream (* Uint8) stream-length int)
;; (printf "Audio len %d\n" stream-length)
(static-var up bool false)
@ -30,7 +42,7 @@
(var mono-sample int 127)
;; Square
;; (set mono-sample (? up 255 0))
;; Triangle
;; Sawtooth
;; (set mono-sample (mod (/ i 4) 255))
;; Sine
;; Map to 0-255
@ -103,7 +115,7 @@
(free device-names))
(defun-local initialize-audio (output-device-out (* SDL_AudioDeviceID)
input-device-out (* SDL_AudioDeviceID) &return bool)
input-device-out (* SDL_AudioDeviceID) &return bool)
(scope ;; Drivers
(printf "Available drivers:\n")
(var num-drivers int (SDL_GetNumAudioDrivers))
@ -133,7 +145,6 @@
(set (field desired-spec freq) 44100)
(set (field desired-spec format) AUDIO_U8)
(set (field desired-spec channels) 2) ;; 1 = Mono 2 = Stereo
;; 86 times per second. ~11ms delay (I think)
(set (field desired-spec samples) 512)
(set (field desired-spec callback) audio-output-callback)
;; Use my HDMI output device
@ -145,13 +156,13 @@
(var device-name (* (const char)) (at 2 devices))
(var valid-device-start-num (const int) 2)
(set output-device-id (SDL_OpenAudioDevice
;; null = reasonable default (doesn't work in my case)
device-name
false ;; iscapture
(addr desired-spec) (addr obtained-output-spec)
(bit-or SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
SDL_AUDIO_ALLOW_SAMPLES_CHANGE
SDL_AUDIO_ALLOW_CHANNELS_CHANGE)))
;; null = reasonable default (doesn't work in my case)
device-name
false ;; iscapture
(addr desired-spec) (addr obtained-output-spec)
(bit-or SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
SDL_AUDIO_ALLOW_SAMPLES_CHANGE
SDL_AUDIO_ALLOW_CHANNELS_CHANGE)))
(if (>= output-device-id valid-device-start-num)
(set selected-output-device device-name)
(sdl-print-error)))
@ -164,7 +175,6 @@
(set (field desired-spec freq) 44100)
(set (field desired-spec format) AUDIO_U8)
(set (field desired-spec channels) 1) ;; 1 = Mono 2 = Stereo
;; 86 times per second. ~11ms delay (I think)
(set (field desired-spec samples) 512)
(set (field desired-spec callback) audio-input-callback)
@ -202,30 +212,7 @@
(SDL_PauseAudioDevice input-device-id 0))
(sdl-audio-free-device-list capture-devices num-capture-devices))
;; Pick the first working device
;; This doesn't actually make sense for my case, where the first device does open
;; (var i int 0)
;; (while (< i num-devices)
;; (var device-name (* (const char)) (at i devices))
;; (var valid-device-start-num (const int) 2)
;; (set output-device-id (SDL_OpenAudioDevice
;; ;; null = reasonable default (doesn't work in my case)
;; device-name
;; false ;; iscapture
;; (addr desired-spec) (addr obtained-spec)
;; (bit-or SDL_AUDIO_ALLOW_FREQUENCY_CHANGE
;; SDL_AUDIO_ALLOW_SAMPLES_CHANGE
;; SDL_AUDIO_ALLOW_CHANNELS_CHANGE)))
;; (if (>= output-device-id
;; valid-device-start-num)
;; (block
;; (set selected-device device-name)
;; (break))
;; (block
;; (sdl-print-error)
;; (incr i))))
(when selected-output-device ;; print final settings
(when selected-output-device
(printf "Final output settings:\n")
(printf "device: %s\n" selected-output-device)
(sdl-audio-list-specification (addr obtained-output-spec))
@ -241,6 +228,11 @@
(return (and output-device-id input-device-id)))
(defun-local sdl-audio-close (output-device SDL_AudioDeviceID
input-device SDL_AudioDeviceID)
(SDL_CloseAudioDevice output-device)
(SDL_CloseAudioDevice input-device))
(defun main (&return int)
(var window (* SDL_Window) null)
(unless (sdl-initialize (addr window))
@ -254,6 +246,8 @@
;; Ogre uses exceptions for error handling, so we can't gracefully close without getting all that
;; stuff set up (which I don't really want to do; it belongs in Gamelib)
(unless (ogre-initialize-sdl)
(sdl-audio-close output-device
input-device)
(return 1))
(var monkey-mesh mesh-handle (ogre-load-mesh "Suzanne.mesh"))
@ -313,8 +307,13 @@
(set exit-reason "Failed to render frame")
(break)))
(audio-dump-recorded-buffer)
(ogre-shutdown)
(sdl-audio-close output-device
input-device)
(sdl-shutdown window)
(when exit-reason
(printf "Exit reason: %s\n" exit-reason))
(return 0))

Loading…
Cancel
Save