Allow skipping locks, precompile
This commit is contained in:
parent
3939d47a8d
commit
79ceac0282
2 changed files with 62 additions and 20 deletions
|
@ -133,7 +133,7 @@ function __init__()
|
||||||
config_folder = "ALSA_CONFIG_DIR"
|
config_folder = "ALSA_CONFIG_DIR"
|
||||||
if config_folder ∉ keys(ENV)
|
if config_folder ∉ keys(ENV)
|
||||||
ENV[config_folder] =
|
ENV[config_folder] =
|
||||||
seek_alsa_conf(("/usr/share/alsa", "/usr/local/share/alsa", "/etc/alsa"))
|
seek_alsa_conf(["/usr/share/alsa", "/usr/local/share/alsa", "/etc/alsa"])
|
||||||
end
|
end
|
||||||
# the plugin folder will contain plugins for, critically, PulseAudio
|
# the plugin folder will contain plugins for, critically, PulseAudio
|
||||||
plugin_folder = "ALSA_PLUGIN_DIR"
|
plugin_folder = "ALSA_PLUGIN_DIR"
|
||||||
|
@ -230,19 +230,25 @@ function devices()
|
||||||
end
|
end
|
||||||
|
|
||||||
# we can handle reading and writing from buffers in a similar way
|
# we can handle reading and writing from buffers in a similar way
|
||||||
function read_or_write(a_function, buffer, use_frames = buffer.frames_per_buffer)
|
function read_or_write(a_function, buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true)
|
||||||
|
pointer_to = buffer.pointer_to
|
||||||
|
data = buffer.data
|
||||||
handle_status(
|
handle_status(
|
||||||
|
if acquire_lock
|
||||||
# because we're calling Pa_ReadStream and Pa_WriteStream from separate threads,
|
# because we're calling Pa_ReadStream and Pa_WriteStream from separate threads,
|
||||||
# we put a lock around these calls
|
# we put a lock around these calls
|
||||||
lock(
|
lock(
|
||||||
let a_function = a_function,
|
let a_function = a_function,
|
||||||
pointer_to = buffer.pointer_to,
|
pointer_to = pointer_to,
|
||||||
data = buffer.data,
|
data = data,
|
||||||
use_frames = use_frames
|
use_frames = use_frames
|
||||||
() -> a_function(pointer_to, data, use_frames)
|
() -> a_function(pointer_to, data, use_frames)
|
||||||
end,
|
end,
|
||||||
buffer.stream_lock,
|
buffer.stream_lock,
|
||||||
),
|
)
|
||||||
|
else
|
||||||
|
a_function(pointer_to, data, use_frames)
|
||||||
|
end;
|
||||||
warn_xruns = buffer.warn_xruns,
|
warn_xruns = buffer.warn_xruns,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -407,21 +413,25 @@ eltype(::Type{Buffer{Sample}}) where {Sample} = Sample
|
||||||
nchannels(buffer::Buffer) = buffer.number_of_channels
|
nchannels(buffer::Buffer) = buffer.number_of_channels
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PortAudio.write_buffer(buffer, use_frames = buffer.frames_per_buffer)
|
PortAudio.write_buffer(buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true)
|
||||||
|
|
||||||
Write a number of frames (`use_frames`) from a [`PortAudio.Buffer`](@ref) to PortAudio.
|
Write a number of frames (`use_frames`) from a [`PortAudio.Buffer`](@ref) to PortAudio.
|
||||||
|
|
||||||
|
Set `acquire_lock = false` to skip acquiring the lock.
|
||||||
"""
|
"""
|
||||||
function write_buffer(buffer::Buffer, use_frames = buffer.frames_per_buffer)
|
function write_buffer(buffer::Buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true)
|
||||||
read_or_write(Pa_WriteStream, buffer, use_frames)
|
read_or_write(Pa_WriteStream, buffer, use_frames; acquire_lock = acquire_lock)
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
PortAudio.read_buffer!(buffer::Buffer, use_frames = buffer.frames_per_buffer)
|
PortAudio.read_buffer!(buffer::Buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true)
|
||||||
|
|
||||||
Read a number of frames (`use_frames`) from PortAudio to a [`PortAudio.Buffer`](@ref).
|
Read a number of frames (`use_frames`) from PortAudio to a [`PortAudio.Buffer`](@ref).
|
||||||
|
|
||||||
|
Set `acquire_lock = false` to skip acquiring the acquire_lock.
|
||||||
"""
|
"""
|
||||||
function read_buffer!(buffer, use_frames = buffer.frames_per_buffer)
|
function read_buffer!(buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true)
|
||||||
read_or_write(Pa_ReadStream, buffer, use_frames)
|
read_or_write(Pa_ReadStream, buffer, use_frames; acquire_lock = acquire_lock)
|
||||||
end
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -907,6 +917,7 @@ end
|
||||||
isopen(stream::PortAudioStream) = isopen(stream.pointer_to)
|
isopen(stream::PortAudioStream) = isopen(stream.pointer_to)
|
||||||
|
|
||||||
samplerate(stream::PortAudioStream) = stream.sample_rate
|
samplerate(stream::PortAudioStream) = stream.sample_rate
|
||||||
|
|
||||||
function eltype(
|
function eltype(
|
||||||
::Type{<:PortAudioStream{<:Messenger{Sample}, <:Messenger{Sample}}},
|
::Type{<:PortAudioStream{<:Messenger{Sample}, <:Messenger{Sample}}},
|
||||||
) where {Sample}
|
) where {Sample}
|
||||||
|
@ -927,7 +938,7 @@ function show(io::IO, stream::PortAudioStream)
|
||||||
print(io, "PortAudioStream{")
|
print(io, "PortAudioStream{")
|
||||||
print(io, eltype(stream))
|
print(io, eltype(stream))
|
||||||
println(io, "}")
|
println(io, "}")
|
||||||
print(io, " Samplerate: ", samplerate(stream), "Hz")
|
print(io, " Samplerate: ", round(Int, samplerate(stream)), "Hz")
|
||||||
# show source or sink if there's any channels
|
# show source or sink if there's any channels
|
||||||
sink = stream.sink
|
sink = stream.sink
|
||||||
if has_channels(sink)
|
if has_channels(sink)
|
||||||
|
@ -1043,4 +1054,6 @@ function unsafe_read!(
|
||||||
exchange(source.stream.source_messenger, as_matrix(julia_buffer), already, frame_count)
|
exchange(source.stream.source_messenger, as_matrix(julia_buffer), already, frame_count)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
include("precompile.jl")
|
||||||
|
|
||||||
end # module PortAudio
|
end # module PortAudio
|
||||||
|
|
29
src/precompile.jl
Normal file
29
src/precompile.jl
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# precompile some important functions
|
||||||
|
const DEFAULT_SINK_MESSENGER_TYPE = Messenger{Float32, SampledSignalsWriter, Tuple{Matrix{Float32}, Int64, Int64}, Int64}
|
||||||
|
const DEFAULT_SOURCE_MESSENGER_TYPE = Messenger{Float32, SampledSignalsReader, Tuple{Matrix{Float32}, Int64, Int64}, Int64}
|
||||||
|
const DEFAULT_STREAM_TYPE = PortAudioStream{DEFAULT_SINK_MESSENGER_TYPE, DEFAULT_SOURCE_MESSENGER_TYPE}
|
||||||
|
const DEFAULT_SINK_TYPE = PortAudioSink{DEFAULT_SINK_MESSENGER_TYPE, DEFAULT_SOURCE_MESSENGER_TYPE}
|
||||||
|
const DEFAULT_SOURCE_TYPE = PortAudioSource{DEFAULT_SINK_MESSENGER_TYPE, DEFAULT_SOURCE_MESSENGER_TYPE}
|
||||||
|
|
||||||
|
precompile(close, (DEFAULT_STREAM_TYPE,))
|
||||||
|
precompile(devices, ())
|
||||||
|
precompile(__init__, ())
|
||||||
|
precompile(isopen, (DEFAULT_STREAM_TYPE,))
|
||||||
|
precompile(nchannels, (DEFAULT_SINK_TYPE,))
|
||||||
|
precompile(nchannels, (DEFAULT_SOURCE_TYPE,))
|
||||||
|
precompile(PortAudioStream, (Int, Int))
|
||||||
|
precompile(PortAudioStream, (String, Int, Int))
|
||||||
|
precompile(PortAudioStream, (String, String, Int, Int))
|
||||||
|
precompile(samplerate, (DEFAULT_STREAM_TYPE,))
|
||||||
|
precompile(send, (DEFAULT_SINK_MESSENGER_TYPE,))
|
||||||
|
precompile(send, (DEFAULT_SOURCE_MESSENGER_TYPE,))
|
||||||
|
precompile(unsafe_read!, (DEFAULT_SOURCE_TYPE, Vector{Float32}, Int, Int))
|
||||||
|
precompile(unsafe_read!, (DEFAULT_SOURCE_TYPE, Matrix{Float32}, Int, Int))
|
||||||
|
precompile(unsafe_write, (DEFAULT_SINK_TYPE, Vector{Float32}, Int, Int))
|
||||||
|
precompile(unsafe_write, (DEFAULT_SINK_TYPE, Matrix{Float32}, Int, Int))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue