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 
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 
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 
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 
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 
122  public:
123  virtual void update_audio_data(Frame* data, uint16_t frameCount, uint8_t volume, bool mono_downmix, bool ivolume_used) {
124  }
125 };
Default implementation for handling of the volume of the audio data.
Definition: VolumeControl.h:66
The simplest possible implementation of a VolumeControl.
Definition: VolumeControl.h:106
Keeps the audio data as is -> no volume control!
Definition: VolumeControl.h:121
Definition: VolumeControl.h:87
Abstract class for handling of the volume of the audio data.
Definition: VolumeControl.h:27