Arduino A2DP
Loading...
Searching...
No Matches
A2DPVolumeControl.h
1#pragma once
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Copyright 2020 Phil Schatzmann
16// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
17
18#include "esp_log.h"
19
26 struct __attribute__((packed)) Frame {
27 int16_t channel1;
28 int16_t channel2;
29
34 Frame(int v = 0) { channel1 = channel2 = v; }
35
41 Frame(int ch1, int ch2) {
42 channel1 = ch1;
43 channel2 = ch2;
44 }
45};
46
55 public:
59 A2DPVolumeControl() = default;
60
66 virtual void update_audio_data(uint8_t* data, uint16_t byteCount) {
67 update_audio_data((Frame*)data, byteCount / 4);
68 }
69
75 virtual void update_audio_data(Frame* data, uint16_t frameCount) {
76 if (data != nullptr && frameCount > 0 && (mono_downmix || is_volume_used)) {
77 ESP_LOGD("VolumeControl", "update_audio_data");
78 for (int i = 0; i < frameCount; i++) {
79 int32_t pcmLeft = data[i].channel1;
80 int32_t pcmRight = data[i].channel2;
81 // if mono -> we provide the same output on both channels
82 if (mono_downmix) {
83 pcmRight = pcmLeft = (pcmLeft + pcmRight) / 2;
84 }
85 // adjust the volume
86 if (is_volume_used) {
87 pcmLeft = clip(pcmLeft * volumeFactor / volumeFactorMax);
88 pcmRight = clip(pcmRight * volumeFactor / volumeFactorMax);
89 }
90 data[i].channel1 = pcmLeft;
91 data[i].channel2 = pcmRight;
92 }
93 }
94 }
95
100 int32_t get_volume_factor() { return volumeFactor; }
101
107
112 void set_enabled(bool enabled) { is_volume_used = enabled; }
113
118 void set_mono_downmix(bool enabled) { mono_downmix = enabled; }
119
124 virtual void set_volume(uint8_t volume) = 0;
125
126 protected:
127 bool is_volume_used = false;
128 bool mono_downmix = false;
129 int32_t volumeFactor = 1;
130 int32_t volumeFactorMax = 0x1000;
132
138 int32_t clip(int32_t value) {
139 int32_t result = value;
140 if (value < -32768) result = -32768;
141 if (value > 32767) result = 32767;
142 return result;
143 }
144};
145
152 public:
157
164 assert(limit < volumeFactorMax);
166 };
167
168 protected:
173 void set_volume(uint8_t volume) override {
174 constexpr float base = 1.4f;
175 constexpr float bits = 12.0f;
176 constexpr float zero_ofs = pow(base, -bits);
177 constexpr float scale = pow(2.0f, bits);
178 float volumeFactorFloat =
179 (pow(base, volume * bits / 127.0f - bits) - zero_ofs) * scale /
180 (1.0f - zero_ofs);
181 volumeFactor = volumeFactorFloat;
184 }
185 }
186};
187
194 public:
199
206 assert(limit < volumeFactorMax);
208 };
209
210 protected:
215 void set_volume(uint8_t volume) override {
216 float volumeFactorFloat = volume;
217 volumeFactorFloat = pow(2.0f, volumeFactorFloat * 12.0f / 127.0f);
218 volumeFactor = volumeFactorFloat - 1.0f;
221 }
222 }
223};
224
231 public:
236
237 protected:
242 void set_volume(uint8_t volume) override { volumeFactor = volume; }
243};
244
251 public:
257 A2DPNoVolumeControl(int32_t fixedVolume = 0x1000) {
258 is_volume_used = fixedVolume != 0x1000;
259 mono_downmix = false;
260 volumeFactor = fixedVolume; // fixed volume
261 volumeFactorMax = 0x1000; // no change
262 }
263
269 void update_audio_data(Frame* data, uint16_t frameCount) override {}
270
275 void set_volume(uint8_t volume) override {}
276};
Default implementation for handling of the volume of the audio data.
Definition A2DPVolumeControl.h:151
A2DPDefaultVolumeControl(int32_t limit)
Constructor with custom volume factor clipping limit.
Definition A2DPVolumeControl.h:163
void set_volume(uint8_t volume) override
Sets the volume using exponential curve calculation.
Definition A2DPVolumeControl.h:173
A2DPDefaultVolumeControl()=default
Default constructor.
The simplest possible implementation of a VolumeControl.
Definition A2DPVolumeControl.h:230
A2DPLinearVolumeControl()
Constructor that sets volumeFactorMax to 128 for linear scaling.
Definition A2DPVolumeControl.h:235
void set_volume(uint8_t volume) override
Sets the volume using direct linear mapping.
Definition A2DPVolumeControl.h:242
Keeps the audio data as is -> no volume control!
Definition A2DPVolumeControl.h:250
void set_volume(uint8_t volume) override
Override that does nothing - no volume setting.
Definition A2DPVolumeControl.h:275
A2DPNoVolumeControl(int32_t fixedVolume=0x1000)
Constructor with optional fixed volume setting.
Definition A2DPVolumeControl.h:257
void update_audio_data(Frame *data, uint16_t frameCount) override
Override that does nothing - no audio data modification.
Definition A2DPVolumeControl.h:269
Exponential volume control.
Definition A2DPVolumeControl.h:193
void set_volume(uint8_t volume) override
Sets the volume using simple exponential calculation.
Definition A2DPVolumeControl.h:215
A2DPSimpleExponentialVolumeControl()=default
Default constructor.
A2DPSimpleExponentialVolumeControl(int32_t limit)
Constructor with custom volume factor clipping limit.
Definition A2DPVolumeControl.h:205
Abstract class for handling of the volume of the audio data.
Definition A2DPVolumeControl.h:54
int32_t clip(int32_t value)
Clips audio sample value to prevent overflow.
Definition A2DPVolumeControl.h:138
virtual void set_volume(uint8_t volume)=0
Sets the volume level (pure virtual function)
void set_mono_downmix(bool enabled)
Enables or disables mono downmix.
Definition A2DPVolumeControl.h:118
int32_t get_volume_factor()
Gets the current volume factor.
Definition A2DPVolumeControl.h:100
virtual void update_audio_data(Frame *data, uint16_t frameCount)
Updates audio data with volume control and optional mono downmix.
Definition A2DPVolumeControl.h:75
bool is_volume_used
Flag indicating if volume control is enabled.
Definition A2DPVolumeControl.h:127
int32_t volumeFactorClippingLimit
Volume factor clipping limit (4095)
Definition A2DPVolumeControl.h:131
bool mono_downmix
Flag indicating if mono downmix is enabled.
Definition A2DPVolumeControl.h:128
virtual void update_audio_data(uint8_t *data, uint16_t byteCount)
Updates audio data with volume control and optional mono downmix.
Definition A2DPVolumeControl.h:66
A2DPVolumeControl()=default
Default constructor.
void set_enabled(bool enabled)
Enables or disables volume control.
Definition A2DPVolumeControl.h:112
int32_t volumeFactor
Current volume factor.
Definition A2DPVolumeControl.h:129
int32_t volumeFactorMax
Maximum volume factor (4096)
Definition A2DPVolumeControl.h:130
int32_t get_volume_factor_max()
Gets the maximum volume factor value.
Definition A2DPVolumeControl.h:106