-
Notifications
You must be signed in to change notification settings - Fork 642
A2DP sink demo reconnect bug #683
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
Comments
btstack_audio_pico_sink_fill_buffers implements a polling logic, so it's plausible/expected that the call to take_audio_buffer returns NULL - but it shouldn't return NULL always. With the original code, init_audio is only called once (as btstack_audio_pico_audio_buffer_pool is never cleared). Could you try to figure out, why init_audio is called twice for you (which then would cause the panic, as the PIO SM is already set up)? Alternatively, it might be good to test the open/start/stop/close sequence, e.g. with a timer and the mod-player or the sine_player demos. |
1)Yes, with the original code, init_audio it's called every time you connect a bluetooth audio source and play some music. If you disconnect after that and then finally reconnect and try to play music again it panics only the second time you play the music. That's because after the connection is released and the stream is closed via this function : static void media_processing_close(void){
if (!media_initialized) return;
media_initialized = 0;
audio_stream_started = 0;
sbc_frame_size = 0;
// stop audio playback
const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
if (audio){
printf("close stream\n");
audio->close();
}
} that calls 2)Second problem is that there is no audio after you do the steps i listed above. Regarding the buffer I dug deeper with the debugger and the strange behaviour is : initially data are written into the ring buffer, for about 1904 Bytes but then the function: static void playback_handler(int16_t * buffer, uint16_t num_audio_frames){
// called from lower-layer but guaranteed to be on main thread
if (sbc_frame_size == 0){
memset(buffer, 0, num_audio_frames * BYTES_PER_FRAME);
return;
}
// first fill from resampled audio
uint32_t bytes_read;
btstack_ring_buffer_read(&decoded_audio_ring_buffer, (uint8_t *) buffer, num_audio_frames * BYTES_PER_FRAME, &bytes_read);
buffer += bytes_read / NUM_CHANNELS;
num_audio_frames -= bytes_read / BYTES_PER_FRAME;
// then start decoding sbc frames using request_* globals
request_buffer = buffer;
request_frames = num_audio_frames;
while (request_frames && btstack_ring_buffer_bytes_available(&sbc_frame_ring_buffer) >= sbc_frame_size) {
// decode frame
uint8_t sbc_frame[MAX_SBC_FRAME_SIZE];
btstack_ring_buffer_read(&sbc_frame_ring_buffer, sbc_frame, sbc_frame_size, &bytes_read);
btstack_sbc_decoder_process_data(&state, 0, sbc_frame, sbc_frame_size);
//printf("bytes_read = %d\n", bytes_read);
}
} doesn't get called anymore and the program outputs : "Error storing samples in SBC ring buffer!!!" to the serial monitor. By looking at the returned code of the function I noticed that the problem regards the buffers in particular the ones regarding the audio which are implemented in this file https://github.com/raspberrypi/pico-extras/blob/4ccfef6fe068bbae8106d0d1f072c7f997472040/src/common/pico_audio/audio.cpp like a producer-consumer with semaphores to sync the access to the shared buffer. Maybe the problem is there, what do you think? Anyway thanks for the help! |
I'm still confused. In btstack_audio_pico_sink_init, btstack_audio_pico_audio_buffer_pool is set with the return value from init_audio. Assuming that the return value isn't NULL, init_audio should never be called again. How/why/where do you think btstack_audio_pico_audio_buffer_pool is set back to NULL? I'd suggest to follow the quick & dirty approach, which does not try to free the PIO SMs and I2S, and just tries to re-enable I2S playback after the reconnect. (Yes, it would be better to fully release all resources, but that requires a better understanding) |
Ok the quick and dirty approach works! In the static void media_processing_close(void){
if (!media_initialized) return;
//media_initialized = 0; <--------don't clear this flag so it doesn't initialize again after reconnect!
audio_stream_started = 0;
sbc_frame_size = 0;
// stop audio playback
const btstack_audio_sink_t * audio = btstack_audio_sink_get_instance();
if (audio){
printf("close stream\n");
audio->close();
}
} Thank you! |
Describe the bug
In the a2dp_sink_demo example built for the pico2W there is no more audio, after reconnecting.
Expected behavior
Audio working after reconnecting to the pico.
HCI Packet Logs
Packets arrives but are not saved in the SBC ring buffer. In fact I logged them and they arrive but I don't have a dump now.
Environment: (please complete the following information):
Additional context
From the concise description when I follow these steps:
1)I connect to the pico with my phone
2)I listen to some music, it works really good!
3)I disconnect and then reconnect
4)and finally I restart the music,
The first thing happened was that the pico panicked because it cannot claim again the same pio SM, so i modified the code of the audio_i2s.c to have a deinit function that is something like this:
and i added that code to
https://github.com/raspberrypi/pico-examples/blob/84e8d489ca321a4be90ee49e36dc29e5c645da08/pico_w/bt/btstack_audio_pico.c#L192
so now it works, i can disconnect and reconnect and it doesn't panic anymore but I can't hear any audio and on the console I receive the "Error storing samples in SBC ring buffer!!!" over and over. It seems to have something to do with buffers, in fact using the debugger i found out that the code listed below (in the same file btstack_audio_pico.c) always breaks the loop and doesn't fill the audio_buffer.
Any help would be greatly appreciated.
Thanks.
Mattia.
The text was updated successfully, but these errors were encountered: