some more upgrades, changes a bunch of Ptrs to Refs
This commit is contained in:
parent
5823404f1a
commit
f6213dc5ef
7 changed files with 35 additions and 52 deletions
|
@ -5,8 +5,9 @@ module PortAudio
|
||||||
using SampledSignals
|
using SampledSignals
|
||||||
using RingBuffers
|
using RingBuffers
|
||||||
using Compat
|
using Compat
|
||||||
import Compat: undef, fetch, @compat
|
using Compat: undef, fetch, @compat
|
||||||
import Compat.LinearAlgebra: transpose!
|
using Compat.LinearAlgebra: transpose!
|
||||||
|
using Compat: stdout
|
||||||
|
|
||||||
import Base: eltype, show
|
import Base: eltype, show
|
||||||
import Base: close, isopen
|
import Base: close, isopen
|
||||||
|
@ -17,7 +18,6 @@ export PortAudioStream
|
||||||
|
|
||||||
# Get binary dependencies loaded from BinDeps
|
# Get binary dependencies loaded from BinDeps
|
||||||
include("../deps/deps.jl")
|
include("../deps/deps.jl")
|
||||||
include("suppressor.jl")
|
|
||||||
include("pa_shim.jl")
|
include("pa_shim.jl")
|
||||||
include("libportaudio.jl")
|
include("libportaudio.jl")
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ const CHUNKSIZE=128
|
||||||
# ringbuffer to receive errors from the audio processing thread
|
# ringbuffer to receive errors from the audio processing thread
|
||||||
const ERR_BUFSIZE=512
|
const ERR_BUFSIZE=512
|
||||||
|
|
||||||
function versioninfo(io::IO=STDOUT)
|
function versioninfo(io::IO=stdout)
|
||||||
println(io, Pa_GetVersionText())
|
println(io, Pa_GetVersionText())
|
||||||
println(io, "Version: ", Pa_GetVersion())
|
println(io, "Version: ", Pa_GetVersion())
|
||||||
println(io, "Shim Source Hash: ", shimhash()[1:10])
|
println(io, "Shim Source Hash: ", shimhash()[1:10])
|
||||||
|
@ -111,10 +111,10 @@ mutable struct PortAudioStream{T}
|
||||||
inchans > 0 ? notifyhandle(this.source) : C_NULL,
|
inchans > 0 ? notifyhandle(this.source) : C_NULL,
|
||||||
outchans > 0 ? notifyhandle(this.sink) : C_NULL,
|
outchans > 0 ? notifyhandle(this.sink) : C_NULL,
|
||||||
notifyhandle(this.errbuf))
|
notifyhandle(this.errbuf))
|
||||||
this.stream = @suppress_err Pa_OpenStream(inparams, outparams,
|
this.stream = suppress_err() do
|
||||||
float(sr), blocksize,
|
Pa_OpenStream(inparams, outparams, float(sr), blocksize, paNoFlag,
|
||||||
paNoFlag, shim_processcb_c,
|
shim_processcb_c, this.bufinfo)
|
||||||
this.bufinfo)
|
end
|
||||||
|
|
||||||
Pa_StartStream(this.stream)
|
Pa_StartStream(this.stream)
|
||||||
@async handle_errors(this)
|
@async handle_errors(this)
|
||||||
|
@ -357,7 +357,7 @@ shimhash() = unsafe_string(ccall((:pa_shim_getsourcehash, libpa_shim), Cstring,
|
||||||
# this is called by the shim process callback to notify that there is new data.
|
# this is called by the shim process callback to notify that there is new data.
|
||||||
# it's run in the audio context so don't do anything besides wake up the
|
# it's run in the audio context so don't do anything besides wake up the
|
||||||
# AsyncCondition handle associated with that ring buffer
|
# AsyncCondition handle associated with that ring buffer
|
||||||
notifycb(handle) = ccall(:uv_async_send, Cint, (Ptr{Cvoid},), handle)
|
notifycb(handle) = ccall(:uv_async_send, Cint, (Ref{Cvoid},), handle)
|
||||||
|
|
||||||
global shim_processcb_c, notifycb_c
|
global shim_processcb_c, notifycb_c
|
||||||
|
|
||||||
|
@ -373,11 +373,20 @@ function set_global_callbacks()
|
||||||
global notifycb_c = @cfunction notifycb Cint (Ptr{Cvoid},)
|
global notifycb_c = @cfunction notifycb Cint (Ptr{Cvoid},)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function suppress_err(dofunc::Function)
|
||||||
|
nullfile = @static Sys.iswindows() ? "nul" : "/dev/null"
|
||||||
|
open(nullfile, "w") do io
|
||||||
|
redirect_stdout(dofunc, io)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function __init__()
|
function __init__()
|
||||||
set_global_callbacks()
|
set_global_callbacks()
|
||||||
|
|
||||||
# initialize PortAudio on module load
|
# initialize PortAudio on module load
|
||||||
@suppress_err Pa_Initialize()
|
suppress_err() do
|
||||||
|
Pa_Initialize()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end # module PortAudio
|
end # module PortAudio
|
||||||
|
|
|
@ -159,18 +159,13 @@ end
|
||||||
function Pa_OpenStream(inParams, outParams,
|
function Pa_OpenStream(inParams, outParams,
|
||||||
sampleRate, framesPerBuffer,
|
sampleRate, framesPerBuffer,
|
||||||
flags::PaStreamFlags,
|
flags::PaStreamFlags,
|
||||||
callback, userdata)
|
callback, userdata::T) where T
|
||||||
streamPtr = Ref{PaStream}(0)
|
streamPtr = Ref{PaStream}(0)
|
||||||
err = ccall((:Pa_OpenStream, libportaudio), PaError,
|
err = ccall((:Pa_OpenStream, libportaudio), PaError,
|
||||||
(Ref{PaStream},
|
(Ref{PaStream}, Ref{Pa_StreamParameters}, Ref{Pa_StreamParameters},
|
||||||
Ptr{Pa_StreamParameters},
|
Cdouble, Culong, PaStreamFlags, Ref{Cvoid}, Ref{T}),
|
||||||
Ptr{Pa_StreamParameters},
|
streamPtr, inParams, outParams,
|
||||||
Cdouble, Culong, PaStreamFlags,
|
sampleRate, framesPerBuffer, flags, callback, userdata)
|
||||||
Ptr{Cvoid}, Ptr{Cvoid}),
|
|
||||||
streamPtr,
|
|
||||||
inParams, outParams,
|
|
||||||
sampleRate, framesPerBuffer, flags,
|
|
||||||
callback, userdata)
|
|
||||||
handle_status(err)
|
handle_status(err)
|
||||||
streamPtr[]
|
streamPtr[]
|
||||||
end
|
end
|
||||||
|
@ -211,7 +206,7 @@ function Pa_ReadStream(stream::PaStream, buf::Array, frames::Integer=length(buf)
|
||||||
show_warnings::Bool=true)
|
show_warnings::Bool=true)
|
||||||
frames <= length(buf) || error("Need a buffer at least $frames long")
|
frames <= length(buf) || error("Need a buffer at least $frames long")
|
||||||
err = ccall((:Pa_ReadStream, libportaudio), PaError,
|
err = ccall((:Pa_ReadStream, libportaudio), PaError,
|
||||||
(PaStream, Ptr{Cvoid}, Culong),
|
(PaStream, Ref{Cvoid}, Culong),
|
||||||
stream, buf, frames)
|
stream, buf, frames)
|
||||||
handle_status(err, show_warnings)
|
handle_status(err, show_warnings)
|
||||||
buf
|
buf
|
||||||
|
@ -221,7 +216,7 @@ function Pa_WriteStream(stream::PaStream, buf::Array, frames::Integer=length(buf
|
||||||
show_warnings::Bool=true)
|
show_warnings::Bool=true)
|
||||||
frames <= length(buf) || error("Need a buffer at least $frames long")
|
frames <= length(buf) || error("Need a buffer at least $frames long")
|
||||||
err = ccall((:Pa_WriteStream, libportaudio), PaError,
|
err = ccall((:Pa_WriteStream, libportaudio), PaError,
|
||||||
(PaStream, Ptr{Cvoid}, Culong),
|
(PaStream, Ref{Cvoid}, Culong),
|
||||||
stream, buf, frames)
|
stream, buf, frames)
|
||||||
handle_status(err, show_warnings)
|
handle_status(err, show_warnings)
|
||||||
nothing
|
nothing
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function find_pa_shim()
|
function find_pa_shim()
|
||||||
libdir = joinpath(dirname(@__FILE__), "..", "deps", "usr", "lib")
|
libdir = joinpath(@__DIR__, "..", "deps", "usr", "lib")
|
||||||
libsuffix = ""
|
libsuffix = ""
|
||||||
basename = "pa_shim"
|
basename = "pa_shim"
|
||||||
@static if Compat.Sys.islinux() && Sys.ARCH == :x86_64
|
@static if Compat.Sys.islinux() && Sys.ARCH == :x86_64
|
||||||
|
@ -43,5 +43,3 @@ mutable struct pa_shim_info_t
|
||||||
outputhandle::Ptr{Cvoid} # condition to notify when ready for output
|
outputhandle::Ptr{Cvoid} # condition to notify when ready for output
|
||||||
errorhandle::Ptr{Cvoid} # condition to notify on new errors
|
errorhandle::Ptr{Cvoid} # condition to notify on new errors
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.unsafe_convert(::Type{Ptr{Cvoid}}, info::pa_shim_info_t) = pointer_from_objref(info)
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
# while waiting for this PR to get merged: https://github.com/Ismael-VC/Suppressor.jl/pull/12
|
|
||||||
# we'll just include the relevant code here
|
|
||||||
|
|
||||||
macro suppress_err(block)
|
|
||||||
quote
|
|
||||||
if ccall(:jl_generating_output, Cint, ()) == 0
|
|
||||||
ORIGINAL_STDERR = stderr
|
|
||||||
err_rd, err_wr = redirect_stderr()
|
|
||||||
err_reader = @async read(err_rd, String)
|
|
||||||
end
|
|
||||||
|
|
||||||
value = $(esc(block))
|
|
||||||
|
|
||||||
if ccall(:jl_generating_output, Cint, ()) == 0
|
|
||||||
redirect_stderr(ORIGINAL_STDERR)
|
|
||||||
close(err_wr)
|
|
||||||
end
|
|
||||||
value
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1 +0,0 @@
|
||||||
TestSetExtensions
|
|
|
@ -3,7 +3,6 @@
|
||||||
using Compat
|
using Compat
|
||||||
using Compat.Test
|
using Compat.Test
|
||||||
import Compat: Cvoid
|
import Compat: Cvoid
|
||||||
using TestSetExtensions
|
|
||||||
using PortAudio
|
using PortAudio
|
||||||
using SampledSignals
|
using SampledSignals
|
||||||
using RingBuffers
|
using RingBuffers
|
||||||
|
@ -36,8 +35,8 @@ function setup_callback(inchans, outchans, nframes, synced)
|
||||||
|
|
||||||
function processfunc()
|
function processfunc()
|
||||||
ccall(shim_processcb_c, Cint,
|
ccall(shim_processcb_c, Cint,
|
||||||
(Ptr{Float32}, Ptr{Float32}, Culong, Ptr{Cvoid}, Culong, Ptr{Cvoid}),
|
(Ref{Float32}, Ref{Float32}, Culong, Ref{Cvoid}, Culong, Ref{pa_shim_info_t}),
|
||||||
cb_input, cb_output, nframes, C_NULL, flags, pointer_from_objref(info))
|
cb_input, cb_output, nframes, C_NULL, flags, info)
|
||||||
end
|
end
|
||||||
|
|
||||||
(sourcebuf, sinkbuf, errbuf, cb_input, cb_output, processfunc)
|
(sourcebuf, sinkbuf, errbuf, cb_input, cb_output, processfunc)
|
||||||
|
@ -52,7 +51,10 @@ function test_callback(inchans, outchans, synced)
|
||||||
testout = rand(Float32, outchans, nframes) # generate some test data to play
|
testout = rand(Float32, outchans, nframes) # generate some test data to play
|
||||||
write(sinkbuf, testout) # fill the output ringbuffer
|
write(sinkbuf, testout) # fill the output ringbuffer
|
||||||
end
|
end
|
||||||
@test process() == PortAudio.paContinue
|
# the process closure only has a pointer (not a ref) to sinkbuf
|
||||||
|
GC.@preserve sinkbuf begin
|
||||||
|
@test process() == PortAudio.paContinue
|
||||||
|
end
|
||||||
if outchans > 0
|
if outchans > 0
|
||||||
# testout -> sinkbuf -> cb_output
|
# testout -> sinkbuf -> cb_output
|
||||||
@test cb_output == testout
|
@test cb_output == testout
|
||||||
|
@ -179,7 +181,7 @@ function test_callback_overflow(inchans, outchans, synced)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset ExtendedTestSet "PortAudio Tests" begin
|
@testset "PortAudio Tests" begin
|
||||||
@testset "Reports version" begin
|
@testset "Reports version" begin
|
||||||
io = IOBuffer()
|
io = IOBuffer()
|
||||||
PortAudio.versioninfo(io)
|
PortAudio.versioninfo(io)
|
||||||
|
|
|
@ -16,7 +16,7 @@ elseif Compat.Sys.islinux()
|
||||||
default_outdev = "default"
|
default_outdev = "default"
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset ExtendedTestSet "Local Tests" begin
|
@testset "Local Tests" begin
|
||||||
@testset "Open Default Device" begin
|
@testset "Open Default Device" begin
|
||||||
println("Recording...")
|
println("Recording...")
|
||||||
stream = PortAudioStream(2, 0)
|
stream = PortAudioStream(2, 0)
|
||||||
|
|
Loading…
Reference in a new issue