Skip to content

Commit afa6609

Browse files
committed
example: mixing a2dp
1 parent 7a6dd2a commit afa6609

File tree

3 files changed

+76
-5
lines changed

3 files changed

+76
-5
lines changed

examples/examples-basic-api/basic-a2dp-i2s/AudioConfigLocal.h

Lines changed: 0 additions & 4 deletions
This file was deleted.

examples/examples-basic-api/basic-a2dp-i2s/basic-a2dp-i2s.ino

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
BluetoothA2DPSink a2dp_sink;
1515
I2SStream i2s;
1616

17-
// Write data to SPDIF in callback
17+
// Write data to I2S
1818
void read_data_stream(const uint8_t *data, uint32_t length) {
1919
i2s.write(data, length);
2020
}
@@ -36,6 +36,8 @@ void setup() {
3636
cfg.sample_rate = a2dp_sink.sample_rate();
3737
cfg.channels = 2;
3838
cfg.bits_per_sample = 16;
39+
cfg.buffer_count = 8;
40+
cfg.buffer_size = 256;
3941
i2s.begin(cfg);
4042
}
4143

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* @file basic-a2dp-mixer-i2s.ino
3+
* @brief A2DP Sink with output to mixer: I think this is the most efficient way
4+
* of mixing a signal that is coming from A2DP which requires only 160 byte of additional RAM.
5+
*
6+
* @author Phil Schatzmann
7+
* @copyright GPLv3
8+
*/
9+
10+
#include "AudioTools.h"
11+
#include "BluetoothA2DPSink.h"
12+
13+
AudioInfo info(44100, 2, 16);
14+
BluetoothA2DPSink a2dp_sink;
15+
I2SStream i2s;
16+
SineWaveGenerator<int16_t> sineWave(10000); // subclass of SoundGenerator with max amplitude of 10000
17+
GeneratedSoundStream<int16_t> sound(sineWave); // Stream generated from sine wave
18+
OutputMixer<int16_t> mixer(i2s, 2); // output mixer with 2 outputs
19+
const int buffer_size = 80; // split up the output into small chunks
20+
uint8_t sound_buffer[buffer_size];
21+
22+
// Write data to mixer
23+
void read_data_stream(const uint8_t *data, uint32_t length) {
24+
// To keep the mixing buffer small we split up the output into small chunks
25+
int count = length / buffer_size + 1;
26+
for (int j = 0; j < count; j++) {
27+
const uint8_t *start = data + (j * buffer_size);
28+
const uint8_t *end = min(data + length, start + buffer_size);
29+
int len = end - start;
30+
if (len > 0) {
31+
// write a2dp
32+
mixer.write(start, len);
33+
34+
// write sine tone with identical length
35+
sound.readBytes(sound_buffer, len);
36+
mixer.write(sound_buffer, len);
37+
38+
// We could flush to force the output but this is not necessary because we
39+
// were already writing all 2 streams mixer.flushMixer();
40+
}
41+
}
42+
}
43+
44+
void setup() {
45+
Serial.begin(115200);
46+
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
47+
48+
// setup Output mixer with min necessary memory
49+
mixer.begin(buffer_size);
50+
51+
// Register data callback
52+
a2dp_sink.set_stream_reader(read_data_stream, false);
53+
54+
// Start Bluetooth Audio Receiver
55+
a2dp_sink.set_auto_reconnect(false);
56+
a2dp_sink.start("a2dp-i2s");
57+
58+
// Update sample rate
59+
info.sample_rate = a2dp_sink.sample_rate();
60+
61+
// start sine wave
62+
sineWave.begin(info, N_B4);
63+
64+
// setup output
65+
auto cfg = i2s.defaultConfig();
66+
cfg.copyFrom(info);
67+
// cfg.pin_data = 23;
68+
cfg.buffer_count = 8;
69+
cfg.buffer_size = 256;
70+
i2s.begin(cfg);
71+
}
72+
73+
void loop() { delay(100); }

0 commit comments

Comments
 (0)