Skip to content

Stale data when recording system audio #217

@gchilds

Description

@gchilds

When recording from the Background Music device, it's possible to get a tightly looping, stale last buffer of audio data when whatever is playing out to the device stops playing.

The strange thing about this bug is that it doesn't always reproduce, and seems dependent on the order in which core audio clients start.

One repro that works for me is to open QuickTime Player > New Audio Recording, select Background Music from the drop down menu, then open an audio editor that lets you choose the output device (e.g. Amadeus Pro) and start playing a file. You can see the level monitoring in QuickTime Player (and hear it too if you add some form of playthrough, but I'm trying to minimize moving parts in this issue) and if you stop the file playing in the audio editor you may see the levels continue to change. In that case you can hit record and then listen to the looping stale buffer. You may need to try a few times, change default output device, quit other audio apps. The bug reproduces on 10.13 and 10.14.

The reason I say it's strange that the bug isn't always reproducible is because it looks like it should always reproduce, as there's driver does track what time the audio buffer represents - access is always the sample timestamp modulo the buffer size:

https://github.com/kyleneideck/BackgroundMusic/blob/master/BGMDriver/BGMDriver/BGM_Device.cpp#L1430

and here I suspect I don't understand the driver timestamps work or how multiple clients look to the driver as it looks like a 2nd client would always read inconsistent data from the ring buffer unless it started reading at exactly the right offset. And maybe I don't understand the audio server plugin architecture, because when there's no stale data it's as if core audio knows the driver cannot have any new data for it.

I'm happy to work on tracking the ring buffer start and finish sample times and return zero samples when someone reads outside the available range, but is that the right thing to do?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions