mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 22:20:37 +00:00
esp32: adapt i2s buffer size to sample rate
This commit is contained in:
parent
c764140abd
commit
76a7b6f546
@ -94,9 +94,10 @@ static void btstack_audio_esp32_source_process_buffer(void);
|
|||||||
|
|
||||||
#define DRIVER_POLL_INTERVAL_MS 5
|
#define DRIVER_POLL_INTERVAL_MS 5
|
||||||
#define DMA_BUFFER_COUNT 2
|
#define DMA_BUFFER_COUNT 2
|
||||||
#define DMA_BUFFER_SAMPLES 512
|
|
||||||
#define BYTES_PER_SAMPLE_STEREO 4
|
#define BYTES_PER_SAMPLE_STEREO 4
|
||||||
|
|
||||||
|
// one DMA buffer for max sample rate
|
||||||
|
#define MAX_DMA_BUFFER_SAMPLES (48000 * 2 * DRIVER_POLL_INTERVAL_MS/ 1000)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BTSTACK_AUDIO_ESP32_OFF = 0,
|
BTSTACK_AUDIO_ESP32_OFF = 0,
|
||||||
@ -107,6 +108,7 @@ typedef enum {
|
|||||||
static bool btstack_audio_esp32_i2s_installed;
|
static bool btstack_audio_esp32_i2s_installed;
|
||||||
static bool btstack_audio_esp32_i2s_streaming;
|
static bool btstack_audio_esp32_i2s_streaming;
|
||||||
static uint32_t btstack_audio_esp32_i2s_samplerate;
|
static uint32_t btstack_audio_esp32_i2s_samplerate;
|
||||||
|
static uint16_t btstack_audio_esp32_samples_per_dma_buffer;
|
||||||
|
|
||||||
// timer to fill output ring buffer
|
// timer to fill output ring buffer
|
||||||
static btstack_timer_source_t btstack_audio_esp32_driver_timer;
|
static btstack_timer_source_t btstack_audio_esp32_driver_timer;
|
||||||
@ -230,6 +232,7 @@ static void btstack_audio_esp32_init(void){
|
|||||||
btstack_assert(btstack_audio_esp32_i2s_samplerate == btstack_audio_esp32_sink_samplerate);
|
btstack_assert(btstack_audio_esp32_i2s_samplerate == btstack_audio_esp32_sink_samplerate);
|
||||||
}
|
}
|
||||||
btstack_audio_esp32_i2s_samplerate = btstack_audio_esp32_sink_samplerate;
|
btstack_audio_esp32_i2s_samplerate = btstack_audio_esp32_sink_samplerate;
|
||||||
|
btstack_audio_esp32_samples_per_dma_buffer = btstack_audio_esp32_sink_samplerate * 2 * DRIVER_POLL_INTERVAL_MS / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btstack_audio_esp32_source_state != BTSTACK_AUDIO_ESP32_OFF){
|
if (btstack_audio_esp32_source_state != BTSTACK_AUDIO_ESP32_OFF){
|
||||||
@ -239,8 +242,11 @@ static void btstack_audio_esp32_init(void){
|
|||||||
btstack_assert(btstack_audio_esp32_i2s_samplerate == btstack_audio_esp32_source_samplerate);
|
btstack_assert(btstack_audio_esp32_i2s_samplerate == btstack_audio_esp32_source_samplerate);
|
||||||
}
|
}
|
||||||
btstack_audio_esp32_i2s_samplerate = btstack_audio_esp32_source_samplerate;
|
btstack_audio_esp32_i2s_samplerate = btstack_audio_esp32_source_samplerate;
|
||||||
|
btstack_audio_esp32_samples_per_dma_buffer = btstack_audio_esp32_source_samplerate * 2 * DRIVER_POLL_INTERVAL_MS / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btstack_assert(btstack_audio_esp32_samples_per_dma_buffer <= MAX_DMA_BUFFER_SAMPLES);
|
||||||
|
|
||||||
i2s_config_t config =
|
i2s_config_t config =
|
||||||
{
|
{
|
||||||
.mode = i2s_mode,
|
.mode = i2s_mode,
|
||||||
@ -248,8 +254,8 @@ static void btstack_audio_esp32_init(void){
|
|||||||
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
|
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
|
||||||
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
|
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
|
||||||
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
|
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
|
||||||
.dma_buf_count = DMA_BUFFER_COUNT, // Number of DMA buffers. Max 128.
|
.dma_buf_count = DMA_BUFFER_COUNT, // Number of DMA buffers. Max 128.
|
||||||
.dma_buf_len = DMA_BUFFER_SAMPLES, // Size of each DMA buffer in samples. Max 1024.
|
.dma_buf_len = btstack_audio_esp32_samples_per_dma_buffer, // Size of each DMA buffer in samples. Max 1024.
|
||||||
.use_apll = true,
|
.use_apll = true,
|
||||||
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
|
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1
|
||||||
};
|
};
|
||||||
@ -266,7 +272,8 @@ static void btstack_audio_esp32_init(void){
|
|||||||
btstack_audio_esp32_set_i2s0_mclk();
|
btstack_audio_esp32_set_i2s0_mclk();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
log_info("i2s init mode 0x%02x, samplerate %" PRIu32, i2s_mode, btstack_audio_esp32_sink_samplerate);
|
log_info("i2s init mode 0x%02x, samplerate %" PRIu32 ", samples per DMA buffer: %u",
|
||||||
|
i2s_mode, btstack_audio_esp32_sink_samplerate, btstack_audio_esp32_samples_per_dma_buffer);
|
||||||
|
|
||||||
i2s_driver_install(BTSTACK_AUDIO_I2S_NUM, &config, DMA_BUFFER_COUNT, &btstack_audio_esp32_i2s_event_queue);
|
i2s_driver_install(BTSTACK_AUDIO_I2S_NUM, &config, DMA_BUFFER_COUNT, &btstack_audio_esp32_i2s_event_queue);
|
||||||
i2s_set_pin(BTSTACK_AUDIO_I2S_NUM, &pins);
|
i2s_set_pin(BTSTACK_AUDIO_I2S_NUM, &pins);
|
||||||
@ -297,14 +304,18 @@ static void btstack_audio_esp32_deinit(void){
|
|||||||
|
|
||||||
static void btstack_audio_esp32_sink_fill_buffer(void){
|
static void btstack_audio_esp32_sink_fill_buffer(void){
|
||||||
size_t bytes_written;
|
size_t bytes_written;
|
||||||
uint8_t buffer[DMA_BUFFER_SAMPLES * BYTES_PER_SAMPLE_STEREO];
|
uint8_t buffer[MAX_DMA_BUFFER_SAMPLES * BYTES_PER_SAMPLE_STEREO];
|
||||||
|
|
||||||
|
btstack_assert(btstack_audio_esp32_samples_per_dma_buffer <= MAX_DMA_BUFFER_SAMPLES);
|
||||||
|
|
||||||
|
uint16_t data_len = btstack_audio_esp32_samples_per_dma_buffer * BYTES_PER_SAMPLE_STEREO;
|
||||||
if (btstack_audio_esp32_sink_state == BTSTACK_AUDIO_ESP32_STREAMING){
|
if (btstack_audio_esp32_sink_state == BTSTACK_AUDIO_ESP32_STREAMING){
|
||||||
(*btstack_audio_esp32_sink_playback_callback)((int16_t *) buffer, DMA_BUFFER_SAMPLES);
|
(*btstack_audio_esp32_sink_playback_callback)((int16_t *) buffer, btstack_audio_esp32_samples_per_dma_buffer);
|
||||||
// duplicate samples for mono
|
// duplicate samples for mono
|
||||||
if (btstack_audio_esp32_sink_num_channels == 1){
|
if (btstack_audio_esp32_sink_num_channels == 1){
|
||||||
int16_t i;
|
int16_t i;
|
||||||
int16_t * buffer16 = (int16_t *) buffer;
|
int16_t * buffer16 = (int16_t *) buffer;
|
||||||
for (i=DMA_BUFFER_SAMPLES-1;i >= 0; i--){
|
for (i=btstack_audio_esp32_samples_per_dma_buffer-1;i >= 0; i--){
|
||||||
buffer16[2*i ] = buffer16[i];
|
buffer16[2*i ] = buffer16[i];
|
||||||
buffer16[2*i+1] = buffer16[i];
|
buffer16[2*i+1] = buffer16[i];
|
||||||
}
|
}
|
||||||
@ -313,11 +324,11 @@ static void btstack_audio_esp32_sink_fill_buffer(void){
|
|||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
i2s_write(BTSTACK_AUDIO_I2S_NUM, buffer, sizeof(buffer), &bytes_written, 0);
|
i2s_write(BTSTACK_AUDIO_I2S_NUM, buffer, data_len, &bytes_written, 0);
|
||||||
if (bytes_written != sizeof(buffer)){
|
if (bytes_written != data_len){
|
||||||
log_error("i2s_write: only %u of %u!!!", (int) bytes_written, (int) sizeof(buffer));
|
log_error("i2s_write: only %u of %u!!!", (int) bytes_written, (int) sizeof(buffer));
|
||||||
}
|
}
|
||||||
btstack_assert(bytes_written == sizeof(buffer));
|
btstack_assert(bytes_written == data_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btstack_audio_esp32_sink_init(
|
static int btstack_audio_esp32_sink_init(
|
||||||
@ -404,21 +415,24 @@ const btstack_audio_sink_t * btstack_audio_esp32_sink_get_instance(void){
|
|||||||
|
|
||||||
static void btstack_audio_esp32_source_process_buffer(void){
|
static void btstack_audio_esp32_source_process_buffer(void){
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
uint8_t buffer[DMA_BUFFER_SAMPLES * BYTES_PER_SAMPLE_STEREO];
|
uint8_t buffer[MAX_DMA_BUFFER_SAMPLES * BYTES_PER_SAMPLE_STEREO];
|
||||||
|
|
||||||
i2s_read(BTSTACK_AUDIO_I2S_NUM, buffer, sizeof(buffer), &bytes_read, 0);
|
btstack_assert(btstack_audio_esp32_samples_per_dma_buffer <= MAX_DMA_BUFFER_SAMPLES);
|
||||||
btstack_assert(bytes_read == sizeof(buffer));
|
|
||||||
|
uint16_t data_len = btstack_audio_esp32_samples_per_dma_buffer * BYTES_PER_SAMPLE_STEREO;
|
||||||
|
i2s_read(BTSTACK_AUDIO_I2S_NUM, buffer, data_len, &bytes_read, 0);
|
||||||
|
btstack_assert(bytes_read == data_len);
|
||||||
|
|
||||||
int16_t * buffer16 = (int16_t *) buffer;
|
int16_t * buffer16 = (int16_t *) buffer;
|
||||||
if (btstack_audio_esp32_source_state == BTSTACK_AUDIO_ESP32_STREAMING) {
|
if (btstack_audio_esp32_source_state == BTSTACK_AUDIO_ESP32_STREAMING) {
|
||||||
// drop second channel if configured for mono
|
// drop second channel if configured for mono
|
||||||
if (btstack_audio_esp32_source_num_channels == 1){
|
if (btstack_audio_esp32_source_num_channels == 1){
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
for (i=0;i<DMA_BUFFER_SAMPLES;i++){
|
for (i=0;i<btstack_audio_esp32_samples_per_dma_buffer;i++){
|
||||||
buffer16[i] = buffer16[2*i];
|
buffer16[i] = buffer16[2*i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(*btstack_audio_esp32_source_recording_callback)(buffer16, DMA_BUFFER_SAMPLES);
|
(*btstack_audio_esp32_source_recording_callback)(buffer16, btstack_audio_esp32_samples_per_dma_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user