adds ability to wait for an AudioNode
This commit is contained in:
parent
83c4199096
commit
22dba358b8
3 changed files with 41 additions and 18 deletions
|
@ -33,7 +33,7 @@ include("sndfile.jl")
|
||||||
|
|
||||||
# Play an AudioNode by adding it as an input to the root mixer node
|
# Play an AudioNode by adding it as an input to the root mixer node
|
||||||
function play(node::AudioNode, stream::AudioStream)
|
function play(node::AudioNode, stream::AudioStream)
|
||||||
node.active = true
|
activate(node)
|
||||||
add_input(stream.mixer, node)
|
add_input(stream.mixer, node)
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
@ -76,8 +76,27 @@ function play{T <: Unsigned}(arr::Array{T}, args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function stop(node::AudioNode)
|
function stop(node::AudioNode)
|
||||||
|
deactivate(node)
|
||||||
|
node
|
||||||
|
end
|
||||||
|
|
||||||
|
function activate(node::AudioNode)
|
||||||
|
node.active = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function deactivate(node::AudioNode)
|
||||||
node.active = false
|
node.active = false
|
||||||
return node
|
notify(node.deactivate_cond)
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_active(node::AudioNode)
|
||||||
|
node.active
|
||||||
|
end
|
||||||
|
|
||||||
|
function Base.wait(node::AudioNode)
|
||||||
|
if is_active(node)
|
||||||
|
wait(node.deactivate_cond)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end # module AudioIO
|
end # module AudioIO
|
||||||
|
|
25
src/nodes.jl
25
src/nodes.jl
|
@ -6,11 +6,12 @@ export SinOsc, AudioMixer, ArrayPlayer, AudioInput
|
||||||
|
|
||||||
type SinOsc <: AudioNode
|
type SinOsc <: AudioNode
|
||||||
active::Bool
|
active::Bool
|
||||||
|
deactivate_cond::Condition
|
||||||
freq::Real
|
freq::Real
|
||||||
phase::FloatingPoint
|
phase::FloatingPoint
|
||||||
|
|
||||||
function SinOsc(freq::Real)
|
function SinOsc(freq::Real)
|
||||||
new(false, freq, 0.0)
|
new(false, Condition(), freq, 0.0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ function render(node::SinOsc, device_input::AudioBuf, info::DeviceInfo)
|
||||||
phase = AudioSample[1:info.buf_size] * 2pi * node.freq / info.sample_rate
|
phase = AudioSample[1:info.buf_size] * 2pi * node.freq / info.sample_rate
|
||||||
phase += node.phase
|
phase += node.phase
|
||||||
node.phase = phase[end]
|
node.phase = phase[end]
|
||||||
return sin(phase), node.active
|
return sin(phase), is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
#### AudioMixer ####
|
#### AudioMixer ####
|
||||||
|
@ -31,6 +32,7 @@ const MAX_MIXER_INPUTS = 32
|
||||||
|
|
||||||
type AudioMixer <: AudioNode
|
type AudioMixer <: AudioNode
|
||||||
active::Bool
|
active::Bool
|
||||||
|
deactivate_cond::Condition
|
||||||
mix_inputs::Array{MaybeAudioNode}
|
mix_inputs::Array{MaybeAudioNode}
|
||||||
|
|
||||||
function AudioMixer{T <: AudioNode}(mix_inputs::Array{T})
|
function AudioMixer{T <: AudioNode}(mix_inputs::Array{T})
|
||||||
|
@ -39,7 +41,7 @@ type AudioMixer <: AudioNode
|
||||||
for (i, node) in enumerate(mix_inputs)
|
for (i, node) in enumerate(mix_inputs)
|
||||||
input_array[i] = node
|
input_array[i] = node
|
||||||
end
|
end
|
||||||
new(false, input_array)
|
new(false, Condition(), input_array)
|
||||||
end
|
end
|
||||||
|
|
||||||
function AudioMixer()
|
function AudioMixer()
|
||||||
|
@ -87,7 +89,7 @@ function render(node::AudioMixer, device_input::AudioBuf, info::DeviceInfo)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return mix_buffer, node.active
|
return mix_buffer, is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Array Player ####
|
#### Array Player ####
|
||||||
|
@ -96,11 +98,12 @@ end
|
||||||
|
|
||||||
type ArrayPlayer <: AudioNode
|
type ArrayPlayer <: AudioNode
|
||||||
active::Bool
|
active::Bool
|
||||||
|
deactivate_cond::Condition
|
||||||
arr::AudioBuf
|
arr::AudioBuf
|
||||||
arr_index::Int
|
arr_index::Int
|
||||||
|
|
||||||
function ArrayPlayer(arr::AudioBuf)
|
function ArrayPlayer(arr::AudioBuf)
|
||||||
new(false, arr, 1)
|
new(false, Condition(), arr, 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -111,13 +114,12 @@ function render(node::ArrayPlayer, device_input::AudioBuf, info::DeviceInfo)
|
||||||
range_end = min(i + info.buf_size-1, length(node.arr))
|
range_end = min(i + info.buf_size-1, length(node.arr))
|
||||||
output = node.arr[i:range_end]
|
output = node.arr[i:range_end]
|
||||||
if length(output) < info.buf_size
|
if length(output) < info.buf_size
|
||||||
# we're finished with the array, pad with zeros and clear our active
|
# we're finished with the array, pad with zeros and deactivate
|
||||||
# flag
|
|
||||||
output = vcat(output, zeros(AudioSample, info.buf_size - length(output)))
|
output = vcat(output, zeros(AudioSample, info.buf_size - length(output)))
|
||||||
node.active = false
|
deactivate(node)
|
||||||
end
|
end
|
||||||
node.arr_index = range_end + 1
|
node.arr_index = range_end + 1
|
||||||
return output, node.active
|
return output, is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
#### AudioInput ####
|
#### AudioInput ####
|
||||||
|
@ -126,14 +128,15 @@ end
|
||||||
|
|
||||||
type AudioInput <: AudioNode
|
type AudioInput <: AudioNode
|
||||||
active::Bool
|
active::Bool
|
||||||
|
deactivate_cond::Condition
|
||||||
channel::Int
|
channel::Int
|
||||||
|
|
||||||
function AudioInput(channel::Int)
|
function AudioInput(channel::Int)
|
||||||
new(false, channel)
|
new(false, Condition(), channel)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function render(node::AudioInput, device_input::AudioBuf, info::DeviceInfo)
|
function render(node::AudioInput, device_input::AudioBuf, info::DeviceInfo)
|
||||||
@assert size(device_input, 1) == info.buf_size
|
@assert size(device_input, 1) == info.buf_size
|
||||||
return device_input[:, node.channel], node.active
|
return device_input[:, node.channel], is_active(node)
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,10 +91,11 @@ end
|
||||||
|
|
||||||
type FilePlayer <: AudioNode
|
type FilePlayer <: AudioNode
|
||||||
active::Bool
|
active::Bool
|
||||||
|
deactivate_cond::Condition
|
||||||
file::AudioFile
|
file::AudioFile
|
||||||
|
|
||||||
function FilePlayer(file::AudioFile)
|
function FilePlayer(file::AudioFile)
|
||||||
node = new(false, file)
|
node = new(false, Condition(), file)
|
||||||
finalizer(node, node -> close(node.file))
|
finalizer(node, node -> close(node.file))
|
||||||
return node
|
return node
|
||||||
end
|
end
|
||||||
|
@ -110,16 +111,16 @@ function render(node::FilePlayer, device_input::AudioBuf, info::DeviceInfo)
|
||||||
audio = read(node.file, info.buf_size, AudioSample)
|
audio = read(node.file, info.buf_size, AudioSample)
|
||||||
|
|
||||||
if audio == Nothing
|
if audio == Nothing
|
||||||
node.active = false
|
deactivate(node)
|
||||||
return zeros(AudioSample, info.buf_size), node.active
|
return zeros(AudioSample, info.buf_size), is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
# if the file is stereo, mix the two channels together
|
# if the file is stereo, mix the two channels together
|
||||||
if node.file.sfinfo.channels == 2
|
if node.file.sfinfo.channels == 2
|
||||||
return (audio[1, :] / 2) + (audio[2, :] / 2), node.active
|
return (audio[1, :] / 2) + (audio[2, :] / 2), is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
return audio, node.active
|
return audio, is_active(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
function play(filename::String, args...)
|
function play(filename::String, args...)
|
||||||
|
|
Loading…
Reference in a new issue