9
9
10
10
namespace audio_tools {
11
11
12
+
12
13
/* *
13
14
* @brief R2R configuration
14
15
* @author Phil Schatzmann
@@ -19,6 +20,8 @@ class R2RConfig : public AudioInfo {
19
20
public:
20
21
std::vector<int > channel1_pins;
21
22
std::vector<int > channel2_pins;
23
+ uint16_t buffer_size = DEFAULT_BUFFER_SIZE; // automatic determination from write size
24
+ uint16_t buffer_count = 2 ; // double buffer
22
25
};
23
26
24
27
/* *
@@ -57,16 +60,26 @@ class R2ROutput : public AudioOutput {
57
60
LOGE (" channel2_pins not defined" );
58
61
return false ;
59
62
}
63
+ if (rcfg.buffer_size * rcfg.buffer_count == 0 ){
64
+ LOGE (" buffer_size or buffer_count is 0" );
65
+ return false ;
66
+ }
67
+ buffer.resize (rcfg.buffer_size , rcfg.buffer_count );
60
68
setupPins ();
61
69
timer.setCallbackParameter (this );
62
70
timer.setIsSave (true );
63
71
return timer.begin (r2r_timer_callback, cfg.sample_rate , HZ);
64
72
}
65
73
66
74
size_t write (const uint8_t *data, size_t len) override {
75
+ // if buffer has not been allocated (buffer_size==0)
76
+ if (len > rcfg.buffer_size ) {
77
+ LOGE (" buffer_size %d too small for write size: %d" , rcfg.buffer_size , len);
78
+ return len;
79
+ }
67
80
size_t result = buffer.writeArray (data, len);
68
- // activate output when buffer is full
69
- if (!is_active && buffer.isFull () ) {
81
+ // activate output when buffer is half full
82
+ if (!is_active && buffer.bufferCountFilled () >= rcfg. buffer_count / 2 ) {
70
83
LOGI (" is_active = true" );
71
84
is_active = true ;
72
85
}
@@ -76,10 +89,10 @@ class R2ROutput : public AudioOutput {
76
89
protected:
77
90
TimerAlarmRepeating timer;
78
91
// Double buffer
79
- NBuffer<uint8_t > buffer{DEFAULT_BUFFER_SIZE, 2 };
92
+ NBuffer<uint8_t > buffer{DEFAULT_BUFFER_SIZE, 0 };
80
93
R2RConfig rcfg;
81
94
82
- void setupPins () {
95
+ virtual void setupPins () {
83
96
TRACED ();
84
97
for (auto pin : rcfg.channel1_pins ) {
85
98
LOGI (" Setup channel1 pin %d" , pin);
@@ -116,9 +129,13 @@ class R2ROutput : public AudioOutput {
116
129
unsigned uvalue = (int )value + NumberConverter::maxValueT<T>() + 1 ;
117
130
// scale value
118
131
uvalue = uvalue >> ((sizeof (T) * 8 ) - rcfg.channel1_pins .size ());
119
- // Serial.println(uvalue);
132
+ // Serial.println(uvalue);
120
133
121
134
// output pins
135
+ writePins (channel, uvalue);
136
+ }
137
+
138
+ virtual void writePins (int channel, unsigned uvalue){
122
139
switch (channel) {
123
140
case 0 :
124
141
for (int j = 0 ; j < rcfg.channel1_pins .size (); j++) {
0 commit comments