3#include "AudioToolsConfig.h"
6#include "AudioTools/CoreAudio/AudioBasic/Collections.h"
8#include "AudioTools/CoreAudio/AudioLogger.h"
9#include "AudioTools/CoreAudio/AudioOutput.h"
10#include "AudioTools/CoreAudio/AudioTypes.h"
12#define READ_ERROR_MSG "Could not read full data"
18typedef bool (*PWMCallbackType)(uint8_t channels, int16_t *data);
60 uint16_t start_pin = PIN_PWM_START;
63 template <
typename T,
int N>
64 void setPins(T (&a)[N]) {
67 for (
int i = 0; i < N; ++i) {
74 void setPins(
Pins &pins) {
76 for (
int i = 0; i < pins.size(); i++) {
77 pins_data.push_back(pins[i]);
83 if (pins_data.size() == 0) {
86 pins_data[j] = start_pin + j;
99 LOGI(
"buffer_count: %u",
buffers);
119 PWMConfig &audioInfo() {
return audio_config; }
130 decimation_factor = 0;
136 if (audio_config.
channels > maxChannels()) {
137 LOGE(
"Only max %d channels are supported!", maxChannels());
141 if (buffer ==
nullptr) {
142 LOGI(
"->Allocating new buffer %d * %d bytes", audio_config.
buffers,
151 if (!isTimerStarted() || !cfg.
equals(actual_info)) {
152 audio_config.logConfig();
160 underflow_per_second = 0;
162 frames_per_second = 0;
164 LOGI(
"->Buffer available: %d", buffer->
available());
166 LOGI(
"->is_timer_started: %s ", isTimerStarted() ?
"true" :
"false");
170 virtual int availableForWrite() {
175 return buffer->size() / frame_size * frame_size;
180 virtual size_t write(
const uint8_t *data,
size_t len) {
184 size = (size / frame_size) * frame_size;
185 LOGD(
"adjusted size: %d", (
int)size);
188 size = decimate.convert((uint8_t *)data, size);
189 LOGD(
"decimated size: %d", (
int)size);
193 LOGD(
"Waiting for buffer to be available");
196 size = min((
size_t)availableForWrite(), size);
199 size_t result = buffer->
writeArray(data, size);
200 if (result != size) {
201 LOGW(
"Could not write all data: %u -> %d", (
unsigned)size, result);
204 if (!is_timer_started) startTimer();
215 uint32_t underflowsPerSecond() {
return underflow_per_second; }
217 uint32_t framesPerSecond() {
return frames_per_second; }
219 inline void updateStatistics() {
221 if (
millis() >= time_1_sec) {
222 time_1_sec =
millis() + 1000;
223 frames_per_second = frame_count;
224 underflow_per_second = underflow_count;
230 bool isTimerStarted() {
return is_timer_started; }
232 virtual void setupPWM() = 0;
233 virtual void setupTimer() = 0;
234 virtual void startTimer() = 0;
235 virtual int maxChannels() = 0;
236 virtual int maxOutputValue() = 0;
237 virtual void end() {};
239 virtual void pwmWrite(
int channel,
int value) = 0;
254 uint32_t underflow_count = 0;
255 uint32_t underflow_per_second = 0;
256 uint32_t frame_count = 0;
257 uint32_t frames_per_second = 0;
258 uint32_t frame_size = 0;
260 bool is_timer_started =
false;
261 bool is_blocking_write =
true;
263 int decimation_factor = 0;
265 void deleteBuffer() {
267 if (buffer !=
nullptr) {
275 if (isTimerStarted() && buffer !=
nullptr) {
279 for (
int j = 0; j < audio_config.
channels; j++) {
296 if (buffer->
readArray((uint8_t *)&value, 1) != 1) {
297 LOGE(READ_ERROR_MSG);
305 if (buffer->
readArray((uint8_t *)&value, 2) != 2) {
306 LOGE(READ_ERROR_MSG);
314 if (buffer->
readArray((uint8_t *)&value, 3) != 3) {
315 LOGE(READ_ERROR_MSG);
323 if (buffer->
readArray((uint8_t *)&value, 4) != 4) {
324 LOGE(READ_ERROR_MSG);
345 if (decimation_factor == 0){
346 for (
int j = 1; j < 20; j++){
348 decimation_factor = j;
349 LOGI(
"Decimation factor: %d" ,j);
353 decimation_factor = 1;
354 LOGI(
"Decimation factor: %d", (
int)decimation_factor);
357 return decimation_factor;
Vector< int > Pins
Pins.
Definition AudioTypes.h:524