1717
1818#include " esp_log.h"
1919
20- /* *
21- * @brief Utility structure that can be used to split a int32_t up into 2
22- * separate channels with int16_t data.
23- * @author Phil Schatzmann
24- * @copyright Apache License Version 2
25- */
26- struct __attribute__ ((packed)) Frame {
27- int16_t channel1;
28- int16_t channel2;
20+ /* *
21+ * @brief Utility structure that can be used to split a int32_t up into 2
22+ * separate channels with int16_t data.
23+ * @author Phil Schatzmann
24+ * @copyright Apache License Version 2
25+ */
26+ struct __attribute__ ((packed)) Frame {
27+ int16_t channel1; // /< Left audio channel data
28+ int16_t channel2; // /< Right audio channel data
2929
30+ /* *
31+ * @brief Default constructor - sets both channels to the same value
32+ * @param v Value to set for both channels (default: 0)
33+ */
3034 Frame (int v = 0 ) { channel1 = channel2 = v; }
3135
36+ /* *
37+ * @brief Constructor with separate channel values
38+ * @param ch1 Value for channel 1 (left)
39+ * @param ch2 Value for channel 2 (right)
40+ */
3241 Frame (int ch1, int ch2) {
3342 channel1 = ch1;
3443 channel2 = ch2;
@@ -44,12 +53,25 @@ struct __attribute__((packed)) Frame {
4453
4554class A2DPVolumeControl {
4655 public:
47- A2DPVolumeControl () { volumeFactorMax = 0x1000 ; }
56+ /* *
57+ * @brief Default constructor
58+ */
59+ A2DPVolumeControl () = default ;
4860
61+ /* *
62+ * @brief Updates audio data with volume control and optional mono downmix
63+ * @param data Pointer to raw audio data (uint8_t)
64+ * @param byteCount Number of bytes to process
65+ */
4966 virtual void update_audio_data (uint8_t * data, uint16_t byteCount) {
5067 update_audio_data ((Frame*)data, byteCount / 4 );
5168 }
5269
70+ /* *
71+ * @brief Updates audio data with volume control and optional mono downmix
72+ * @param data Pointer to audio frame data
73+ * @param frameCount Number of frames to process
74+ */
5375 virtual void update_audio_data (Frame* data, uint16_t frameCount) {
5476 if (data != nullptr && frameCount > 0 && (mono_downmix || is_volume_used)) {
5577 ESP_LOGD (" VolumeControl" , " update_audio_data" );
@@ -71,23 +93,42 @@ class A2DPVolumeControl {
7193 }
7294 }
7395
74- // provides a factor in the range of 0 to 4096
96+ /* *
97+ * @brief Gets the current volume factor
98+ * @return Volume factor in the range of 0 to 4096
99+ */
75100 int32_t get_volume_factor () { return volumeFactor; }
76101
77- // provides the max factor value 4096
102+ /* *
103+ * @brief Gets the maximum volume factor value
104+ * @return Maximum factor value (4096)
105+ */
78106 int32_t get_volume_factor_max () { return volumeFactorMax; }
79107
108+ /* *
109+ * @brief Enables or disables volume control
110+ * @param enabled True to enable volume control, false to disable
111+ */
80112 void set_enabled (bool enabled) { is_volume_used = enabled; }
81113
114+ /* *
115+ * @brief Enables or disables mono downmix
116+ * @param enabled True to enable mono downmix, false to disable
117+ */
82118 void set_mono_downmix (bool enabled) { mono_downmix = enabled; }
83119
120+ /* *
121+ * @brief Sets the volume level (pure virtual function)
122+ * @param volume Volume level (0-127)
123+ */
84124 virtual void set_volume (uint8_t volume) = 0;
85125
86126 protected:
87127 bool is_volume_used = false ;
88128 bool mono_downmix = false ;
89- int32_t volumeFactor;
90- int32_t volumeFactorMax;
129+ int32_t volumeFactor = 1 ;
130+ int32_t volumeFactorMax = 0x1000 ; // 4096
131+ int32_t volumeFactorClippingLimit = 0xfff ; // 4095
91132
92133 int32_t clip (int32_t value) {
93134 int32_t result = value;
@@ -103,7 +144,27 @@ class A2DPVolumeControl {
103144 * @copyright Apache License Version 2
104145 */
105146class A2DPDefaultVolumeControl : public A2DPVolumeControl {
147+ public:
148+ /* *
149+ * @brief Default constructor
150+ */
151+ A2DPDefaultVolumeControl () = default ;
152+
153+ /* *
154+ * @brief Constructor with custom volume factor clipping limit
155+ * @param limit Maximum volume factor limit (must be less than
156+ * 4096)
157+ */
158+ A2DPDefaultVolumeControl (int32_t limit) {
159+ assert (limit < volumeFactorMax);
160+ volumeFactorClippingLimit = limit;
161+ };
162+
106163 protected:
164+ /* *
165+ * @brief Sets the volume using exponential curve calculation
166+ * @param volume Volume level (0-127)
167+ */
107168 void set_volume (uint8_t volume) override {
108169 constexpr float base = 1 .4f ;
109170 constexpr float bits = 12 .0f ;
@@ -113,24 +174,45 @@ class A2DPDefaultVolumeControl : public A2DPVolumeControl {
113174 (pow (base, volume * bits / 127 .0f - bits) - zero_ofs) * scale /
114175 (1 .0f - zero_ofs);
115176 volumeFactor = volumeFactorFloat;
116- if (volumeFactor > 0xfff ) {
117- volumeFactor = 0xfff ;
177+ if (volumeFactor > volumeFactorClippingLimit ) {
178+ volumeFactor = volumeFactorClippingLimit ;
118179 }
119180 }
120181};
121182
122183/* *
123- * @brief Exponentional volume control
184+ * @brief Exponential volume control
124185 * @author rbruelma
186+ * @copyright Apache License Version 2
125187 */
126188class A2DPSimpleExponentialVolumeControl : public A2DPVolumeControl {
189+ public:
190+ /* *
191+ * @brief Default constructor
192+ */
193+ A2DPSimpleExponentialVolumeControl () = default ;
194+
195+ /* *
196+ * @brief Constructor with custom volume factor clipping limit
197+ * @param limit Maximum volume factor limit (must be less than
198+ * 4096)
199+ */
200+ A2DPSimpleExponentialVolumeControl (int32_t limit) {
201+ assert (limit < volumeFactorMax);
202+ volumeFactorClippingLimit = limit;
203+ };
204+
127205 protected:
206+ /* *
207+ * @brief Sets the volume using simple exponential calculation
208+ * @param volume Volume level (0-127)
209+ */
128210 void set_volume (uint8_t volume) override {
129211 float volumeFactorFloat = volume;
130212 volumeFactorFloat = pow (2 .0f , volumeFactorFloat * 12 .0f / 127 .0f );
131213 volumeFactor = volumeFactorFloat - 1 .0f ;
132- if (volumeFactor > 0xfff ) {
133- volumeFactor = 0xfff ;
214+ if (volumeFactor > volumeFactorClippingLimit ) {
215+ volumeFactor = volumeFactorClippingLimit ;
134216 }
135217 }
136218};
@@ -142,9 +224,16 @@ class A2DPSimpleExponentialVolumeControl : public A2DPVolumeControl {
142224 */
143225class A2DPLinearVolumeControl : public A2DPVolumeControl {
144226 public:
227+ /* *
228+ * @brief Constructor that sets volumeFactorMax to 128 for linear scaling
229+ */
145230 A2DPLinearVolumeControl () { volumeFactorMax = 128 ; }
146231
147232 protected:
233+ /* *
234+ * @brief Sets the volume using direct linear mapping
235+ * @param volume Volume level (0-127) - directly used as volume factor
236+ */
148237 void set_volume (uint8_t volume) override { volumeFactor = volume; }
149238};
150239
@@ -155,6 +244,16 @@ class A2DPLinearVolumeControl : public A2DPVolumeControl {
155244 */
156245class A2DPNoVolumeControl : public A2DPVolumeControl {
157246 public:
247+ /* *
248+ * @brief Override that does nothing - no audio data modification
249+ * @param data Pointer to audio frame data (unused)
250+ * @param frameCount Number of frames (unused)
251+ */
158252 void update_audio_data (Frame* data, uint16_t frameCount) override {}
253+
254+ /* *
255+ * @brief Override that does nothing - no volume setting
256+ * @param volume Volume level (unused)
257+ */
159258 void set_volume (uint8_t volume) override {}
160259};
0 commit comments