Skip to content

Commit eecbcdf

Browse files
Derive playback devices from common AudioOutputBase (#2703)
The audio output objects all have the same general necessary configuration calls. Abstract them out to a generic AudioOutputBase interface class that they will inherit from. Simplifies letting applications use different output channels. Should be backwards compatible with existing code.
1 parent f1b965f commit eecbcdf

File tree

7 files changed

+77
-22
lines changed

7 files changed

+77
-22
lines changed

cores/rp2040/AudioOutputBase.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Abstract class for audio output devices to allow easy swapping between output devices
2+
3+
#pragma once
4+
5+
#include <Print.h>
6+
7+
class AudioOutputBase : public Print {
8+
public:
9+
virtual ~AudioOutputBase() { }
10+
virtual bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0) = 0;
11+
virtual bool setBitsPerSample(int bps) = 0;
12+
virtual bool setFrequency(int freq) = 0;
13+
virtual bool setStereo(bool stereo = true) = 0;
14+
virtual bool begin() = 0;
15+
virtual bool end() = 0;
16+
virtual bool getUnderflow() = 0;
17+
virtual void onTransmit(void(*)(void *), void *) = 0;
18+
// From Print
19+
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
20+
virtual int availableForWrite() = 0;
21+
};

libraries/BluetoothAudio/src/A2DPSource.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ void A2DPSource::clearPairing() {
220220
size_t A2DPSource::write(const uint8_t *buffer, size_t size) {
221221
BluetoothLock b;
222222

223+
size = std::min((size_t)availableForWrite(), size);
224+
223225
size_t count = 0;
224226
size /= 2;
225227

@@ -260,6 +262,7 @@ int A2DPSource::availableForWrite() {
260262
} else {
261263
avail = _pcmBufferSize - _pcmWriter + _pcmReader - 1;
262264
}
265+
avail /= sizeof(uint32_t); // availableForWrite always 32b sample pairs in this core...
263266
return avail;
264267
}
265268

libraries/BluetoothAudio/src/A2DPSource.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@
2424
#include <BluetoothHCI.h>
2525
#include <BluetoothLock.h>
2626
#include "BluetoothMediaConfigurationSBC.h"
27+
#include <AudioOutputBase.h>
2728
#include <functional>
2829
#include <list>
2930
#include <memory>
3031

3132

32-
class A2DPSource : public Stream {
33+
class A2DPSource : public Stream, public AudioOutputBase {
3334
public:
3435
A2DPSource() {
3536
}
3637

37-
bool setFrequency(uint32_t rate) {
38+
virtual ~A2DPSource() { }
39+
40+
virtual bool setFrequency(int rate) override {
3841
if (_running || ((rate != 44100) && (rate != 48000))) {
3942
return false;
4043
}
@@ -51,7 +54,14 @@ class A2DPSource : public Stream {
5154
return true;
5255
}
5356

54-
void onTransmit(void (*cb)(void *), void *cbData = nullptr) {
57+
virtual bool setBitsPerSample(int bps) override {
58+
return bps == 16;
59+
}
60+
virtual bool setStereo(bool stereo = true) override {
61+
return stereo;
62+
}
63+
64+
virtual void onTransmit(void (*cb)(void *), void *cbData = nullptr) override {
5565
_transmitCB = cb;
5666
_transmitData = cbData;
5767
}
@@ -84,7 +94,11 @@ class A2DPSource : public Stream {
8494
return true;
8595
}
8696

87-
bool getUnderflow() {
97+
virtual bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0) override {
98+
return setBufferSize(buffers * bufferWords * sizeof(int32_t));
99+
}
100+
101+
virtual bool getUnderflow() override {
88102
BluetoothLock b;
89103
if (!_running) {
90104
return false;
@@ -102,7 +116,10 @@ class A2DPSource : public Stream {
102116
}
103117
}
104118

105-
bool begin();
119+
virtual bool begin() override;
120+
virtual bool end() override {
121+
return false; // We can't actually stop bluetooth on this device
122+
}
106123

107124
std::vector<BTDeviceInfo> scan(uint32_t mask = BluetoothHCI::speaker_cod, int scanTimeSec = 5, bool async = false) {
108125
return _hci.scan(mask, scanTimeSec, async);

libraries/I2S/src/I2S.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ bool I2S::begin() {
287287
return true;
288288
}
289289

290-
void I2S::end() {
290+
bool I2S::end() {
291291
if (_running) {
292292
if (_MCLKenabled) {
293293
pio_sm_set_enabled(_pioMCLK, _smMCLK, false);
@@ -301,6 +301,7 @@ void I2S::end() {
301301
delete _i2s;
302302
_i2s = nullptr;
303303
}
304+
return true;
304305
}
305306

306307
int I2S::available() {

libraries/I2S/src/I2S.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,23 @@
2121

2222
#pragma once
2323
#include <Arduino.h>
24-
#include "AudioBufferManager.h"
24+
#include <AudioBufferManager.h>
25+
#include <AudioOutputBase.h>
2526

26-
class I2S : public Stream {
27+
class I2S : public Stream, public AudioOutputBase {
2728
public:
2829
I2S(PinMode direction = OUTPUT, pin_size_t bclk = 26, pin_size_t data = 28, pin_size_t mclk = 25);
2930
virtual ~I2S();
3031

3132
bool setBCLK(pin_size_t pin);
3233
bool setDATA(pin_size_t pin);
3334
bool setMCLK(pin_size_t pin);
34-
bool setBitsPerSample(int bps);
35-
bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0);
36-
bool setFrequency(int newFreq);
35+
virtual bool setBitsPerSample(int bps) override;
36+
virtual bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0) override;
37+
virtual bool setFrequency(int newFreq) override;
38+
virtual bool setStereo(bool stereo = true) override {
39+
return stereo;
40+
}
3741
bool setLSBJFormat();
3842
bool setTDMFormat();
3943
bool setTDMChannels(int channels);
@@ -46,8 +50,11 @@ class I2S : public Stream {
4650
return begin();
4751
}
4852

49-
bool begin();
50-
void end();
53+
virtual bool begin() override;
54+
virtual bool end() override;
55+
virtual bool getUnderflow() override {
56+
return getOverUnderflow();
57+
}
5158

5259
// from Stream
5360
virtual int available() override;

libraries/PWMAudio/src/PWMAudio.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ PWMAudio::~PWMAudio() {
4040
end();
4141
}
4242

43-
bool PWMAudio::setBuffers(size_t buffers, size_t bufferWords) {
43+
bool PWMAudio::setBuffers(size_t buffers, size_t bufferWords, int32_t silence) {
44+
(void) silence;
4445
if (_running || (buffers < 3) || (bufferWords < 8)) {
4546
return false;
4647
}
@@ -176,7 +177,7 @@ bool PWMAudio::begin() {
176177
return true;
177178
}
178179

179-
void PWMAudio::end() {
180+
bool PWMAudio::end() {
180181
if (_running) {
181182
_running = false;
182183
pinMode(_pin, OUTPUT);
@@ -189,6 +190,7 @@ void PWMAudio::end() {
189190
dma_timer_unclaim(_pacer);
190191
_pacer = -1;
191192
}
193+
return true;
192194
}
193195

194196
int PWMAudio::available() {

libraries/PWMAudio/src/PWMAudio.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,24 @@
2121

2222
#pragma once
2323
#include <Arduino.h>
24-
#include "AudioBufferManager.h"
24+
#include <AudioOutputBase.h>
25+
#include <AudioBufferManager.h>
2526

26-
class PWMAudio : public Stream {
27+
class PWMAudio : public Stream, public AudioOutputBase {
2728
public:
2829
PWMAudio(pin_size_t pin = 0, bool stereo = false);
2930
virtual ~PWMAudio();
3031

31-
bool setBuffers(size_t buffers, size_t bufferWords);
32+
virtual bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0) override;
3233
/*Sets the frequency of the PWM in hz*/
3334
bool setPWMFrequency(int newFreq);
3435
/*Sets the sample rate frequency in hz*/
35-
bool setFrequency(int frequency);
36+
virtual bool setFrequency(int frequency) override;
3637
bool setPin(pin_size_t pin);
37-
bool setStereo(bool stereo = true);
38+
virtual bool setStereo(bool stereo = true) override;
39+
virtual bool setBitsPerSample(int bits) override {
40+
return bits == 16;
41+
}
3842

3943
bool begin(long sampleRate) {
4044
_sampleRate = sampleRate;
@@ -47,8 +51,8 @@ class PWMAudio : public Stream {
4751
return begin();
4852
}
4953

50-
bool begin();
51-
void end();
54+
virtual bool begin() override;
55+
virtual bool end() override;
5256

5357
// from Stream
5458
virtual int available() override;

0 commit comments

Comments
 (0)