Send debug to debug (#74)

* send to debug

* use Suppressor

* actually, this might be nicer as a macro

* return

* fix, add test

* small fix

* Logging target

* send xrun messages to debug

* Add note to README

* Revert "send xrun messages to debug"

This reverts commit d47abb9072.
This commit is contained in:
bramtayl 2021-05-24 17:34:37 -04:00 committed by GitHub
parent 0187b4937d
commit dd68835815
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 16 deletions

View file

@ -8,15 +8,18 @@ alsa_plugins_jll = "5ac2f6bb-493e-5871-9171-112d4c21a6e7"
libportaudio_jll = "2d7b7beb-0762-5160-978e-1ab83a1e8a31"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
SampledSignals = "bd7594eb-a658-542f-9e75-4c4d8908c167"
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
[compat]
julia = "1.3"
alsa_plugins_jll = "1.2.2"
libportaudio_jll = "19.6.0"
SampledSignals = "2.1.1"
Suppressor = "0.2.0"
[extras]
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[targets]
test = ["Test"]
test = ["Logging", "Test"]

View file

@ -45,6 +45,16 @@ The `PortAudioStream` type has `source` and `sink` fields which are of type `Por
PortAudio.jl also provides convenience wrappers around the `PortAudioStream` type so you can read and write to it directly, e.g. `write(stream, stream)` will set up a loopback that will read from the input and play it back on the output.
## Debugging
If you are experiencing issues and wish to view detailed logging and debug information, set
```
ENV["JULIA_DEBUG"] = :PortAudio
```
before using the package.
## Examples
### Set up an audio pass-through from microphone to speaker

View file

@ -1,7 +1,9 @@
module PortAudio
using alsa_plugins_jll: alsa_plugins_jll
using libportaudio_jll, SampledSignals
using libportaudio_jll: libportaudio
using SampledSignals
using Suppressor: @capture_err
import Base: eltype, show
import Base: close, isopen
@ -14,6 +16,15 @@ export PortAudioStream
include("libportaudio.jl")
macro stderr_as_debug(expression)
quote
local result
debug_message = @capture_err result = $(esc(expression))
@debug debug_message
result
end
end
# This size is in frames
# data is passed to and from portaudio in chunks with this many frames, because
@ -94,10 +105,8 @@ mutable struct PortAudioStream{T}
# finalizer(close, this)
this.sink = PortAudioSink{T}(outdev.name, this, outchans)
this.source = PortAudioSource{T}(indev.name, this, inchans)
this.stream = suppress_err() do
Pa_OpenStream(inparams, outparams, sr, 0, paNoFlag,
this.stream = @stderr_as_debug Pa_OpenStream(inparams, outparams, sr, 0, paNoFlag,
nothing, nothing)
end
Pa_StartStream(this.stream)
# pre-fill the output stream so we're less likely to underrun
@ -370,13 +379,6 @@ function discard_input(source::PortAudioSource)
end
end
function suppress_err(dofunc::Function)
nullfile = @static Sys.iswindows() ? "nul" : "/dev/null"
open(nullfile, "w") do io
redirect_stderr(dofunc, io)
end
end
function __init__()
if Sys.islinux()
envkey = "ALSA_CONFIG_DIR"
@ -415,9 +417,7 @@ function __init__()
# junk to STDOUT on initialization, so we swallow it.
# TODO: actually check the junk to make sure there's nothing in there we
# don't expect
suppress_err() do
Pa_Initialize()
end
@stderr_as_debug Pa_Initialize()
atexit() do
Pa_Terminate()

View file

@ -1,10 +1,18 @@
#!/usr/bin/env julia
using Logging: Debug
using PortAudio
using PortAudio: Pa_GetDefaultInputDevice, Pa_GetDefaultOutputDevice, Pa_GetDeviceInfo, Pa_GetHostApiInfo, PortAudioDevice
using PortAudio: Pa_GetDefaultInputDevice, Pa_GetDefaultOutputDevice, Pa_GetDeviceInfo, Pa_GetHostApiInfo, PortAudioDevice, @stderr_as_debug
using Test
using SampledSignals
@testset "Debug messages" begin
@test_logs (:debug, "hi") min_level = Debug @test_nowarn @stderr_as_debug begin
print(stderr, "hi")
true
end
end
@testset "PortAudio Tests" begin
@testset "Reports version" begin
io = IOBuffer()