SinOsc{Float32} allocation is way down

This commit is contained in:
Spencer Russell 2014-06-25 21:51:16 -04:00
parent dd49d374fa
commit 7aafc697b0
2 changed files with 27 additions and 12 deletions

View file

@ -16,10 +16,11 @@ end
type SinOscRenderer{T<:Union(Float32, AudioNode)} <: AudioRenderer type SinOscRenderer{T<:Union(Float32, AudioNode)} <: AudioRenderer
freq::T freq::T
phase::Float64 phase::Float32
buf::AudioBuf
function SinOscRenderer(freq) function SinOscRenderer(freq)
new(freq, 0.0) new(freq, 0.0, AudioSample[])
end end
end end
@ -31,12 +32,22 @@ export SinOsc
function render(node::SinOscRenderer{Float32}, device_input::AudioBuf, function render(node::SinOscRenderer{Float32}, device_input::AudioBuf,
info::DeviceInfo) info::DeviceInfo)
outbuf = Array(AudioSample, info.buf_size) if length(node.buf) != info.buf_size
resize!(node.buf, info.buf_size)
end
outbuf = node.buf
phase = node.phase phase = node.phase
dt = 1/info.sample_rate freq = node.freq
for i in 1:info.buf_size # make sure these are Float32s so that we don't allocate doing conversions
# in the tight loop
pii::Float32 = pi
dt::Float32 = 1/info.sample_rate
i::Int = 1
while i <= info.buf_size
outbuf[i] = sin(phase) outbuf[i] = sin(phase)
phase += 2pi*node.freq*dt phase += 2pii*freq*dt
phase = phase % 2pii
i += 1
end end
node.phase = phase node.phase = phase
return outbuf return outbuf

View file

@ -7,9 +7,6 @@ import AudioIO.AudioNode
import AudioIO.DeviceInfo import AudioIO.DeviceInfo
import AudioIO.render import AudioIO.render
test_info = DeviceInfo(44100, 512)
dev_input = zeros(AudioSample, test_info.buf_size)
# A TestNode just renders out 1:buf_size each frame # A TestNode just renders out 1:buf_size each frame
type TestRenderer <: AudioRenderer end type TestRenderer <: AudioRenderer end
@ -22,6 +19,9 @@ function render(node::TestRenderer,
return AudioSample[1:info.buf_size] return AudioSample[1:info.buf_size]
end end
test_info = DeviceInfo(44100, 512)
dev_input = zeros(AudioSample, test_info.buf_size)
#### AudioMixer Tests #### #### AudioMixer Tests ####
# TODO: there should be a setup/teardown mechanism and some way to isolate # TODO: there should be a setup/teardown mechanism and some way to isolate
@ -54,6 +54,9 @@ stop(mix)
render_output = render(mix, dev_input, test_info) render_output = render(mix, dev_input, test_info)
@test render_output == AudioSample[] @test render_output == AudioSample[]
# TODO: I think we can do better than this
const FLOAT_THRESH = 1e-9
info("Testing SinOSC...") info("Testing SinOSC...")
freq = 440 freq = 440
# note that this range includes the end, which is why there are sample_rate+1 samples # note that this range includes the end, which is why there are sample_rate+1 samples
@ -61,10 +64,11 @@ t = linspace(0, 1, test_info.sample_rate+1)
test_vect = convert(AudioBuf, sin(2pi * t * freq)) test_vect = convert(AudioBuf, sin(2pi * t * freq))
osc = SinOsc(freq) osc = SinOsc(freq)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@test render_output == test_vect[1:test_info.buf_size] @test mse(render_output, test_vect[1:test_info.buf_size]) < FLOAT_THRESH
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@test render_output == test_vect[test_info.buf_size+1:2*test_info.buf_size] @test mse(render_output,
@test 50000 > (@allocated render(osc, dev_input, test_info)) test_vect[test_info.buf_size+1:2*test_info.buf_size]) < FLOAT_THRESH
@test 600 > (@allocated render(osc, dev_input, test_info))
stop(osc) stop(osc)
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@test render_output == AudioSample[] @test render_output == AudioSample[]