drops allocation of MixRenderer to 64bytes
This commit is contained in:
parent
b8802449c9
commit
8cc51a435c
2 changed files with 20 additions and 9 deletions
26
src/nodes.jl
26
src/nodes.jl
|
@ -80,6 +80,9 @@ end
|
||||||
|
|
||||||
type MixRenderer <: AudioRenderer
|
type MixRenderer <: AudioRenderer
|
||||||
inputs::Vector{AudioNode}
|
inputs::Vector{AudioNode}
|
||||||
|
buf::AudioBuf
|
||||||
|
|
||||||
|
MixRenderer(inputs) = new(inputs, AudioSample[])
|
||||||
end
|
end
|
||||||
|
|
||||||
typealias AudioMixer AudioNode{MixRenderer}
|
typealias AudioMixer AudioNode{MixRenderer}
|
||||||
|
@ -88,21 +91,23 @@ AudioMixer() = AudioMixer(AudioNode[])
|
||||||
export AudioMixer
|
export AudioMixer
|
||||||
|
|
||||||
function render(node::MixRenderer, device_input::AudioBuf, info::DeviceInfo)
|
function render(node::MixRenderer, device_input::AudioBuf, info::DeviceInfo)
|
||||||
# TODO: we probably want to pre-allocate this buffer and share between
|
if length(node.buf) != info.buf_size
|
||||||
# render calls. Unfortunately we don't know the right size when the object
|
resize!(node.buf, info.buf_size)
|
||||||
# is created, so maybe we check the size on every render call and only
|
end
|
||||||
# re-allocate when the size changes? I suppose that's got to be cheaper
|
mix_buffer = node.buf
|
||||||
# than the GC and allocation every frame
|
|
||||||
|
|
||||||
mix_buffer = zeros(AudioSample, info.buf_size)
|
|
||||||
n_inputs = length(node.inputs)
|
n_inputs = length(node.inputs)
|
||||||
i = 1
|
i = 1
|
||||||
max_samples = 0
|
max_samples = 0
|
||||||
|
fill!(mix_buffer, 0)
|
||||||
while i <= n_inputs
|
while i <= n_inputs
|
||||||
rendered = render(node.inputs[i], device_input, info)::AudioBuf
|
rendered = render(node.inputs[i], device_input, info)::AudioBuf
|
||||||
nsamples = length(rendered)
|
nsamples = length(rendered)
|
||||||
max_samples = max(max_samples, nsamples)
|
max_samples = max(max_samples, nsamples)
|
||||||
mix_buffer[1:nsamples] .+= rendered
|
j::Int = 1
|
||||||
|
while j <= nsamples
|
||||||
|
mix_buffer[j] += rendered[j]
|
||||||
|
j += 1
|
||||||
|
end
|
||||||
if nsamples < info.buf_size
|
if nsamples < info.buf_size
|
||||||
deleteat!(node.inputs, i)
|
deleteat!(node.inputs, i)
|
||||||
n_inputs -= 1
|
n_inputs -= 1
|
||||||
|
@ -110,7 +115,12 @@ function render(node::MixRenderer, device_input::AudioBuf, info::DeviceInfo)
|
||||||
i += 1
|
i += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if max_samples < length(mix_buffer)
|
||||||
return mix_buffer[1:max_samples]
|
return mix_buffer[1:max_samples]
|
||||||
|
else
|
||||||
|
# save the allocate and copy if we don't need to
|
||||||
|
return mix_buffer
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.push!(mixer::AudioMixer, node::AudioNode) = push!(mixer.renderer.inputs, node)
|
Base.push!(mixer::AudioMixer, node::AudioNode) = push!(mixer.renderer.inputs, node)
|
||||||
|
|
|
@ -46,6 +46,7 @@ testnode = TestNode(test_info.buf_size)
|
||||||
mix = AudioMixer([testnode])
|
mix = AudioMixer([testnode])
|
||||||
render_output = render(mix, dev_input, test_info)
|
render_output = render(mix, dev_input, test_info)
|
||||||
@test render_output == AudioSample[1:test_info.buf_size]
|
@test render_output == AudioSample[1:test_info.buf_size]
|
||||||
|
@test 100 > (@allocated render(mix, dev_input, test_info))
|
||||||
|
|
||||||
test1 = TestNode(test_info.buf_size)
|
test1 = TestNode(test_info.buf_size)
|
||||||
test2 = TestNode(test_info.buf_size)
|
test2 = TestNode(test_info.buf_size)
|
||||||
|
|
Loading…
Reference in a new issue