-
Notifications
You must be signed in to change notification settings - Fork 456
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
A2DPSink callbacks are not called properly #2751
Comments
Your running into a cut and paste error and the BTStack weirdness, I think. 1 and 2 is just what the BTStack library in the pico SDK is doing. We get a connect event, we call our callback. They're sending multiple events, sometimes not in what I'd consider logical order. 3 yeah, oops I forgot to callback from the AVRCP message handler. A PR would be welcome. 4 should be deleted. This is a sink not a source so it's not transmitting anything. For your needs you need to implement a BluetoothAudioConsumer which will get the decompressed audio samples as they arrive. A real Stream was not implemented because that would imply yet one more later of buffering and memory usage. The audio output codecs already have this logic and memory management so it's pushed off to them. |
I'll see what I can do here, but no promises - coding for microcontrollers is still new to me =)
Will it, tho? Examples of consumers that I can find (BluetoothAudioConsumerI2S.cpp, for example) suggests that consumer doesn't get any samples passively, rather they request them with |
Ah, I think you're correct there. It was a while ago when I wrote this, but it is driven off of the request side, not the source. That's what the BTStack folks and other stacks I've seen implement because BT is so unreliable and subject to frequent dropouts, and it allows for some frequency drift in playback vs. encode. So you do need to pace this off of some event generator. But aren't you outputting the audio after doing something? If so, then in the I2S callback you register (i.e. nothing in
|
Eventually - sure! For now - I'm tinkering without any sound output (DAC has not arrived yet), just (trying to) grab samples and calculate stuff, so callbacks would've been helpful to test. Anyway - I'll leave this issue open in case I (or someone else) manage to fix volume callbacks and PR. |
Your other option is to just make a new BTAudio class which doesn't do the 0-stuffing underflow bits. arduino-pico/libraries/BluetoothAudio/src/A2DPSink.cpp Lines 237 to 241 in 8caa590
You'd obviously need to return the read amount since it's not guaranteed anymore. That's part of the reference class because you're theoretically pulling from the BT ring buffer at the same rate as it's being filled so you'd never really hit that except in case of drift. There are more advanced ways to correct (repeating samples if you detect you're undersupplying, or dropping if you're consistently too far ahead) but they're not implemented here. |
Hello! I'm trying to prototype a Bluetooth speaker with audio visualization, but I've stumbled on weird behavior of A2DPSink class.
Sketch code
Connecting my Android phone to Pico W and playing around with some music and volume controls, I get following output:
There are several oddities here:
Looking through A2DPSink.cpp code reveals that while onTransmit and onVolume callbacks does get saved in class fields, there are no calls to it at all! Is this intended? If yes, how could I get access to volume controls?
Also, since I need to do some processing on audio samples, there is no obvious way to either get audio data in a callback (since there is no relevant arguments in onTransmit callback) or by reading a stream of it (while A2DPSink is a Stream, all of it's Stream methods are effectively stubs).
Looking into BluetoothAudioConsumerI2S, it seems to me that it relies on callbacks from I2S to do its job, which means that I need to setup some external timer that will tick for samples every now and then so I could read samples from A2DPSink myself. I would prefer to either have a callback to that, or a read-only Stream so that I could process data as they arrive and not rely on I2S callbacks. Is there any way to do this that I miss here?
Thank you!
The text was updated successfully, but these errors were encountered: