array playback seems to be working smoothly now

This commit is contained in:
Spencer Russell 2013-12-22 17:16:53 -05:00
parent 12760b4096
commit 7806ead4ec

View file

@ -17,8 +17,9 @@ _stream = nothing
# A node in the render tree # A node in the render tree
abstract AudioNode abstract AudioNode
typealias AudioSample Float32
# A frame of audio, possibly multi-channel # A frame of audio, possibly multi-channel
typealias AudioBuf Array{Float32} typealias AudioBuf Array{AudioSample}
# Info about the hardware device # Info about the hardware device
@ -38,7 +39,7 @@ type AudioStream
end end
function render(node::Nothing, device_input::AudioBuf, info::DeviceInfo) function render(node::Nothing, device_input::AudioBuf, info::DeviceInfo)
return zeros(info.buf_size) return zeros(AudioSample, info.buf_size)
end end
#### SinOsc #### #### SinOsc ####
@ -55,7 +56,7 @@ type SinOsc <: AudioNode
end end
function render(node::SinOsc, device_input::AudioBuf, info::DeviceInfo) function render(node::SinOsc, device_input::AudioBuf, info::DeviceInfo)
phase = Float32[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) return sin(phase)
@ -72,7 +73,7 @@ end
function render(node::AudioMixer, device_input::AudioBuf, info::DeviceInfo) function render(node::AudioMixer, device_input::AudioBuf, info::DeviceInfo)
# TODO: we may want to pre-allocate this buffer and share between render # TODO: we may want to pre-allocate this buffer and share between render
# calls # calls
mix_buffer = zeros(info.buf_size) mix_buffer = zeros(AudioSample, info.buf_size)
for in_node in node.mix_inputs for in_node in node.mix_inputs
mix_buffer += render(in_node, device_input, info) mix_buffer += render(in_node, device_input, info)
end end
@ -80,7 +81,7 @@ end
#### Array Player #### #### Array Player ####
# Plays a Vector{Float32} by rendering it out piece-by-piece # Plays a AudioBuf by rendering it out piece-by-piece
type ArrayPlayer <: AudioNode type ArrayPlayer <: AudioNode
arr::AudioBuf arr::AudioBuf
@ -91,12 +92,12 @@ type ArrayPlayer <: AudioNode
end end
end end
function render(node::ArrayPlayer, device_input::Vector{Float32}, info::DeviceInfo) function render(node::ArrayPlayer, device_input::AudioBuf, info::DeviceInfo)
i = node.arr_index i = node.arr_index
range_end = min(i + info.buf_size, 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
output = vcat(output, zeros(info.buf_size - length(output))) output = vcat(output, zeros(AudioSample, info.buf_size - length(output)))
end end
node.arr_index = range_end + 1 node.arr_index = range_end + 1
return output return output
@ -110,7 +111,7 @@ type AudioInput <: AudioNode
channel::Int channel::Int
end end
function render(node::AudioInput, device_input::Vector{Float32}, 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] return device_input[:, node.channel]
end end
@ -177,12 +178,12 @@ end
function audio_task(jl_filedesc::Integer, stream::AudioStream) function audio_task(jl_filedesc::Integer, stream::AudioStream)
info("Audio Task Launched") info("Audio Task Launched")
in_array = convert(AudioBuf, zeros(stream.info.buf_size)) in_array = zeros(AudioSample, stream.info.buf_size)
desc_bytes = Cchar[0] desc_bytes = Cchar[0]
jl_stream = fdio(jl_filedesc) jl_stream = fdio(jl_filedesc)
jl_rawfd = RawFD(jl_filedesc) jl_rawfd = RawFD(jl_filedesc)
while true while true
out_array = render(stream.root_node, in_array, stream.info) out_array = render(stream.root_node, in_array, stream.info)::AudioBuf
# wake the C code so it knows we've given it some more data # wake the C code so it knows we've given it some more data
wake_callback_thread(out_array) wake_callback_thread(out_array)
# wait for new data to be available from the sound card (and for it to # wait for new data to be available from the sound card (and for it to