Merge branch 'nocallback' of https://github.com/jakubwro/PortAudio.jl
This commit is contained in:
commit
bea3577abe
2 changed files with 73 additions and 5 deletions
68
examples/measure_latency.jl
Normal file
68
examples/measure_latency.jl
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
using PortAudio
|
||||||
|
using DSP
|
||||||
|
|
||||||
|
function create_measure_signal()
|
||||||
|
signal = zeros(Float32, 20000)
|
||||||
|
for i in 1:3
|
||||||
|
signal = vcat(signal, rand(Float32, 100), zeros(Float32, i*10000))
|
||||||
|
end
|
||||||
|
return signal
|
||||||
|
end
|
||||||
|
|
||||||
|
function measure_latency(in_latency = 0.1, out_latency=0.1, blocksize = 32; is_warmup = false)
|
||||||
|
|
||||||
|
in_stream = PortAudioStream(1,0; latency=in_latency, blocksize=32)
|
||||||
|
out_stream = PortAudioStream(0,1; latency=out_latency, blocksize=32)
|
||||||
|
|
||||||
|
cond = Base.Event()
|
||||||
|
|
||||||
|
writer_start_time = Int64(0)
|
||||||
|
reader_start_time = Int64(0)
|
||||||
|
|
||||||
|
reader = Threads.@spawn begin
|
||||||
|
wait(cond)
|
||||||
|
writer_start_time = time_ns() |> Int64
|
||||||
|
return read(in_stream, 100000)
|
||||||
|
end
|
||||||
|
|
||||||
|
signal = create_measure_signal()
|
||||||
|
writer = Threads.@spawn begin
|
||||||
|
wait(cond)
|
||||||
|
reader_start_time = time_ns() |> Int64
|
||||||
|
write(out_stream, signal)
|
||||||
|
end
|
||||||
|
|
||||||
|
notify(cond)
|
||||||
|
|
||||||
|
wait(reader)
|
||||||
|
wait(writer)
|
||||||
|
|
||||||
|
recorded = collect(reader.result)[:,1]
|
||||||
|
|
||||||
|
close(in_stream)
|
||||||
|
close(out_stream)
|
||||||
|
|
||||||
|
diff = reader_start_time - writer_start_time |> abs
|
||||||
|
|
||||||
|
diff_in_ms = diff / 10^6 # 1 ms = 10^6 ns
|
||||||
|
|
||||||
|
if !is_warmup && diff_in_ms > 1
|
||||||
|
@warn "Threads start time difference $diff_in_ms ms is bigger than 1 ms"
|
||||||
|
end
|
||||||
|
|
||||||
|
delay = finddelay(recorded, signal) / 48000
|
||||||
|
|
||||||
|
return trunc(Int, delay * 1000)# result in ms
|
||||||
|
end
|
||||||
|
|
||||||
|
measure_latency(0.1, 0.1, 32; is_warmup = true) # warmup
|
||||||
|
|
||||||
|
latencies = [0.1, 0.01, 0.005]
|
||||||
|
for in_latency in latencies
|
||||||
|
for out_latency in latencies
|
||||||
|
for blocksize in [32]
|
||||||
|
measure = measure_latency(in_latency, out_latency, blocksize)
|
||||||
|
println("$measure ms latency for in_latency=$in_latency, out_latency=$out_latency, blocksize=$blocksize")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -78,15 +78,15 @@ mutable struct PortAudioStream{T}
|
||||||
# TODO: write a latency tester app
|
# TODO: write a latency tester app
|
||||||
function PortAudioStream{T}(indev::PortAudioDevice, outdev::PortAudioDevice,
|
function PortAudioStream{T}(indev::PortAudioDevice, outdev::PortAudioDevice,
|
||||||
inchans, outchans, sr, blocksize,
|
inchans, outchans, sr, blocksize,
|
||||||
warn_xruns) where {T}
|
warn_xruns, latency) where {T}
|
||||||
inchans = inchans == -1 ? indev.maxinchans : inchans
|
inchans = inchans == -1 ? indev.maxinchans : inchans
|
||||||
outchans = outchans == -1 ? outdev.maxoutchans : outchans
|
outchans = outchans == -1 ? outdev.maxoutchans : outchans
|
||||||
inparams = (inchans == 0) ?
|
inparams = (inchans == 0) ?
|
||||||
Ptr{Pa_StreamParameters}(0) :
|
Ptr{Pa_StreamParameters}(0) :
|
||||||
Ref(Pa_StreamParameters(indev.idx, inchans, type_to_fmt[T], 0.1, C_NULL))
|
Ref(Pa_StreamParameters(indev.idx, inchans, type_to_fmt[T], latency, C_NULL))
|
||||||
outparams = (outchans == 0) ?
|
outparams = (outchans == 0) ?
|
||||||
Ptr{Pa_StreamParameters}(0) :
|
Ptr{Pa_StreamParameters}(0) :
|
||||||
Ref(Pa_StreamParameters(outdev.idx, outchans, type_to_fmt[T], 0.1, C_NULL))
|
Ref(Pa_StreamParameters(outdev.idx, outchans, type_to_fmt[T], latency, C_NULL))
|
||||||
this = new(sr, blocksize, C_NULL, warn_xruns)
|
this = new(sr, blocksize, C_NULL, warn_xruns)
|
||||||
# finalizer(close, this)
|
# finalizer(close, this)
|
||||||
this.sink = PortAudioSink{T}(outdev.name, this, outchans)
|
this.sink = PortAudioSink{T}(outdev.name, this, outchans)
|
||||||
|
@ -127,7 +127,7 @@ Options:
|
||||||
"""
|
"""
|
||||||
function PortAudioStream(indev::PortAudioDevice, outdev::PortAudioDevice,
|
function PortAudioStream(indev::PortAudioDevice, outdev::PortAudioDevice,
|
||||||
inchans=2, outchans=2; eltype=Float32, samplerate=-1, blocksize=DEFAULT_BLOCKSIZE,
|
inchans=2, outchans=2; eltype=Float32, samplerate=-1, blocksize=DEFAULT_BLOCKSIZE,
|
||||||
warn_xruns=false)
|
warn_xruns=false, latency=0.1)
|
||||||
if samplerate == -1
|
if samplerate == -1
|
||||||
sampleratein = indev.defaultsamplerate
|
sampleratein = indev.defaultsamplerate
|
||||||
samplerateout = outdev.defaultsamplerate
|
samplerateout = outdev.defaultsamplerate
|
||||||
|
@ -142,7 +142,7 @@ function PortAudioStream(indev::PortAudioDevice, outdev::PortAudioDevice,
|
||||||
samplerate = samplerateout
|
samplerate = samplerateout
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
PortAudioStream{eltype}(indev, outdev, inchans, outchans, samplerate, blocksize, warn_xruns)
|
PortAudioStream{eltype}(indev, outdev, inchans, outchans, samplerate, blocksize, warn_xruns, latency)
|
||||||
end
|
end
|
||||||
|
|
||||||
# handle device names given as streams
|
# handle device names given as streams
|
||||||
|
|
Loading…
Add table
Reference in a new issue