diff --git a/examples/measure_latency.jl b/examples/measure_latency.jl new file mode 100644 index 0000000..7747da4 --- /dev/null +++ b/examples/measure_latency.jl @@ -0,0 +1,67 @@ +using PortAudio +using DSP + +function create_measure_signal() + signal = zeros(Float32, 1000) + for i in 1:3 + signal = vcat(signal, rand(Float32, 100), zeros(Float32, i*3000)) + 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 + +for in_latency in [0.1, 0.01, 0.005] + for out_latency in [0.1, 0.01, 0.005] + 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