releases read/write busy flag on an exception
This commit is contained in:
parent
8ee46f5125
commit
d193a9c83d
2 changed files with 51 additions and 33 deletions
15
README.md
15
README.md
|
@ -1,7 +1,18 @@
|
||||||
PortAudio.jl
|
PortAudio.jl
|
||||||
==========
|
============
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/JuliaAudio/PortAudio.jl.svg?branch=master)](https://travis-ci.org/JuliaAudio/PortAudio.jl)
|
[![Build Status](https://travis-ci.org/JuliaAudio/PortAudio.jl.svg?branch=master)](https://travis-ci.org/JuliaAudio/PortAudio.jl)
|
||||||
[![codecov.io] (http://codecov.io/github/JuliaAudio/PortAudio.jl/coverage.svg?branch=master)] (http://codecov.io/github/JuliaAudio/PortAudio.jl?branch=master)
|
[![codecov.io] (http://codecov.io/github/JuliaAudio/PortAudio.jl/coverage.svg?branch=master)] (http://codecov.io/github/JuliaAudio/PortAudio.jl?branch=master)
|
||||||
|
|
||||||
PortAudio.jl is a wrapper for [libportaudio](http://www.portaudio.com/), which gives cross-platform access to audio devices. It is compatible with the types defined in [SampleTypes.jl](https://github.com/JuliaAudio/SampleTypes.jl), so it provides `PASampleSink` and `PASampleSource` types, which can be read from and written to.
|
PortAudio.jl is a wrapper for [libportaudio](http://www.portaudio.com/), which gives cross-platform access to audio devices. It is compatible with the types defined in [SampleTypes.jl](https://github.com/JuliaAudio/SampleTypes.jl), so it provides `PortAudioSink` and `PortAudioSource` types, which can be read from and written to.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Set up an audio pass-through from microphone to speaker
|
||||||
|
|
||||||
|
```julia
|
||||||
|
src = PortAudioSource()
|
||||||
|
sink = PortAudioSink()
|
||||||
|
write(sink, source)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
|
@ -93,24 +93,28 @@ function SampleTypes.unsafe_write(sink::PortAudioSink, buf::SampleBuf)
|
||||||
shift!(sink.waiters)
|
shift!(sink.waiters)
|
||||||
end
|
end
|
||||||
|
|
||||||
sink.busy = true
|
|
||||||
total = nframes(buf)
|
total = nframes(buf)
|
||||||
written = 0
|
written = 0
|
||||||
|
try
|
||||||
|
sink.busy = true
|
||||||
|
|
||||||
while written < total
|
while written < total
|
||||||
n = min(size(sink.pabuf, 2), total-written, Pa_GetStreamWriteAvailable(sink.stream))
|
n = min(size(sink.pabuf, 2), total-written, Pa_GetStreamWriteAvailable(sink.stream))
|
||||||
bufstart = 1+written
|
bufstart = 1+written
|
||||||
bufend = n+written
|
bufend = n+written
|
||||||
@devec sink.jlbuf[1:n, :] = buf[bufstart:bufend, :]
|
@devec sink.jlbuf[1:n, :] = buf[bufstart:bufend, :]
|
||||||
transpose!(sink.pabuf, sink.jlbuf)
|
transpose!(sink.pabuf, sink.jlbuf)
|
||||||
Pa_WriteStream(sink.stream, sink.pabuf, n, false)
|
Pa_WriteStream(sink.stream, sink.pabuf, n, false)
|
||||||
written += n
|
written += n
|
||||||
sleep(POLL_SECONDS)
|
sleep(POLL_SECONDS)
|
||||||
end
|
end
|
||||||
sink.busy = false
|
finally
|
||||||
if length(sink.waiters) > 0
|
# make sure we release the busy flag even if the user ctrl-C'ed out
|
||||||
# let the next task in line go
|
sink.busy = false
|
||||||
notify(sink.waiters[1])
|
if length(sink.waiters) > 0
|
||||||
|
# let the next task in line go
|
||||||
|
notify(sink.waiters[1])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
written
|
written
|
||||||
|
@ -124,26 +128,29 @@ function SampleTypes.unsafe_read!(source::PortAudioSource, buf::SampleBuf)
|
||||||
shift!(source.waiters)
|
shift!(source.waiters)
|
||||||
end
|
end
|
||||||
|
|
||||||
source.busy = true
|
|
||||||
|
|
||||||
total = nframes(buf)
|
total = nframes(buf)
|
||||||
read = 0
|
read = 0
|
||||||
|
|
||||||
while read < total
|
try
|
||||||
n = min(size(source.pabuf, 2), total-read, Pa_GetStreamReadAvailable(source.stream))
|
source.busy = true
|
||||||
Pa_ReadStream(source.stream, source.pabuf, n, false)
|
|
||||||
transpose!(source.jlbuf, source.pabuf)
|
|
||||||
bufstart = 1+read
|
|
||||||
bufend = n+read
|
|
||||||
@devec buf[bufstart:bufend, :] = source.jlbuf[1:n, :]
|
|
||||||
read += n
|
|
||||||
sleep(POLL_SECONDS)
|
|
||||||
end
|
|
||||||
|
|
||||||
source.busy = false
|
while read < total
|
||||||
if length(source.waiters) > 0
|
n = min(size(source.pabuf, 2), total-read, Pa_GetStreamReadAvailable(source.stream))
|
||||||
# let the next task in line go
|
Pa_ReadStream(source.stream, source.pabuf, n, false)
|
||||||
notify(source.waiters[1])
|
transpose!(source.jlbuf, source.pabuf)
|
||||||
|
bufstart = 1+read
|
||||||
|
bufend = n+read
|
||||||
|
@devec buf[bufstart:bufend, :] = source.jlbuf[1:n, :]
|
||||||
|
read += n
|
||||||
|
sleep(POLL_SECONDS)
|
||||||
|
end
|
||||||
|
|
||||||
|
finally
|
||||||
|
source.busy = false
|
||||||
|
if length(source.waiters) > 0
|
||||||
|
# let the next task in line go
|
||||||
|
notify(source.waiters[1])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
read
|
read
|
||||||
|
|
Loading…
Reference in a new issue