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);
57 uint16_t start_pin = PIN_PWM_START;
60 template <
typename T,
int N>
61 void setPins(T (&a)[N]) {
64 for (
int i = 0; i < N; ++i) {
71 void setPins(
Pins &pins) {
73 for (
int i = 0; i < pins.size(); i++) {
74 pins_data.push_back(pins[i]);
80 if (pins_data.size() == 0) {
83 pins_data[j] = start_pin + j;
96 LOGI(
"buffer_count: %u",
buffers);
115 PWMConfig &audioInfo() {
return audio_config; }
126 decimation_factor = 0;
132 if (audio_config.
channels > maxChannels()) {
133 LOGE(
"Only max %d channels are supported!", maxChannels());
137 if (buffer ==
nullptr) {
138 LOGI(
"->Allocating new buffer %d * %d bytes", audio_config.
buffers,
147 if (!isTimerStarted() || !cfg.
equals(actual_info)) {
148 audio_config.logConfig();
156 underflow_per_second = 0;
158 frames_per_second = 0;
160 LOGI(
"->Buffer available: %d", buffer->
available());
162 LOGI(
"->is_timer_started: %s ", isTimerStarted() ?
"true" :
"false");
166 virtual int availableForWrite() {
171 return buffer->size() / frame_size * frame_size;
176 virtual size_t write(
const uint8_t *data,
size_t len) {
180 size = (size / frame_size) * frame_size;
181 LOGD(
"adjusted size: %d", (
int)size);
184 size = decimate.convert((uint8_t *)data, size);
185 LOGD(
"decimated size: %d", (
int)size);
189 LOGD(
"Waiting for buffer to be available");
192 size = min((
size_t)availableForWrite(), size);
195 size_t result = buffer->
writeArray(data, size);
196 if (result != size) {
197 LOGW(
"Could not write all data: %u -> %d", (
unsigned)size, result);
200 if (!is_timer_started) startTimer();
211 uint32_t underflowsPerSecond() {
return underflow_per_second; }
213 uint32_t framesPerSecond() {
return frames_per_second; }
215 inline void updateStatistics() {
217 if (
millis() >= time_1_sec) {
218 time_1_sec =
millis() + 1000;
219 frames_per_second = frame_count;
220 underflow_per_second = underflow_count;
226 bool isTimerStarted() {
return is_timer_started; }
228 virtual void setupPWM() = 0;
229 virtual void setupTimer() = 0;
230 virtual void startTimer() = 0;
231 virtual int maxChannels() = 0;
232 virtual int maxOutputValue() = 0;
233 virtual void end() {};
235 virtual void pwmWrite(
int channel,
int value) = 0;
250 uint32_t underflow_count = 0;
251 uint32_t underflow_per_second = 0;
252 uint32_t frame_count = 0;
253 uint32_t frames_per_second = 0;
254 uint32_t frame_size = 0;
256 bool is_timer_started =
false;
257 bool is_blocking_write =
true;
259 int decimation_factor = 0;
261 void deleteBuffer() {
263 if (buffer !=
nullptr) {
271 if (isTimerStarted() && buffer !=
nullptr) {
275 for (
int j = 0; j < audio_config.
channels; j++) {
292 if (buffer->
readArray((uint8_t *)&value, 1) != 1) {
293 LOGE(READ_ERROR_MSG);
301 if (buffer->
readArray((uint8_t *)&value, 2) != 2) {
302 LOGE(READ_ERROR_MSG);
310 if (buffer->
readArray((uint8_t *)&value, 3) != 3) {
311 LOGE(READ_ERROR_MSG);
319 if (buffer->
readArray((uint8_t *)&value, 4) != 4) {
320 LOGE(READ_ERROR_MSG);
341 if (decimation_factor == 0){
342 for (
int j = 1; j < 20; j++){
344 decimation_factor = j;
345 LOGI(
"Decimation factor: %d" ,j);
349 decimation_factor = 1;
350 LOGI(
"Decimation factor: %d", (
int)decimation_factor);
353 return decimation_factor;
Vector< int > Pins
Pins.
Definition AudioTypes.h:524