dropped allocation on SinOsc{AudioNode}

This commit is contained in:
Spencer Russell 2014-06-25 22:40:23 -04:00
parent e451509293
commit 66654d3aaf
2 changed files with 38 additions and 30 deletions

View file

@ -54,15 +54,21 @@ end
function render(node::SinOscRenderer{AudioNode}, device_input::AudioBuf, function render(node::SinOscRenderer{AudioNode}, device_input::AudioBuf,
info::DeviceInfo) info::DeviceInfo)
freq = render(node.freq, device_input, info) freq = render(node.freq, device_input, info)::AudioBuf
block_size = min(length(freq), info.buf_size) block_size = min(length(freq), info.buf_size)
outbuf = Array(AudioSample, block_size) if(length(node.buf) != block_size)
resize!(node.buf, block_size)
end
outbuf = node.buf
phase = node.phase phase::Float32 = node.phase
dt = 1/(info.sample_rate) pi2::Float32 = 2pi
for i in 1:block_size phase_step::Float32 = 2pi/(info.sample_rate)
i::Int = 1
while i <= block_size
outbuf[i] = sin(phase) outbuf[i] = sin(phase)
phase += 2pi*dt*freq[i] phase = (phase + phase_step*freq[i]) % pi2
i += 1
end end
node.phase = phase node.phase = phase
return outbuf return outbuf

View file

@ -55,7 +55,7 @@ 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 # TODO: I think we can do better than this
const FLOAT_THRESH = 1e-9 const MSE_THRESH = 1e-7
info("Testing SinOSC...") info("Testing SinOSC...")
freq = 440 freq = 440
@ -64,34 +64,36 @@ 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 mse(render_output, test_vect[1:test_info.buf_size]) < FLOAT_THRESH @test mse(render_output, test_vect[1:test_info.buf_size]) < MSE_THRESH
render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
@test mse(render_output, @test mse(render_output,
test_vect[test_info.buf_size+1:2*test_info.buf_size]) < FLOAT_THRESH test_vect[test_info.buf_size+1:2*test_info.buf_size]) < MSE_THRESH
@test 200 > (@allocated render(osc, dev_input, test_info)) @test 200 > (@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[]
#info("Testing SinOsc with signal input") info("Testing SinOsc with signal input")
#t = linspace(0, 1, test_info.sample_rate+1) t = linspace(0, 1, test_info.sample_rate+1)
#f = 440 .- t .* (440-110) f = 440 .- t .* (440-110)
#dt = 1 / test_info.sample_rate dt = 1 / test_info.sample_rate
## NOTE - this treats the phase as constant at each sample, which isn't strictly # NOTE - this treats the phase as constant at each sample, which isn't strictly
## true. Unfortunately doing this correctly requires knowing more about the # true. Unfortunately doing this correctly requires knowing more about the
## modulating signal and doing the real integral # modulating signal and doing the real integral
#phase = cumsum(2pi * dt .* f) phase = cumsum(2pi * dt .* f)
#unshift!(phase, 0) unshift!(phase, 0)
#expected = convert(AudioBuf, sin(phase)) expected = convert(AudioBuf, sin(phase))
#
#freq = LinRamp(440, 110, 1) freq = LinRamp(440, 110, 1)
#osc = SinOsc(freq) osc = SinOsc(freq)
#render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
#@test mse(render_output, expected[1:test_info.buf_size]) < FLOAT_THRESH @test mse(render_output, expected[1:test_info.buf_size]) < MSE_THRESH
#render_output = render(osc, dev_input, test_info) render_output = render(osc, dev_input, test_info)
#@test mse(render_output, @test mse(render_output,
# expected[test_info.buf_size+1:2*test_info.buf_size]) < FLOAT_THRESH expected[test_info.buf_size+1:2*test_info.buf_size]) < MSE_THRESH
##@test 400 > (@allocated render(osc, dev_input, test_info)) # give a bigger budget here because we're rendering 2 nodes
println("alloc: ", @allocated render(osc, dev_input, test_info))
@test 500 > (@allocated render(osc, dev_input, test_info))
info("Testing ArrayPlayer...") info("Testing ArrayPlayer...")
v = rand(AudioSample, 44100) v = rand(AudioSample, 44100)
@ -121,8 +123,8 @@ info("Testing LinRamp...")
ramp = LinRamp(0.25, 0.80, 1) ramp = LinRamp(0.25, 0.80, 1)
expected = convert(AudioBuf, linspace(0.25, 0.80, test_info.sample_rate+1)) expected = convert(AudioBuf, linspace(0.25, 0.80, test_info.sample_rate+1))
render_output = render(ramp, dev_input, test_info) render_output = render(ramp, dev_input, test_info)
@test mse(render_output, expected[1:test_info.buf_size]) < FLOAT_THRESH @test mse(render_output, expected[1:test_info.buf_size]) < MSE_THRESH
render_output = render(ramp, dev_input, test_info) render_output = render(ramp, dev_input, test_info)
@test mse(render_output, @test mse(render_output,
expected[(test_info.buf_size+1):(2*test_info.buf_size)]) < FLOAT_THRESH expected[(test_info.buf_size+1):(2*test_info.buf_size)]) < MSE_THRESH
@test 300 > (@allocated render(ramp, dev_input, test_info)) @test 300 > (@allocated render(ramp, dev_input, test_info))