Skip to content

Commit 560e457

Browse files
committed
VolumeControl add max parameter to constructor
1 parent f275b82 commit 560e457

File tree

1 file changed

+118
-19
lines changed

1 file changed

+118
-19
lines changed

src/A2DPVolumeControl.h

Lines changed: 118 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,27 @@
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

4554
class 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
*/
105146
class 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
*/
126188
class 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
*/
143225
class 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
*/
156245
class 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

Comments
 (0)