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