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