Mixing A2DP with SPIFF sample, need help with buffering #2151
-
Hello! I'm trying to write a script that will take audio from A2DP and overlay a drum sample on top of it, then output to I2S. I'm currently storing the sample in SPIFFS but I don't think that matters. Right now, I have two BufferedStreams, one for the drum audio and one for the A2DP audio, both going to an OutputMixer like in this example. However, I'm getting stuttering on the output, like what happens when the mixer isn't getting two synchronized audio streams (writing the A2DP data to both buffers plays fine). I'm not sure how to appropriately buffer and send the decoded sample data to the mixer (I tried putting Side note: I haven't actually set up the SPIFFS samples yet, so I called Thank you!! #include <BluetoothA2DPSink.h>
#include <AudioTools.h>
#include <AudioTools/AudioCodecs/CodecWAV.h>
#include <AudioTools/Disk/AudioSourceSPIFFS.h>
// — Config —
constexpr uint32_t buffer_size = 5000; // stupidly high value for testing
constexpr char *startFilePath="/";
constexpr char* ext="wav";
BluetoothA2DPSink a2dp_sink;
I2SStream i2s;
OutputMixer<int16_t> mixer(i2s, 2);
BufferedStream a2dp_buffer(buffer_size, mixer);
BufferedStream drum_buffer(buffer_size, mixer);
AudioSourceSPIFFS source(startFilePath, ext);
WAVDecoder wavDecoder;
//EncodedAudioStream streamPlayer(source, &wavDecoder);
AudioPlayer player(source, drum_buffer, wavDecoder);
AudioInfo fmt{44100, 2, 16};
// A2DP callback
void onA2dpData(const uint8_t* data, uint32_t len) {
a2dp_buffer.write(data, len);
//player.copy(buffer_size);
}
void setup() {
Serial.begin(115200);
AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Info);
// A2DP sink config
a2dp_sink.set_stream_reader(onA2dpData, false);
a2dp_sink.set_auto_reconnect(true);
a2dp_sink.start("a2dp-i2s");
auto cfg = i2s.defaultConfig(TX_MODE);
cfg.sample_rate = 44100;
cfg.bits_per_sample = fmt.bits_per_sample;
cfg.channels = fmt.channels;
cfg.pin_bck = 18;
cfg.pin_ws = 22;
cfg.pin_data = 19;
i2s.begin(cfg);
mixer.begin(buffer_size);
player.begin(0, 0);
}
void loop() {
player.copy(buffer_size);
}
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I have improved the documentation of the OutputMixer. Please try to understand the API Your sketch has many isssues:
However, it would be better to use the direct write API by indicating the mixing channel, when possible. void onA2dpData(const uint8_t* data, uint32_t len) {
// write to channel 0
mixer.write(0, data, len);
// write to channel 1
mixer.setIndex(1);
player.copy(mixer.available(0));
// output mixing reslt
mixer.flushMixer();
}
void setup() {
...
// deactivate automatic index management
mixer.setAutoIndex(false);
...
} Also make sure that the buffer is big enough for the A2SP writes by calling resize(size); |
Beta Was this translation helpful? Give feedback.
I have improved the documentation of the OutputMixer. Please try to understand the API
Your sketch has many isssues:
However, it would be better to use the direct write API by indicating the mixing channel, whe…