3 #include "AudioConfig.h"
4 #include "AudioTools/CoreAudio/AudioTimer/AudioTimer.h"
5 #include "AudioTools/CoreAudio/AudioLogger.h"
6 #include "AudioTools/CoreAudio/AudioOutput.h"
7 #include "AudioTools/CoreAudio/Buffers.h"
8 #include "AudioTools/CoreAudio/AudioBasic/Collections/Vector.h"
23 virtual void writePins(
int channels,
int channel,
unsigned uvalue) = 0;
39 p_channel1_pins = &channel1_pins;
40 p_channel2_pins = &channel2_pins;
42 for (
auto pin : channel1_pins) {
43 LOGI(
"Setup channel1 pin %d", pin);
46 for (
int pin : channel2_pins) {
47 LOGI(
"Setup channel2 pin %d", pin);
52 void writePins(
int channels,
int channel,
unsigned uvalue)
override {
55 for (
int j = 0; j < (*p_channel1_pins).size(); j++) {
56 int pin = (*p_channel1_pins)[j];
57 if (pin >= 0) digitalWrite(pin, (uvalue >> j) & 1);
61 for (
int j = 0; j < (*p_channel2_pins).size(); j++) {
62 int pin = (*p_channel2_pins)[j];
63 if (pin >= 0) digitalWrite(pin, (uvalue >> j) & 1);
84 uint16_t buffer_size = DEFAULT_BUFFER_SIZE;
85 uint16_t buffer_count = 2;
87 bool is_blocking =
true;
88 int blocking_retry_delay_ms = 5;
119 bool begin()
override {
122 LOGE(
"channels is %d", cfg.
channels);
125 if (rcfg.channel1_pins.size() == 0) {
126 LOGE(
"channel1_pins not defined");
130 rcfg.channel2_pins.size() != rcfg.channel1_pins.size()) {
131 LOGE(
"channel2_pins not defined");
134 if (rcfg.buffer_size * rcfg.buffer_count == 0) {
135 LOGE(
"buffer_size or buffer_count is 0");
138 buffer.resize(rcfg.buffer_size, rcfg.buffer_count);
139 rcfg.driver->setupPins(rcfg.channel1_pins, rcfg.channel2_pins);
142 timer.setCallbackParameter(
this);
143 timer.setIsSave(
true);
144 timer.setTimer(rcfg.timer_id);
145 return timer.begin(r2r_timer_callback, cfg.
sample_rate, HZ);
148 size_t write(
const uint8_t *data,
size_t len)
override {
149 LOGD(
"write: %d", len);
152 if (len > rcfg.buffer_size) {
153 LOGE(
"buffer_size %d too small for write size: %d", rcfg.buffer_size,
158 if (rcfg.is_blocking){
162 int written = buffer.
writeArray(data + result, open);
166 delay(rcfg.blocking_retry_delay_ms);
174 if (!is_active && buffer.bufferCountFilled() >= rcfg.buffer_count / 2) {
175 LOGI(
"is_active = true");
188 void writeValue(
int channel) {
191 return writeValueT<int8_t>(channel);
193 return writeValueT<int16_t>(channel);
195 return writeValueT<int24_t>(channel);
197 return writeValueT<int32_t>(channel);
201 template <
typename T>
202 void writeValueT(
int channel) {
204 if (buffer.
available() <
sizeof(T))
return;
208 buffer.
readArray((uint8_t *)&value,
sizeof(T));
210 unsigned uvalue = (int)value + NumberConverter::maxValueT<T>() + 1;
212 uvalue = uvalue >> ((
sizeof(T) * 8) - rcfg.channel1_pins.size());
216 rcfg.driver->writePins(cfg.
channels, channel, uvalue);
219 static void r2r_timer_callback(
void *ptr) {
221 if (self->is_active) {
225 if (self->cfg.channels == 2)
self->writeValue(1);