From 7aafc697b01160db19b546c0e673106a29f1476d Mon Sep 17 00:00:00 2001 From: Spencer Russell Date: Wed, 25 Jun 2014 21:51:16 -0400 Subject: [PATCH] SinOsc{Float32} allocation is way down --- src/nodes.jl | 23 +++++++++++++++++------ test/test_nodes.jl | 16 ++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/nodes.jl b/src/nodes.jl index 9b69337..d71d067 100644 --- a/src/nodes.jl +++ b/src/nodes.jl @@ -16,10 +16,11 @@ end type SinOscRenderer{T<:Union(Float32, AudioNode)} <: AudioRenderer freq::T - phase::Float64 + phase::Float32 + buf::AudioBuf function SinOscRenderer(freq) - new(freq, 0.0) + new(freq, 0.0, AudioSample[]) end end @@ -31,12 +32,22 @@ export SinOsc function render(node::SinOscRenderer{Float32}, device_input::AudioBuf, 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 - dt = 1/info.sample_rate - for i in 1:info.buf_size + freq = node.freq + # 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) - phase += 2pi*node.freq*dt + phase += 2pii*freq*dt + phase = phase % 2pii + i += 1 end node.phase = phase return outbuf diff --git a/test/test_nodes.jl b/test/test_nodes.jl index b321712..f49f1da 100644 --- a/test/test_nodes.jl +++ b/test/test_nodes.jl @@ -7,9 +7,6 @@ import AudioIO.AudioNode import AudioIO.DeviceInfo 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 type TestRenderer <: AudioRenderer end @@ -22,6 +19,9 @@ function render(node::TestRenderer, return AudioSample[1:info.buf_size] end +test_info = DeviceInfo(44100, 512) +dev_input = zeros(AudioSample, test_info.buf_size) + #### AudioMixer Tests #### # 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) @test render_output == AudioSample[] +# TODO: I think we can do better than this +const FLOAT_THRESH = 1e-9 + info("Testing SinOSC...") freq = 440 # 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)) osc = SinOsc(freq) 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) -@test render_output == test_vect[test_info.buf_size+1:2*test_info.buf_size] -@test 50000 > (@allocated render(osc, dev_input, test_info)) +@test mse(render_output, + 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) render_output = render(osc, dev_input, test_info) @test render_output == AudioSample[]