send xrun messages to debug
This commit is contained in:
parent
3233af2277
commit
d47abb9072
2 changed files with 16 additions and 25 deletions
|
@ -77,7 +77,6 @@ mutable struct PortAudioStream{T}
|
|||
samplerate::Float64
|
||||
latency::Float64
|
||||
stream::PaStream
|
||||
warn_xruns::Bool
|
||||
recover_xruns::Bool
|
||||
sink # untyped because of circular type definition
|
||||
source # untyped because of circular type definition
|
||||
|
@ -91,7 +90,7 @@ mutable struct PortAudioStream{T}
|
|||
# TODO: figure out whether we can get deterministic latency...
|
||||
function PortAudioStream{T}(indev::PortAudioDevice, outdev::PortAudioDevice,
|
||||
inchans, outchans, sr,
|
||||
latency, warn_xruns, recover_xruns) where {T}
|
||||
latency, recover_xruns) where {T}
|
||||
inchans = inchans == -1 ? indev.maxinchans : inchans
|
||||
outchans = outchans == -1 ? outdev.maxoutchans : outchans
|
||||
inparams = (inchans == 0) ?
|
||||
|
@ -100,7 +99,7 @@ mutable struct PortAudioStream{T}
|
|||
outparams = (outchans == 0) ?
|
||||
Ptr{Pa_StreamParameters}(0) :
|
||||
Ref(Pa_StreamParameters(outdev.idx, outchans, type_to_fmt[T], latency, C_NULL))
|
||||
this = new(sr, latency, C_NULL, warn_xruns, recover_xruns)
|
||||
this = new(sr, latency, C_NULL, recover_xruns)
|
||||
# finalizer(close, this)
|
||||
this.sink = PortAudioSink{T}(outdev.name, this, outchans)
|
||||
this.source = PortAudioSource{T}(indev.name, this, inchans)
|
||||
|
@ -144,7 +143,7 @@ Audio devices can either be `PortAudioDevice` instances as returned
|
|||
by `PortAudio.devices()`, or strings with the device name as reported by the
|
||||
operating system. If a single `duplexdevice` is given it will be used for both
|
||||
input and output. If no devices are given the system default devices will be
|
||||
used.
|
||||
used. Over- and under-run messages will be sent to the debug log.
|
||||
|
||||
Options:
|
||||
|
||||
|
@ -152,9 +151,6 @@ Options:
|
|||
* `samplerate`: Sample rate (defaults to device sample rate)
|
||||
* `latency`: Requested latency. Stream could underrun when too low, consider
|
||||
using provided device defaults
|
||||
* `warn_xruns`: Display a warning if there is a stream overrun or underrun, which
|
||||
often happens when Julia is compiling, or with a particularly large
|
||||
GC run. This can be quite verbose so is false by default.
|
||||
* `recover_xruns`: Attempt to recover from overruns and underruns by emptying and
|
||||
filling the input and output buffers, respectively. Should result in
|
||||
fewer xruns but could make each xrun more audible. True by default.
|
||||
|
@ -162,7 +158,7 @@ Options:
|
|||
"""
|
||||
function PortAudioStream(indev::PortAudioDevice, outdev::PortAudioDevice,
|
||||
inchans=2, outchans=2; eltype=Float32, samplerate=-1,
|
||||
latency=defaultlatency(indev, outdev), warn_xruns=false, recover_xruns=true)
|
||||
latency=defaultlatency(indev, outdev), recover_xruns=true)
|
||||
if samplerate == -1
|
||||
sampleratein = indev.defaultsamplerate
|
||||
samplerateout = outdev.defaultsamplerate
|
||||
|
@ -178,7 +174,7 @@ function PortAudioStream(indev::PortAudioDevice, outdev::PortAudioDevice,
|
|||
end
|
||||
end
|
||||
PortAudioStream{eltype}(indev, outdev, inchans, outchans, samplerate,
|
||||
latency, warn_xruns, recover_xruns)
|
||||
latency, recover_xruns)
|
||||
end
|
||||
|
||||
# handle device names given as streams
|
||||
|
@ -315,8 +311,7 @@ function SampledSignals.unsafe_write(sink::PortAudioSink, buf::Array, frameoffse
|
|||
view(buf, (1:n) .+ nwritten .+ frameoffset, :))
|
||||
# TODO: if the stream is closed we just want to return a
|
||||
# shorter-than-requested frame count instead of throwing an error
|
||||
err = Pa_WriteStream(sink.stream.stream, sink.chunkbuf, n,
|
||||
sink.stream.warn_xruns)
|
||||
err = Pa_WriteStream(sink.stream.stream, sink.chunkbuf, n)
|
||||
if err ∈ (PA_OUTPUT_UNDERFLOWED, PA_INPUT_OVERFLOWED) && sink.stream.recover_xruns
|
||||
recover_xrun(sink.stream)
|
||||
end
|
||||
|
@ -332,8 +327,7 @@ function SampledSignals.unsafe_read!(source::PortAudioSource, buf::Array, frameo
|
|||
n = min(framecount-nread, CHUNKFRAMES)
|
||||
# TODO: if the stream is closed we just want to return a
|
||||
# shorter-than-requested frame count instead of throwing an error
|
||||
err = Pa_ReadStream(source.stream.stream, source.chunkbuf, n,
|
||||
source.stream.warn_xruns)
|
||||
err = Pa_ReadStream(source.stream.stream, source.chunkbuf, n)
|
||||
if err ∈ (PA_OUTPUT_UNDERFLOWED, PA_INPUT_OVERFLOWED) && source.stream.recover_xruns
|
||||
recover_xrun(source.stream)
|
||||
end
|
||||
|
|
|
@ -242,8 +242,7 @@ function Pa_GetStreamWriteAvailable(stream::PaStream)
|
|||
avail
|
||||
end
|
||||
|
||||
function Pa_ReadStream(stream::PaStream, buf::Array, frames::Integer,
|
||||
show_warnings=true)
|
||||
function Pa_ReadStream(stream::PaStream, buf::Array, frames::Integer)
|
||||
# without disable_sigint I get a segfault with the error:
|
||||
# "error thrown and no exception handler available."
|
||||
# if the user tries to ctrl-C. Note I've still had some crash problems with
|
||||
|
@ -254,18 +253,17 @@ function Pa_ReadStream(stream::PaStream, buf::Array, frames::Integer,
|
|||
(PaStream, Ptr{Cvoid}, Culong),
|
||||
stream, buf, frames)
|
||||
end
|
||||
handle_status(err, show_warnings)
|
||||
handle_status(err)
|
||||
err
|
||||
end
|
||||
|
||||
function Pa_WriteStream(stream::PaStream, buf::Array, frames::Integer,
|
||||
show_warnings=true)
|
||||
function Pa_WriteStream(stream::PaStream, buf::Array, frames::Integer)
|
||||
err = disable_sigint() do
|
||||
@tcall @locked ccall((:Pa_WriteStream, libportaudio), PaError,
|
||||
(PaStream, Ptr{Cvoid}, Culong),
|
||||
stream, buf, frames)
|
||||
end
|
||||
handle_status(err, show_warnings)
|
||||
handle_status(err)
|
||||
err
|
||||
end
|
||||
|
||||
|
@ -279,13 +277,12 @@ end
|
|||
# end
|
||||
#
|
||||
# General utility function to handle the status from the Pa_* functions
|
||||
function handle_status(err::PaError, show_warnings::Bool=true)
|
||||
function handle_status(err::PaError)
|
||||
if err == PA_OUTPUT_UNDERFLOWED || err == PA_INPUT_OVERFLOWED
|
||||
if show_warnings
|
||||
msg = @locked ccall((:Pa_GetErrorText, libportaudio),
|
||||
Ptr{Cchar}, (PaError,), err)
|
||||
@warn("libportaudio: " * unsafe_string(msg))
|
||||
end
|
||||
@debug unsafe_string(
|
||||
@locked ccall((:Pa_GetErrorText, libportaudio),
|
||||
Ptr{Cchar}, (PaError,), err)
|
||||
)
|
||||
elseif err != PA_NO_ERROR
|
||||
msg = @locked ccall((:Pa_GetErrorText, libportaudio),
|
||||
Ptr{Cchar}, (PaError,), err)
|
||||
|
|
Loading…
Reference in a new issue