Coder Social home page Coder Social logo

Comments (12)

mgeier avatar mgeier commented on July 20, 2024

Thanks for having a critical look at this, I appreciate that!

ad 1) That's strange, the sleep trick should do it. Another way would be to set the block size to an insanely low value, e.g. blocksize=1. If the flags are never set, there might be a bug somewhere! I definitely get those flags when using small block sizes.
There is no specific example to test this, but you can try those examples which allow setting the block size. Actually, there are no automated tests at all; If you want to help out with that, that would be great!

ad 2) This has never worked for me (I tried it on Linux). The PortAudio documentation isn't very verbose about that, but if I remember correctly (probably this was mentioned on the mailing list?), this is only supposed to work on certain host APIs. I've actually started working on an example (ce662b8), but like you, I've never seen the flag. And since I got the impression of it not being available on all host APIs, I just abandoned it. Feel free to investigate further!

What host API(s) are you using?
Would you actually use the "priming" feature?
If yes, what for?

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

ad 1) I'll try reproducing my problem with one of the simplified examples
ad 2) I didn't know that was an API specific feature. It's not a big deal, just a nice to have. I'm just interested in streaming audio files and in that application it makes sense to prime the buffers.

I was testing in Windows 10 w/ ASIO mainly, but I will try testing the priming feature on linux w/ ALSA as well.

BTW the code that I'm working on for streaming audio files is posted as a public gist here

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

OK

  1. prime_output_buffers doesn't seem to have any effect in linux w/ ALSA either. NBD
  1. I tried putting a sleep() in the callback of the rec_unlimited example: that underflowed as expected. (making the blocksize tiny also works). In my application however (linked in the post above) setting the blocksize very small causes the underflow flag to be set but adding a sleep() in my callback does not. What happens instead is that runs seemingly normally until I try to exit the application which gives me this error:
  File "C:\Program Files\Anaconda2\lib\site-packages\sounddevice.py", line 1110, in __exit__
    self.stop()
  File "c:\svn\partie\pARTIe\pastream.py", line 212, in stop
    sd.RawOutputStream.stop(self)
  File "C:\Program Files\Anaconda2\lib\site-packages\sounddevice.py", line 1138, in stop
    _check(err, 'Error stopping stream')
  File "C:\Program Files\Anaconda2\lib\site-packages\sounddevice.py", line 2607, in _check
    raise PortAudioError(msg)
sounddevice.PortAudioError: Error stopping stream: Wait timed out

So obviously something went wrong in the background but Portaudio is not completely aware of it. I'm mainly concerned about this because I need my application to exit as soon as there are any underflow/overflows. If portaudio can't tell me that reliably then I'm in a pinch.

EDIT:

This issue only seems to occur in windows. In linux the underflow flag does get set.

from python-sounddevice.

mgeier avatar mgeier commented on July 20, 2024

Thanks for sharing your code, that's really interesting.

I had the feeling that your PortAudioStreamFactory, your multiple slightly different classes and out-of-line definition of methods is unnecessarily complicated because of my API.
I just created #65 with a few changes which might make that easier.
Could you imagine deriving your stream class (which could then be a single class) directly from sounddevice._StreamBase?
You would still have to handle the different callback signatures, but all the rest should hopefully get significantly simpler.

Regarding your actual problem: Thanks for the additional tests. Sadly, I have no idea why sometimes you don't get the expected callback flags. This might be a problem with PortAudio itself, but I'm not sure.
Did you try the different versions of the DLL that are available?

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

Yeah the way I wrote the classes isn't ideal, mostly because of having to duplicate code, but it wasn't too difficult to write so it's not a big deal for me.

I made some updates to my code and now it seems like I can reliably get it to raise an underflow condition but I'm still not really convinced of how reliable this flag really is. I have an inkling that underflow can still occur without portaudio letting you know if the drop out is short enough. (I wonder if it's possible that data might be getting dropped over USB since I'm using a USB audio device). I'll see if I can dig a little deeper in the following days.

I have not tried the different DLL's, I'm just using the windows sounddevice build provided by gohlke. That uses a pretty recent portaudio version right?

from python-sounddevice.

mgeier avatar mgeier commented on July 20, 2024

OK, I've merged #65 anyway. If you have any ideas how to improve the API for a use case like yours, please tell me!

I don't know how reliable those flags are, in case of doubt you could ask on the PortAudio mailing list.

PortAudio has loopback tests which should be able to detect dropped audio blocks. I've been meaning to port them to Python, but I haven't yet. See #14. If you like to implement this or have some other ideas how to systematically test this, that would be great!

And yes, the Gohlke DLLs should use the most recent PortAudio version. But to be sure, you should check sd.get_portaudio_version().

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

@mgeier I've reviewed #65 and it looks really helpful. Thanks for adding this!

Hmm the PortAudio loopback tests look pretty extensive. I had approached loopback testing from a very different angle in my tests for the audio file streamer script I've been writing. The test code is here. All I'm doing in the tests is to generate a stream of random integers then verify them in a separate thread as the audio data comes in. I used the ALSA loop module - snd-aloop - to set up a virtual loopback device then configured that using the .asroundrc file I posted along with my code. I have very little experience with JACK but likely I could adapt my scripts to use it and maybe make something that works across platforms.

BTW I've added some comments to #14

from python-sounddevice.

mgeier avatar mgeier commented on July 20, 2024

I guess it doesn't have to be JACK.
I was just hoping (but didn't try yet) that JACK with the dummy driver could be used on a CI site like travis-ci.
But probably that works just as well (or better?) with ALSA and snd-aloop?
Thanks for bringing that up, I didn't know that before (and I know very little about ALSA anyway).

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

I don't really know anything about travis-ci..do you get to choose the OS you're running? The upside to using JACK is that JACK works across platforms. Mine was more of a one off test. I'll try using the JACK dummy driver when I get some spare time.

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

I'm going to consider this issue closed at this point. It may be that portaudio doesn't always properly detect underruns, but that doesn't have anything to do with sounddevice. Same goes for the prime_output_buffers_using_stream_callback: if anything this is a portaudio or even a API specific feature/bug. If I find anything further I'll post it here.

Many thanks for your support!

from python-sounddevice.

mgeier avatar mgeier commented on July 20, 2024

... about travis-ci..do you get to choose the OS you're running?

AFAIK, Linux (Ubuntu) and OSX are supported.

Here are two working Linux example configurations I've made:
https://github.com/AudioProcessingFramework/apf/blob/master/.travis.yml
https://github.com/bastibe/PySoundFile/blob/master/.travis.yml

OSX can apparently be enabled with:

os:
  - osx

There are also other CI services available, it doesn't have to be travis-ci if something else works better.

JACK works across platforms

That's theoretically true, but AFAICT PortAudio can only really use it on Linux.
I've tried to compile the JACK host API on macOS but failed (probably my fault). But even if JACK is not directly supported by PortAudio/macOS, it can still be used because all CoreAudio applications can be re-routed to JACK. It might be a somewhat complicated setup procedure, though.
On Windows, I don't think we can use JACK.

But anyway, those loopback tests don't have to be host API-specific, people can just use an actual physical cable on any platform.
Just the automated CI tests would have to run on some kind of virtual loopback cable.

... but that doesn't have anything to do with sounddevice.

The sounddevice library inherits some bugs from PortAudio. From a user's perspective it's still a bug in sounddevice, therefore an open issue would be appropriate. There's most likely nothing I can do about it though, so I would mark it as "wontfix".

from python-sounddevice.

tgarc avatar tgarc commented on July 20, 2024

Well JACK is available on Windoze but now that I look into it I see that its support in Windows relies on using Portaudio which seems to defeat the purpose of using jack for testing.

I'll defer to you on the OSX testing, I don't have an OSX machine to test on and I'm not really familiar with it.

from python-sounddevice.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.