diff --git a/src/PortAudio.jl b/src/PortAudio.jl index 4ee7630..30c4e0d 100644 --- a/src/PortAudio.jl +++ b/src/PortAudio.jl @@ -133,7 +133,7 @@ function __init__() config_folder = "ALSA_CONFIG_DIR" if config_folder ∉ keys(ENV) 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 # the plugin folder will contain plugins for, critically, PulseAudio plugin_folder = "ALSA_PLUGIN_DIR" @@ -230,19 +230,25 @@ function devices() end # 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( - # because we're calling Pa_ReadStream and Pa_WriteStream from separate threads, - # we put a lock around these calls - lock( - let a_function = a_function, - pointer_to = buffer.pointer_to, - data = buffer.data, - use_frames = use_frames - () -> a_function(pointer_to, data, use_frames) - end, - buffer.stream_lock, - ), + if acquire_lock + # because we're calling Pa_ReadStream and Pa_WriteStream from separate threads, + # we put a lock around these calls + lock( + let a_function = a_function, + pointer_to = pointer_to, + data = data, + use_frames = use_frames + () -> a_function(pointer_to, data, use_frames) + end, + buffer.stream_lock, + ) + else + a_function(pointer_to, data, use_frames) + end; warn_xruns = buffer.warn_xruns, ) end @@ -407,21 +413,25 @@ eltype(::Type{Buffer{Sample}}) where {Sample} = Sample 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. + +Set `acquire_lock = false` to skip acquiring the lock. """ -function write_buffer(buffer::Buffer, use_frames = buffer.frames_per_buffer) - read_or_write(Pa_WriteStream, buffer, use_frames) +function write_buffer(buffer::Buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true) + read_or_write(Pa_WriteStream, buffer, use_frames; acquire_lock = acquire_lock) 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). + +Set `acquire_lock = false` to skip acquiring the acquire_lock. """ -function read_buffer!(buffer, use_frames = buffer.frames_per_buffer) - read_or_write(Pa_ReadStream, buffer, use_frames) +function read_buffer!(buffer, use_frames = buffer.frames_per_buffer; acquire_lock = true) + read_or_write(Pa_ReadStream, buffer, use_frames; acquire_lock = acquire_lock) end """ @@ -907,6 +917,7 @@ end isopen(stream::PortAudioStream) = isopen(stream.pointer_to) samplerate(stream::PortAudioStream) = stream.sample_rate + function eltype( ::Type{<:PortAudioStream{<:Messenger{Sample}, <:Messenger{Sample}}}, ) where {Sample} @@ -927,7 +938,7 @@ function show(io::IO, stream::PortAudioStream) print(io, "PortAudioStream{") print(io, eltype(stream)) 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 sink = stream.sink if has_channels(sink) @@ -1043,4 +1054,6 @@ function unsafe_read!( exchange(source.stream.source_messenger, as_matrix(julia_buffer), already, frame_count) end +include("precompile.jl") + end # module PortAudio diff --git a/src/precompile.jl b/src/precompile.jl new file mode 100644 index 0000000..7dd9ab3 --- /dev/null +++ b/src/precompile.jl @@ -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)) + + + + + +