3 #include "AudioConfig.h"
6 #include "AudioBasic/Collections.h"
8 #include "AudioTools/AudioLogger.h"
9 #include "AudioTools/AudioOutput.h"
10 #include "AudioTools/AudioTypes.h"
12 #define READ_ERROR_MSG "Could not read full data"
18 typedef bool (*PWMCallbackType)(uint8_t channels, int16_t *data);
23 class PWMDriverRP2040;
41 uint16_t buffer_size = PWM_BUFFER_SIZE;
42 uint8_t buffers = PWM_BUFFER_COUNT;
45 uint32_t pwm_frequency = PWM_AUDIO_FREQUENCY;
47 uint8_t resolution = 8;
52 uint16_t start_pin = PIN_PWM_START;
55 template <
typename T,
int N>
56 void setPins(T (&a)[N]) {
59 for (
int i = 0; i < N; ++i) {
66 void setPins(
Pins &pins) {
68 for (
int i = 0; i < pins.size(); i++) {
69 pins_data.push_back(pins[i]);
75 if (pins_data.size() == 0) {
78 pins_data[j] = start_pin + j;
90 LOGI(
"buffer_size: %u", buffer_size);
91 LOGI(
"buffer_count: %u", buffers);
92 LOGI(
"pwm_frequency: %u", (
unsigned)pwm_frequency);
93 LOGI(
"resolution: %d", resolution);
110 PWMConfig &audioInfo() {
return audio_config; }
126 if (audio_config.
channels > maxChannels()) {
127 LOGE(
"Only max %d channels are supported!", maxChannels());
131 if (buffer ==
nullptr) {
132 LOGI(
"->Allocating new buffer %d * %d bytes", audio_config.buffers,
133 audio_config.buffer_size);
137 audio_config.buffers);
141 if (!isTimerStarted()) {
142 audio_config.logConfig();
149 underflow_per_second = 0;
151 frames_per_second = 0;
153 LOGI(
"->Buffer available: %d", buffer->
available());
155 LOGI(
"->is_timer_started: %s ", isTimerStarted() ?
"true" :
"false");
159 virtual int availableForWrite() {
160 return is_blocking_write
161 ? audio_config.buffer_size
167 virtual size_t write(
const uint8_t *wrt_buffer,
size_t bytes) {
171 size = (size / frame_size) * frame_size;
172 LOGD(
"adjusted size: %d", (
int)size);
175 size = decimate.convert((uint8_t *)wrt_buffer, size);
176 LOGD(
"decimated size: %d", (
int)size);
180 LOGD(
"Waiting for buffer to be available");
183 size = min((
size_t)availableForWrite(), size);
186 size_t result = buffer->
writeArray(wrt_buffer, size);
187 if (result != size) {
188 LOGW(
"Could not write all data: %u -> %d", (
unsigned int)size, result);
196 uint32_t underflowsPerSecond() {
return underflow_per_second; }
198 uint32_t framesPerSecond() {
return frames_per_second; }
200 inline void updateStatistics() {
202 if (
millis() >= time_1_sec) {
203 time_1_sec =
millis() + 1000;
204 frames_per_second = frame_count;
205 underflow_per_second = underflow_count;
211 bool isTimerStarted() {
return is_timer_started; }
213 virtual void setupPWM() = 0;
214 virtual void setupTimer() = 0;
215 virtual void startTimer() = 0;
216 virtual int maxChannels() = 0;
217 virtual int maxOutputValue() = 0;
218 virtual void end() {};
220 virtual void pwmWrite(
int channel,
int value) = 0;
229 uint32_t underflow_count = 0;
230 uint32_t underflow_per_second = 0;
231 uint32_t frame_count = 0;
232 uint32_t frames_per_second = 0;
233 uint32_t frame_size = 0;
235 bool is_timer_started =
false;
236 bool is_blocking_write =
true;
239 void deleteBuffer() {
241 if (buffer !=
nullptr) {
249 if (isTimerStarted() && buffer !=
nullptr) {
253 for (
int j = 0; j < audio_config.
channels; j++) {
269 int16_t value = buffer->
read();
271 LOGE(READ_ERROR_MSG);
280 if (buffer->
readArray((uint8_t *)&value, 2) != 2) {
281 LOGE(READ_ERROR_MSG);
289 if (buffer->
readArray((uint8_t *)&value, 3) != 3) {
290 LOGE(READ_ERROR_MSG);
298 if (buffer->
readArray((uint8_t *)&value, 4) != 4) {
299 LOGE(READ_ERROR_MSG);
315 return audio_config.
sample_rate >= ANALOG_MAX_SAMPLE_RATE;