arduino-audio-tools
Loading...
Searching...
No Matches
PWMDriverBase.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
4#ifdef USE_PWM
5
11#include "PWMConfig.h"
12#define READ_ERROR_MSG "Could not read full data"
13
14#ifndef PIN_PWM_START
15# define PIN_PWM_START 0
16#endif
17
18namespace audio_tools {
19
20// forward declarations
21// Callback for user
22typedef bool (*PWMCallbackType)(uint8_t channels, int16_t *data);
23// Callback used by system
25// Driver classes
26class PWMDriverESP32;
27class PWMDriverRP2040;
28class PWMDriverMBED;
29class PWMDriverSTM32;
30
31
37 public:
38 PWMDriverBase() = default;
39 virtual ~PWMDriverBase() { end(); }
40
42
44 PWMConfig cfg;
45 return cfg;
46 }
47
48 // restart with prior definitions
49 bool begin(PWMConfig cfg) {
50 TRACEI();
51
53 audio_config = cfg;
59 LOGE("Only max %d channels are supported!", maxChannels());
60 return false;
61 }
62
63 if (buffer == nullptr) {
64 LOGI("->Allocating new buffer %d * %d bytes", audio_config.buffers,
66 // buffer = new NBuffer<uint8_t>(audio_config.buffer_size,
67 // audio_config.buffers);
70 }
71
72 // initialize if necessary
73 if (!isTimerStarted() || !cfg.equals(actual_info)) {
75 actual_info = cfg;
76 setupPWM();
77 setupTimer();
78 }
79
80 // reset class variables
83 frame_count = 0;
85
86 LOGI("->Buffer available: %d", buffer->available());
87 LOGI("->Buffer available for write: %d", buffer->availableForWrite());
88 LOGI("->is_timer_started: %s ", isTimerStarted() ? "true" : "false");
89 return true;
90 }
91
92 virtual int availableForWrite() {
93 // return is_blocking_write
94 // ? audio_config.buffer_size
95 // : buffer->availableForWrite() / frame_size * frame_size;
96 // we must not write anything bigger then the buffer size
97 return buffer->size() / frame_size * frame_size;
98 }
99
100 // blocking write for an array: we expect a singed value and convert it into a
101 // unsigned
102 virtual size_t write(const uint8_t *data, size_t len) {
103 size_t size = len;
104
105 // only allow full frame
106 size = (size / frame_size) * frame_size;
107 LOGD("adjusted size: %d", (int)size);
108
109 if (isDecimateActive()) {
110 size = decimate.convert((uint8_t *)data, size);
111 LOGD("decimated size: %d", (int)size);
112 }
113
114 if (is_blocking_write && buffer->availableForWrite() < size) {
115 LOGD("Waiting for buffer to be available");
116 while (buffer->availableForWrite() < size) delay(5);
117 } else {
118 size = min((size_t)availableForWrite(), size);
119 }
120
121 size_t result = buffer->writeArray(data, size);
122 if (result != size) {
123 LOGW("Could not write all data: %u -> %d", (unsigned)size, result);
124 }
125 // activate the timer now - if not already done
127
128 // adjust the result by the descimation
129 if (isDecimateActive()) {
130 result = result * decimation();
131 }
132 //LOGD("write %u -> %u", len, result);
133 return result;
134 }
135
136 // When the timer does not have enough data we increase the underflow_count;
138 // provides the effectivly measured output frames per second
140
141 inline void updateStatistics() {
142 frame_count++;
143 if (millis() >= time_1_sec) {
144 time_1_sec = millis() + 1000;
147 underflow_count = 0;
148 frame_count = 0;
149 }
150 }
151
153
154 virtual void setupPWM() = 0;
155 virtual void setupTimer() = 0;
156 virtual void startTimer() = 0;
157 virtual int maxChannels() = 0;
158 virtual int maxOutputValue() = 0;
159 virtual void end() {};
160
161 virtual void pwmWrite(int channel, int value) = 0;
162
165 void setBuffer(BaseBuffer<uint8_t> *buffer) { this->buffer = buffer; }
166
170 }
171
172 protected:
182 bool is_timer_started = false;
183 bool is_blocking_write = true;
186
188 // delete buffer if necessary
189 if (buffer != nullptr) {
190 delete buffer;
191 buffer = nullptr;
192 }
193 }
194
197 if (isTimerStarted() && buffer != nullptr) {
198 // TRACED();
200 if (buffer->available() >= required) {
201 for (int j = 0; j < audio_config.channels; j++) {
202 int value = nextValue();
203 pwmWrite(j, value);
204 }
205 } else {
207 }
209 }
210 }
211
213 virtual int nextValue() {
214 int result = 0;
216 case 8: {
217 int8_t value;
218 if (buffer->readArray((uint8_t *)&value, 1) != 1) {
220 }
221 result = map(value, -NumberConverter::maxValue(8),
223 break;
224 }
225 case 16: {
226 int16_t value;
227 if (buffer->readArray((uint8_t *)&value, 2) != 2) {
229 }
230 result = map(value, -NumberConverter::maxValue(16),
232 break;
233 }
234 case 24: {
235 int24_t value;
236 if (buffer->readArray((uint8_t *)&value, 3) != 3) {
238 }
239 result = map((int32_t)value, -NumberConverter::maxValue(24),
241 break;
242 }
243 case 32: {
244 int32_t value;
245 if (buffer->readArray((uint8_t *)&value, 4) != 4) {
247 }
248 result = map(value, -NumberConverter::maxValue(32),
250 break;
251 }
252 }
253 return result;
254 }
255
258
264
266 virtual int decimation() {
267 if (decimation_factor == 0){
268 for (int j = 1; j < 20; j++){
271 LOGI("Decimation factor: %d" ,j);
272 return j;
273 }
274 }
276 LOGI("Decimation factor: %d", (int)decimation_factor);
277 }
278
279 return decimation_factor;
280 }
281};
282
283} // namespace audio_tool
284
285#endif
long map(long x, long in_min, long in_max, long out_min, long out_max)
Maps input to output values.
Definition Arduino.h:182
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define READ_ERROR_MSG
Definition PWMDriverBase.h:12
Shared functionality of all buffers.
Definition Buffers.h:23
virtual int readArray(T data[], int len)
reads multiple values
Definition Buffers.h:34
virtual int writeArray(const T data[], int len)
Fills the buffer data.
Definition Buffers.h:56
virtual size_t size()=0
virtual int availableForWrite()=0
provides the number of entries that are available to write
virtual int available()=0
provides the number of entries that are available to read
Provides a reduced sampling rate by taking a sample at every factor location (ingoring factor-1 sampl...
Definition BaseConverter.h:614
void setFactor(int factor)
Sets the factor: e.g. with 4 we keep every forth sample.
Definition BaseConverter.h:632
size_t convert(uint8_t *src, size_t size)
Definition BaseConverter.h:644
void setChannels(int channels)
Defines the number of channels.
Definition BaseConverter.h:623
void setBits(int bits)
Definition BaseConverter.h:627
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:297
Base Class for all PWM drivers.
Definition PWMDriverBase.h:36
uint32_t frame_size
Definition PWMDriverBase.h:180
virtual void pwmWrite(int channel, int value)=0
uint32_t framesPerSecond()
Definition PWMDriverBase.h:139
virtual int effectiveOutputSampleRate()
Provides the effective sample rate.
Definition PWMDriverBase.h:168
uint32_t underflow_per_second
Definition PWMDriverBase.h:177
int decimation_factor
Definition PWMDriverBase.h:185
void playNextFrame()
writes the next frame to the output pins
Definition PWMDriverBase.h:196
uint32_t underflowsPerSecond()
Definition PWMDriverBase.h:137
uint32_t frames_per_second
Definition PWMDriverBase.h:179
virtual int availableForWrite()
Definition PWMDriverBase.h:92
void setBuffer(BaseBuffer< uint8_t > *buffer)
Definition PWMDriverBase.h:165
bool is_timer_started
Definition PWMDriverBase.h:182
virtual PWMConfig defaultConfig()
Definition PWMDriverBase.h:43
uint32_t underflow_count
Definition PWMDriverBase.h:176
virtual int maxSampleRate()
Provides the max working sample rate.
Definition PWMDriverBase.h:257
virtual int maxChannels()=0
virtual void startTimer()=0
BaseBuffer< uint8_t > * buffer
Definition PWMDriverBase.h:175
bool isTimerStarted()
Definition PWMDriverBase.h:152
virtual int nextValue()
determines the next scaled value
Definition PWMDriverBase.h:213
virtual size_t write(const uint8_t *data, size_t len)
Definition PWMDriverBase.h:102
bool begin(PWMConfig cfg)
Definition PWMDriverBase.h:49
PWMConfig & audioInfo()
Definition PWMDriverBase.h:41
virtual void setupTimer()=0
bool is_blocking_write
Definition PWMDriverBase.h:183
PWMConfig audio_config
Definition PWMDriverBase.h:173
virtual ~PWMDriverBase()
Definition PWMDriverBase.h:39
virtual int decimation()
Decimation factor to reduce the sample rate.
Definition PWMDriverBase.h:266
virtual bool isDecimateActive()
Definition PWMDriverBase.h:261
virtual void setupPWM()=0
void deleteBuffer()
Definition PWMDriverBase.h:187
void updateStatistics()
Definition PWMDriverBase.h:141
virtual void end()
Definition PWMDriverBase.h:159
uint32_t time_1_sec
Definition PWMDriverBase.h:181
uint32_t frame_count
Definition PWMDriverBase.h:178
AudioInfo actual_info
Definition PWMDriverBase.h:174
virtual int maxOutputValue()=0
Decimate decimate
Definition PWMDriverBase.h:184
Audio output to PWM pins for the ESP32. The ESP32 supports up to 16 channels.
Definition PWMDriverESP32.h:55
Audio output to PWM pins for MBED based Arduino implementations.
Definition PWMDriverMBED.h:26
Audio output to PWM pins for STM32. We use one timer to generate the sample rate and one timer for th...
Definition PWMDriverSTM32.h:25
Implements a typed Ringbuffer.
Definition Buffers.h:353
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition Int24_4bytes_t.h:22
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
bool(* PWMCallbackType)(uint8_t channels, int16_t *data)
Definition PWMDriverBase.h:22
void defaultPWMAudioOutputCallback()
Definition PWMDriverAVR.h:134
void delay(uint32_t ms)
Definition Arduino.h:255
uint32_t millis()
Returns the milliseconds since the start.
Definition Arduino.h:256
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:508
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
bool equals(AudioInfo alt)
Returns true if alt values are the same like the current values.
Definition AudioTypes.h:83
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
Configuration data for PWM audio output.
Definition PWMConfigAVR.h:10
void logConfig()
Definition PWMConfigAVR.h:37
uint32_t max_sample_rate
max sample sample rate that still produces good audio
Definition PWMConfigAVR.h:34
uint16_t buffer_size
size of an inidividual buffer
Definition PWMConfigAVR.h:19
uint8_t buffers
number of buffers
Definition PWMConfigAVR.h:21