Arduino A2DP

VolumeControl.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 "SoundData.h"
19 #include "esp_log.h"
20
27 class VolumeControl {
28 public:
29 virtual void update_audio_data(Frame* data, uint16_t frameCount, uint8_t volume, bool mono_downmix, bool is_volume_used) {
30 if (data!=nullptr && frameCount>0 && ( mono_downmix || is_volume_used)) {
31 ESP_LOGD("VolumeControl", "update_audio_data");
32 int32_t volumeFactor = get_volume_factor(volume);
33 int32_t max = get_volume_factor_max();
34 for (int i=0;i<frameCount;i++){
35 int32_t pcmLeft = data[i].channel1;
36 int32_t pcmRight = data[i].channel2;
37 // if mono -> we provide the same output on both channels
38 if (mono_downmix) {
39 pcmRight = pcmLeft = (pcmLeft + pcmRight) / 2;
40 }
41 // adjust the volume
42 if (is_volume_used) {
43 pcmLeft = pcmLeft * volumeFactor / max;
44 pcmRight = pcmRight * volumeFactor / max;
45 }
46 data[i].channel1 = pcmLeft;
47 data[i].channel2 = pcmRight;
48 }
49 }
50 }
51
52 // provides a factor in the range of 0 to 4096
53 virtual int32_t get_volume_factor(uint8_t volume) = 0;
54
55 // provides the max factor value 4096
56 virtual int32_t get_volume_factor_max() {
57 return 0x1000;
58 }
59 };
60
66 class DefaultVolumeControl : public VolumeControl {
67 // provides a factor in the range of 0 to 4096
68 virtual int32_t get_volume_factor(uint8_t volume) {
69 constexpr double base = 1.4;
70 constexpr double bits = 12;
71 constexpr double zero_ofs = pow(base, -bits);
72 constexpr double scale = pow(2.0, bits);
73 double volumeFactorFloat = (pow(base, volume * bits / 127.0 - bits) - zero_ofs) * scale / (1.0 - zero_ofs);
74 int32_t volumeFactor = volumeFactorFloat;
75 if (volumeFactor > 0x1000) {
76 volumeFactor = 0x1000;
77 }
78 return volumeFactor;
79 }
80
81 };
82
87 class SimpleExponentialVolumeControl : public VolumeControl {
88 // provides a factor in the range of 0 to 4096
89 virtual int32_t get_volume_factor(uint8_t volume) {
90 double volumeFactorFloat = volume;
91 volumeFactorFloat = pow(2.0, volumeFactorFloat * 12.0 / 127.0);
92 int32_t volumeFactor = volumeFactorFloat - 1.0;
93 if (volumeFactor > 0xfff) {
94 volumeFactor = 0xfff;
95 }
96 return volumeFactor;
97 }
98
99 };
100
106 class LinearVolumeControl : public VolumeControl {
107 // provides a factor in the range of 0 to 4096
108 virtual int32_t get_volume_factor(uint8_t volume) {
109 return volume;
110 }
111 virtual int32_t get_volume_factor_max() {
112 return 128;
113 }
114 };
115
121 class NoVolumeControl : public VolumeControl {
122 public:
123 virtual void update_audio_data(Frame* data, uint16_t frameCount, uint8_t volume, bool mono_downmix, bool ivolume_used) {
124 }
125 };
DefaultVolumeControl
Default implementation for handling of the volume of the audio data.
Definition: VolumeControl.h:66
LinearVolumeControl
The simplest possible implementation of a VolumeControl.
Definition: VolumeControl.h:106
NoVolumeControl
Keeps the audio data as is -> no volume control!
Definition: VolumeControl.h:121
SimpleExponentialVolumeControl
Exponentional volume control.
Definition: VolumeControl.h:87
VolumeControl
Abstract class for handling of the volume of the audio data.
Definition: VolumeControl.h:27