-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix issue #1 #75
fix issue #1 #75
Conversation
Thanks! I'm just trying to reproduce the original problem #1 on macOS and the error doesn't seem to happen there (but your changes don't seem to hurt, either). I'll try it later on Linux. On which OSs could you reproduce the original error?
I don't understand. A sound started with Maybe I'm missing something ... can you provide an example where a global I think it makes sense to call |
Did you try using python 2? I tested it using python 2 on Linux. Anyhow, it absolutely makes sense that the error would occur: the
What I meant was, I think that you can start and stop a Anyhow, that's kind of a separate discussion. One detail about the commit: Do you have any objection to the part of the commit which doesn't ignore errors on |
OK, I think this was a bug in PortAudio and it was fixed in the newest version. Which PortAudio version did you use? I just downgraded to But anyway, since not everyone is using the latest and greatest version yet, we should apply your fix. This PR indeed fixes the problem, but I think it does too much. I assumed that closing a stream implies stopping it (or rather, to be exact, aborting it). Did you encounter a situation where this wasn't the case? I'm not sure about the Even if this can happen, the stream would already be in a broken state, so
Yes, you can indeed do that. Try this in an interactive session: >>> import sounddevice as sd
>>> def callback(indata, outdata, *stuff):
... outdata[:] = indata
...
>>> s = sd.Stream(channels=2, callback=callback)
>>> s.start()
>>> s.stop()
>>> s.start() Works like a charm for me (BTW, multiple consecutive calls to >>> s.close()
>>> s.start()
Traceback (most recent call last):
...
sounddevice.PortAudioError: Error starting stream: Invalid stream pointer
>>> If the stream is stopped by raising an exception in the callback, it cannot be re- |
wait so you're saying that the only time that |
pro tip: If you use Phew. I'm using an older portaudio version so it's possible this was a bug that's been fixed. I'll let the portaudio people know otherwise. |
Yes. At least that's how I understand it. The behavior of On top of somewhat vaguely specified behavior, you never know if all host APIs at least behave the same way ... |
Well here's a case in point: when I abort() a stream on my redhat machine (using ALSA), IsStreamStopped returns False. (Which is not what I'd expect). However, I tested the same code on a windows machine with ASIO and IsStreamStopped returns True after abort() is called. I need to go back and sync up my portaudio library versions to see if this difference in behavior is still true today..the one I'm using on linux is all the way from 2010. EDIT: I tested this with a portaudio release from Oct 2016 and IsStreamStopped still returns False on Linux/ALSA after a call to AbortStream. I've reported this on the portaudio mailing list. |
@tgarc Would be nice to get this merged ... what are your thoughts on my comments above (#75 (comment))? |
I think you're right. The thing is when I tried removing all the changes except for the adding of |
so oddly enough, aborting or closing the stream inside the exit handler causes portaudio to hang. however calling PaStopStream before closing seems to fix the issue altogether. Try it out but I think this is ready for a merge. Feel free to look into why it hangs when you call close() without calling stop() first in the exit handler, but it was starting to look like a rabbit hole to me. I suspect it has to do with the non-deterministic behavior of closing down the interpreter plus portaudio, but that's about as far as I got. |
True. I tried loading up a newer (2016) version of portaudio and I couldn't reproduce this issue. |
+ Apparently older versions of portaudio don't handle closing any open streams which would sometimes cause a segmentation fault while exiting python. This commit makes sure any open streams are closed in the atexit handler
@tgarc Thanks for your investigations, I could reproduce the hanging behavior and it is indeed very strange. I wanted to suggest that you use I don't have the stamina to investigate this further, and I wouldn't even know where to start. But since you fixed it and current versions of PortAudio don't even have that bug anymore, I'm fine with not knowing all the details. I'm merging this, thanks again for your help! |
fix for #1
this commit makes sure that any streams started with play/rec/playrec
are closed before exiting to avoid segmentation faults from unreleased
PaStream objects
Added a similar try/finally to
StreamBase.__exit__
to make surewith
always closes the stream properly.Don't quote me on this but I'm pretty sure it's possible that a stream that has had
PaStopStream()
called on it can be started again without creating a new stream object so it may make sense to add a globalclose
function to deallocate the stream corresponding to_last_callback
.