arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
PWMAudioESP32.h
1
2#pragma once
3#ifdef ESP32
4#include "AudioTools/CoreAudio/AudioPWM/PWMAudioBase.h"
5
6namespace audio_tools {
7
8// forward declaration
9class PWMDriverESP32;
14using PWMDriver = PWMDriverESP32;
15
22 int pwm_channel;
23 int gpio;
24};
25
26typedef PinInfoESP32 PinInfo;
27
37 public:
38 // friend void pwm_callback(void*ptr);
39
40 PWMDriverESP32() { TRACED(); }
41
42 // Ends the output
43 virtual void end() {
44 TRACED();
45 timer.end();
46 is_timer_started = false;
47 for (int j = 0; j < audio_config.channels; j++) {
48#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0)
49 ledcDetach(pins[j].gpio);
50#else
51 ledcDetachPin(pins[j].gpio);
52#endif
53 }
54 deleteBuffer();
55 }
56
59 virtual void startTimer() {
60 if (!timer) {
61 TRACEI();
62 timer.begin(pwm_callback, effectiveOutputSampleRate(), HZ);
63 actual_timer_frequency = effectiveOutputSampleRate();
64 is_timer_started = true;
65 }
66 }
67
69 virtual void setupPWM() {
70 // frequency is driven by selected resolution
71 if (audio_config.pwm_frequency == 0){
72 audio_config.pwm_frequency = frequency(audio_config.resolution) * 1000;
73 }
74
75 pins.resize(audio_config.channels);
76 for (int j = 0; j < audio_config.channels; j++) {
77 pins[j].gpio = audio_config.pins()[j];
78#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0)
79 if (!ledcAttach(pins[j].gpio, audio_config.pwm_frequency,
80 audio_config.resolution)) {
81 LOGE("ledcAttach: %d", pins[j].gpio);
82 }
83#else
84 int pwmChannel = j;
85 pins[j].pwm_channel = pwmChannel;
86 ledcSetup(pins[j].pwm_channel, audio_config.pwm_frequency,
87 audio_config.resolution);
88 ledcAttachPin(pins[j].gpio, pins[j].pwm_channel);
89#endif
90 LOGI("setupPWM: pin=%d, channel=%d, frequency=%u, resolution=%d",
91 pins[j].gpio, pins[j].pwm_channel, (unsigned)audio_config.pwm_frequency,
92 audio_config.resolution);
93 }
94 logPins();
95 }
96
97 void logPins() {
98 for (int j = 0; j < pins.size(); j++) {
99 LOGI("pin%d: %d", j, pins[j].gpio);
100 }
101 }
102
104 virtual void setupTimer() {
105 timer.setCallbackParameter(this);
106 timer.setIsSave(false);
107
108 if (actual_timer_frequency != effectiveOutputSampleRate()){
109 timer.end();
110 startTimer();
111 }
112 }
113
116 virtual void pwmWrite(int channel, int value) {
117#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0)
118 ledcWrite(pins[channel].gpio, value);
119#else
120 ledcWrite(pins[channel].pwm_channel, value);
121#endif
122 }
123
124 protected:
125 Vector<PinInfo> pins;
127 uint32_t actual_timer_frequency = 0;
128
130 int maxUnsignedValue(int resolution) { return pow(2, resolution); }
131
132 virtual int maxChannels() { return 16; };
133
135 virtual int maxOutputValue() {
136 return maxUnsignedValue(audio_config.resolution);
137 }
138
140 float frequency(int resolution) {
141// On ESP32S2 and S3, the frequncy seems off by a factor of 2
142#if defined(ESP32S2) || defined(ESP32S3)
143 switch (resolution) {
144 case 7:
145 return 312.5;
146 case 8:
147 return 156.25;
148 case 9:
149 return 78.125;
150 case 10:
151 return 39.0625;
152 case 11:
153 return 19.53125;
154 }
155 return 312.5;
156#else
157 switch (resolution) {
158 case 8:
159 return 312.5;
160 case 9:
161 return 156.25;
162 case 10:
163 return 78.125;
164 case 11:
165 return 39.0625;
166 }
167 return 312.5;
168#endif
169 }
170
172 static void pwm_callback(void *ptr) {
173 PWMDriverESP32 *accessAudioPWM = (PWMDriverESP32 *)ptr;
174 if (accessAudioPWM != nullptr) {
175 accessAudioPWM->playNextFrame();
176 }
177 }
178};
179
180} // namespace audio_tools
181
182#endif
Base Class for all PWM drivers.
Definition PWMAudioBase.h:110
virtual int effectiveOutputSampleRate()
Provides the effective sample rate.
Definition PWMAudioBase.h:242
void playNextFrame()
writes the next frame to the output pins
Definition PWMAudioBase.h:270
Audio output to PWM pins for the ESP32. The ESP32 supports up to 16 channels.
Definition PWMAudioESP32.h:36
float frequency(int resolution)
determiens the PWM frequency based on the requested resolution
Definition PWMAudioESP32.h:140
virtual void setupPWM()
Setup LED PWM.
Definition PWMAudioESP32.h:69
virtual int maxOutputValue()
provides the max value for the configured resulution
Definition PWMAudioESP32.h:135
virtual void startTimer()
Definition PWMAudioESP32.h:59
int maxUnsignedValue(int resolution)
provides the max value for the indicated resulution
Definition PWMAudioESP32.h:130
virtual void pwmWrite(int channel, int value)
Definition PWMAudioESP32.h:116
static void pwm_callback(void *ptr)
timer callback: write the next frame to the pins
Definition PWMAudioESP32.h:172
virtual void setupTimer()
Setup ESP32 timer with callback.
Definition PWMAudioESP32.h:104
Common Interface definition for TimerAlarmRepeating.
Definition AudioTimer.h:25
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t resolution
Only used by ESP32: must be between 8 and 11 -> drives pwm frequency // 20,000Hz (not used by ESP32)
Definition PWMAudioBase.h:48
uint32_t pwm_frequency
additinal info which might not be used by all processors
Definition PWMAudioBase.h:46
Information for a PIN.
Definition PWMAudioESP32.h:21