now SinOsc, AudioMixer, and ArrayPlayer report their active flag properly

This commit is contained in:
Spencer Russell 2014-01-03 13:32:30 -08:00
parent 72fef9e4e1
commit 0f43ff836a
3 changed files with 46 additions and 8 deletions

View file

@ -1,7 +1,7 @@
module AudioIO
# export the basic API
export play
export play, stop
# default stream used when none is given
_stream = nothing
@ -76,4 +76,8 @@ function play{T <: Unsigned}(arr::Array{T}, args...)
play(arr, args...)
end
function stop(node::AudioNode)
node.active = false
end
end # module AudioIO

View file

@ -5,11 +5,12 @@ export SinOsc, AudioMixer, ArrayPlayer, AudioInput
# Generates a sin tone at the given frequency
type SinOsc <: AudioNode
active::Bool
freq::Real
phase::FloatingPoint
function SinOsc(freq::Real)
new(freq, 0.0)
new(true, freq, 0.0)
end
end
@ -17,7 +18,7 @@ function render(node::SinOsc, device_input::AudioBuf, info::DeviceInfo)
phase = AudioSample[1:info.buf_size] * 2pi * node.freq / info.sample_rate
phase += node.phase
node.phase = phase[end]
return sin(phase), true
return sin(phase), node.active
end
#### AudioMixer ####
@ -25,14 +26,15 @@ end
# Mixes a set of inputs equally
type AudioMixer <: AudioNode
active::Bool
mix_inputs::Array{AudioNode}
function AudioMixer{T <: AudioNode}(mix_inputs::Array{T})
new(mix_inputs)
new(true, mix_inputs)
end
function AudioMixer()
new(AudioNode[])
new(true, AudioNode[])
end
end
@ -44,7 +46,7 @@ function render(node::AudioMixer, device_input::AudioBuf, info::DeviceInfo)
in_buffer, active = render(in_node, device_input, info)
mix_buffer += in_buffer
end
return mix_buffer, true
return mix_buffer, node.active
end
#### Array Player ####
@ -52,11 +54,12 @@ end
# Plays a AudioBuf by rendering it out piece-by-piece
type ArrayPlayer <: AudioNode
active::Bool
arr::AudioBuf
arr_index::Int
function ArrayPlayer(arr::AudioBuf)
new(arr, 1)
new(true, arr, 1)
end
end
@ -67,10 +70,13 @@ function render(node::ArrayPlayer, device_input::AudioBuf, info::DeviceInfo)
range_end = min(i + info.buf_size-1, length(node.arr))
output = node.arr[i:range_end]
if length(output) < info.buf_size
# we're finished with the array, pad with zeros and clear our active
# flag
output = vcat(output, zeros(AudioSample, info.buf_size - length(output)))
node.active = false
end
node.arr_index = range_end + 1
return output, true
return output, node.active
end
#### AudioInput ####

View file

@ -38,6 +38,10 @@ render_output, active = AudioIO.render(mix, dev_input, test_info)
@test render_output == 2 * AudioIO.AudioSample[1:test_info.buf_size]
@test active
stop(mix)
render_output, active = AudioIO.render(mix, dev_input, test_info)
@test !active
info("Testing SinOSC...")
freq = 440
t = linspace(1 / test_info.sample_rate,
@ -48,3 +52,27 @@ osc = SinOsc(freq)
render_output, active = AudioIO.render(osc, dev_input, test_info)
@test_approx_eq(render_output, test_vect)
@test active
stop(osc)
render_output, active = AudioIO.render(osc, dev_input, test_info)
@test !active
info("Testing ArrayPlayer...")
v = rand(AudioIO.AudioSample, 44100)
player = ArrayPlayer(v)
render_output, active = AudioIO.render(player, dev_input, test_info)
@test render_output == v[1:test_info.buf_size]
@test active
render_output, active = AudioIO.render(player, dev_input, test_info)
@test render_output == v[(test_info.buf_size + 1) : (2*test_info.buf_size)]
@test active
stop(player)
render_output, active = AudioIO.render(player, dev_input, test_info)
@test !active
# give a vector just a bit larger than 1 buffer size
v = rand(AudioIO.AudioSample, test_info.buf_size + 1)
player = ArrayPlayer(v)
_, active = AudioIO.render(player, dev_input, test_info)
@test active
_, active = AudioIO.render(player, dev_input, test_info)
@test !active