From 22dba358b8c9cfa278d5a98bc03a5e9d07a7cfeb Mon Sep 17 00:00:00 2001 From: Spencer Russell Date: Mon, 13 Jan 2014 19:19:56 -0500 Subject: [PATCH] adds ability to wait for an AudioNode --- src/AudioIO.jl | 23 +++++++++++++++++++++-- src/nodes.jl | 25 ++++++++++++++----------- src/sndfile.jl | 11 ++++++----- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/AudioIO.jl b/src/AudioIO.jl index a786d12..a9ee241 100644 --- a/src/AudioIO.jl +++ b/src/AudioIO.jl @@ -33,7 +33,7 @@ include("sndfile.jl") # Play an AudioNode by adding it as an input to the root mixer node function play(node::AudioNode, stream::AudioStream) - node.active = true + activate(node) add_input(stream.mixer, node) return node end @@ -76,8 +76,27 @@ function play{T <: Unsigned}(arr::Array{T}, args...) end function stop(node::AudioNode) + deactivate(node) + node +end + +function activate(node::AudioNode) + node.active = true +end + +function deactivate(node::AudioNode) 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 # module AudioIO diff --git a/src/nodes.jl b/src/nodes.jl index 2f98f97..ce2cb62 100644 --- a/src/nodes.jl +++ b/src/nodes.jl @@ -6,11 +6,12 @@ export SinOsc, AudioMixer, ArrayPlayer, AudioInput type SinOsc <: AudioNode active::Bool + deactivate_cond::Condition freq::Real phase::FloatingPoint function SinOsc(freq::Real) - new(false, freq, 0.0) + new(false, Condition(), freq, 0.0) 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 += node.phase node.phase = phase[end] - return sin(phase), node.active + return sin(phase), is_active(node) end #### AudioMixer #### @@ -31,6 +32,7 @@ const MAX_MIXER_INPUTS = 32 type AudioMixer <: AudioNode active::Bool + deactivate_cond::Condition mix_inputs::Array{MaybeAudioNode} function AudioMixer{T <: AudioNode}(mix_inputs::Array{T}) @@ -39,7 +41,7 @@ type AudioMixer <: AudioNode for (i, node) in enumerate(mix_inputs) input_array[i] = node end - new(false, input_array) + new(false, Condition(), input_array) end function AudioMixer() @@ -87,7 +89,7 @@ function render(node::AudioMixer, device_input::AudioBuf, info::DeviceInfo) end end end - return mix_buffer, node.active + return mix_buffer, is_active(node) end #### Array Player #### @@ -96,11 +98,12 @@ end type ArrayPlayer <: AudioNode active::Bool + deactivate_cond::Condition arr::AudioBuf arr_index::Int function ArrayPlayer(arr::AudioBuf) - new(false, arr, 1) + new(false, Condition(), arr, 1) 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)) 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 + # we're finished with the array, pad with zeros and deactivate output = vcat(output, zeros(AudioSample, info.buf_size - length(output))) - node.active = false + deactivate(node) end node.arr_index = range_end + 1 - return output, node.active + return output, is_active(node) end #### AudioInput #### @@ -126,14 +128,15 @@ end type AudioInput <: AudioNode active::Bool + deactivate_cond::Condition channel::Int function AudioInput(channel::Int) - new(false, channel) + new(false, Condition(), channel) end end function render(node::AudioInput, device_input::AudioBuf, info::DeviceInfo) @assert size(device_input, 1) == info.buf_size - return device_input[:, node.channel], node.active + return device_input[:, node.channel], is_active(node) end diff --git a/src/sndfile.jl b/src/sndfile.jl index bf557be..130023d 100644 --- a/src/sndfile.jl +++ b/src/sndfile.jl @@ -91,10 +91,11 @@ end type FilePlayer <: AudioNode active::Bool + deactivate_cond::Condition file::AudioFile function FilePlayer(file::AudioFile) - node = new(false, file) + node = new(false, Condition(), file) finalizer(node, node -> close(node.file)) return node end @@ -110,16 +111,16 @@ function render(node::FilePlayer, device_input::AudioBuf, info::DeviceInfo) audio = read(node.file, info.buf_size, AudioSample) if audio == Nothing - node.active = false - return zeros(AudioSample, info.buf_size), node.active + deactivate(node) + return zeros(AudioSample, info.buf_size), is_active(node) end # if the file is stereo, mix the two channels together 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 - return audio, node.active + return audio, is_active(node) end function play(filename::String, args...)