Skip to content
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

Reliably avoid audio pop/glitch at start/end of stream #455

Closed
timlod opened this issue Feb 27, 2023 · 2 comments
Closed

Reliably avoid audio pop/glitch at start/end of stream #455

timlod opened this issue Feb 27, 2023 · 2 comments

Comments

@timlod
Copy link

timlod commented Feb 27, 2023

Hi, thanks for this package, which I'm currently using to prototype a pet project loop machine!

One thing that I haven't been able to avoid is an audible pop whenever I start/stop an OutputStream:

stream = sd.OutputStream(
            samplerate=96000,
            device="default",
            channels=1,
            callback=self._get_callback(),
            blocksize=512
)

I'm currently playing a simple sine sweep, at the start and end of which I've put a fade-in/out of 5ms.
There's no pop when looping, but often when starting, and always when stopping playback.

When stopping, I also only raise sd.CallbackStop after executing callbacks which run a fade-out of 5ms, yet there's still an audible pop.
The code is a bit lengthy, but in principle the last code called inside the callback will look somewhat like this:

# Let's assume blocksize is large enough for the fade-out to be long enough to eliminate pop
# In reality, this operation is spread out over multiple callbacks
outdata[:] *= np.linspace(1, 0, blocksize)
raise sd.CallbackStop()

So the last outdata I can print before execution stops clearly shows the fade-out is applied, which makes me think that perhaps the last buffer isn't playing, or there's an extra/non-empty buffer playing after, which I don't have control over.

Any ideas what this could be?

timlod added a commit to timlod/loopmate that referenced this issue Feb 27, 2023
@mgeier
Copy link
Member

mgeier commented Mar 3, 2023

Did you try different host APIs and different (virtual) devices?

I have experienced clicks when starting/stopping streams on Linux, depending on the chosen device.

If that's it, I think that's a deeper problem that cannot be solved from the Python side.

It might even be a hardware issue, maybe some kind of DC offset that you hear when starting/stopping the stream?

In general, I would recommend that you decouple the start of the stream from the start of your sound playback.
If you start the stream at application startup (or after device selection), the artifact might be less annoying.

If there is still a glitch when you start your playback while the stream has already been running, you should check the status flags. And if those are fine, the problem is most likely in your signal generation.

@timlod
Copy link
Author

timlod commented Mar 6, 2023

I did try different devices, and I think you're right that it probably depends on host API/device.
It's definitely better with one of the audio interfaces I tried, all else being equal (although still sometimes noticeable).

I already decoupled the start of the stream from the start of the sound playback for the most important cases, which does help.
I guess I'll just have to live with the general issue, or mitigate as much as possible.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants