bastibe/PySoundCard

Input overflowed

Closed this issue · 4 comments

I'm running pySoundcard in real-time for analysing the audio from the microphone. When I use a small block_length for the Stream (i.e. less than 256 for a 44.1KHz input) it keeps throwing this warning:

/usr/local/lib/python2.7/site-packages/pysoundcard.py:582: RuntimeWarning: 30067.9355: Input overflowed

Could you give any insight on what does it mean?

By the way, I am using the normal mode (not callback mode) since you point it is more performant and I am doing real-time processing.

What OS are you using (the error message seems to indicate Linux)? Which audio API are you using (Alsa? Jack?)? When you run your program, how much CPU utilization do you see?

In general, an input overflow means that the microphone has recorded more data than your program could deal with. Thus, microphone data is being discarded. Depending on your application, this might not be a problem at all. This usually happens if you take longer than one block length to process a block of data.

If you show me a bit of your code, maybe I can help you further.

Also, there is a method called Stream.cpu_load, which can tell you something about your CPU utilization. If you look at your regular system monitor, Python should not use more than, say, 70% CPU, or else input overflows might start happening.

I am using OSX 10.6.8, so it must be using CoreAudio I guess.

Your explanation is completely satisfactory. I tried different block_length(s) for the PySoundCard stream and, effectively, as smaller the CPU use goes up and when block_length < 256 it goes above 70% and that is when starts showing overflows. I am calculating the pitch using the YIN algorithm and even it is a C++ implementation it makes sense and it is fair enough that below 256 (so at 128 or less) it starts dropping some blocks.

Just for the sake of total clarity, what exactly is the behavior when overflowing, i.e. when microphone data is discarded. My guess is that I call stream.read(...), I do computations that take too long, and so the next stream.read(...) does not return the exact next block in time, but two or more after, right?

Thanks for the help.

PySoundCard is based on portaudio, so it is bound to portaudio's semantics. From the documentation, my understanding is that portaudio does not necessarily discard whole buffers, but single samples, too. Thus, an input overflow means that consecutive reads did not return consecutive audio data and that at least one frame of audio data was dropped between two reads.

In your case, you might get an appreciable speed boost by using the raw option of the read function. This will give you a byte stream instead of a numpy array. Since you are calling a C++ API anyway there is probably no need for creating a numpy array and then converting that back to a float array. Also, I have found that CFFI is a spectacular way of interacting with C libraries from Python that might offer another possible performance boost over other, more complex ways of interacting with C (cython, ctypes, CPython).

Thank you, I will take a lot into that!