vdr-plugin-softhddevice-drm-gles 1.6.7
audioprocessor.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
14#include <cmath>
15#include <cstdint>
16#include <cstring>
17#include <string>
18
19#include "audioprocessor.h"
20#include "logger.h"
21
22/******************************************************************************
23 * Audio Manipulation
24 *****************************************************************************/
25
32 : m_bytesPerSample(bytesPerSample)
33{
34}
35
43{
44 int i;
45 int l;
46 int n;
48 int factor;
49 uint16_t *data;
50
51 // average samples
53 data = samples;
54 do {
55 n = l;
58 }
60 for (i = 0; i < n; ++i) {
61 int t;
62
63 t = data[i];
64 avg += (t * t) / NORMALIZE_SAMPLES;
65 }
71 } else {
72 avg = 0;
73 for (i = 0; i < NORMALIZE_MAX_INDEX; ++i) {
75 }
76
77 // calculate normalize factor
78 if (avg > 0) {
79 factor = ((INT16_MAX / 8) * 1000U) / (uint32_t) sqrt(avg);
80 // smooth normalize
81 m_normalizeFactor = (m_normalizeFactor * 500 + factor * 500) / 1000;
84 }
87 }
88 } else {
89 factor = 1000;
90 }
91 LOGDEBUG2(L_SOUND, "audio: %s: avg %8d, fac=%6.3f, norm=%6.3f", __FUNCTION__,
92 avg, factor / 1000.0, m_normalizeFactor / 1000.0);
93 }
94
98 }
99 data += n;
100 l -= n;
101 } while (l > 0);
102
103 // apply normalize factor
104 for (i = 0; i < count / m_bytesPerSample; ++i) {
105 int t;
106
107 t = (samples[i] * m_normalizeFactor) / 1000;
108 if (t < INT16_MIN) {
109 t = INT16_MIN;
110 } else if (t > INT16_MAX) {
111 t = INT16_MAX;
112 }
113 samples[i] = t;
114 }
115}
116
126
137
145{
146 int maxSample;
147 int i;
148 int factor;
149
150 // find loudest sample
151 maxSample = 0;
152 for (i = 0; i < count / m_bytesPerSample; ++i) {
153 int t;
154
155 t = abs(samples[i]);
156 if (t > maxSample) {
157 maxSample = t;
158 }
159 }
160
161 // calculate compression factor
162 if (maxSample > 0) {
163 factor = (INT16_MAX * 1000) / maxSample;
164 // smooth compression (FIXME: make configurable?)
165 m_compressionFactor = (m_compressionFactor * 950 + factor * 50) / 1000;
167 m_compressionFactor = factor; // no clipping
168 }
171 }
172 } else {
173 return; // silent nothing todo
174 }
175
176 LOGDEBUG2(L_SOUND, "audio: %s: max %5d, fac=%6.3f, com=%6.3f", __FUNCTION__,
177 maxSample, factor / 1000.0, m_compressionFactor / 1000.0);
178
179 // apply compression factor
180 for (i = 0; i < count / m_bytesPerSample; ++i) {
181 int t;
182
183 t = (samples[i] * m_compressionFactor) / 1000;
184 if (t < INT16_MIN) {
185 t = INT16_MIN;
186 } else if (t > INT16_MAX) {
187 t = INT16_MAX;
188 }
189 samples[i] = t;
190 }
191}
192
208
216
223{
224 int i;
225/*
226 LOGDEBUG2(L_SOUND, "audio: %s: %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i onoff %d", __FUNCTION__,
227 band[0], band[1], band[2], band[3], band[4], band[5], band[6], band[7],
228 band[8], band[9], band[10], band[11], band[12], band[13], band[14],
229 band[15], band[16], band[17], onoff);
230*/
231 for (i = 0; i < 18; i++) {
232 switch (band[i]) {
233 case 1: m_equalizerBand[i] = 1.5; break;
234 case 0: m_equalizerBand[i] = 1; break;
235 case -1: m_equalizerBand[i] = 0.95; break;
236 case -2: m_equalizerBand[i] = 0.9; break;
237 case -3: m_equalizerBand[i] = 0.85; break;
238 case -4: m_equalizerBand[i] = 0.8; break;
239 case -5: m_equalizerBand[i] = 0.75; break;
240 case -6: m_equalizerBand[i] = 0.7; break;
241 case -7: m_equalizerBand[i] = 0.65; break;
242 case -8: m_equalizerBand[i] = 0.6; break;
243 case -9: m_equalizerBand[i] = 0.55; break;
244 case -10: m_equalizerBand[i] = 0.5; break;
245 case -11: m_equalizerBand[i] = 0.45; break;
246 case -12: m_equalizerBand[i] = 0.4; break;
247 case -13: m_equalizerBand[i] = 0.35; break;
248 case -14: m_equalizerBand[i] = 0.3; break;
249 case -15: m_equalizerBand[i] = 0.25; break;
250 }
251 }
252}
253
258{
259 char buffer[256];
260
261 snprintf(buffer, sizeof(buffer),
262 "1b=%.2f:2b=%.2f:3b=%.2f"
263 ":4b=%.2f:5b=%.2f:6b=%.2f"
264 ":7b=%.2f:8b=%.2f:9b=%.2f"
265 ":10b=%.2f:11b=%.2f:12b=%.2f"
266 ":13b=%.2f:14b=%.2f:15b=%.2f:"
267 "16b=%.2f:17b=%.2f:18b=%.2f ",
274
275 return buffer;
276}
277
287{
288 int i;
289
290 // silence
291 if (volume == 0 || !m_amplifier) {
292 memset(samples, 0, count);
293 return;
294 }
295
296 for (i = 0; i < count / m_bytesPerSample; ++i) {
297 int t;
298
299 t = (samples[i] * m_amplifier) / 1000;
300 if (t < INT16_MIN) {
301 t = INT16_MIN;
302 } else if (t > INT16_MAX) {
303 t = INT16_MAX;
304 }
305 samples[i] = t;
306 }
307}
Audio Manipulation Interface Header File.
cAudioProcessor(const int)
Create a new audio processoror.
static constexpr int COMPRESSION_DEFAULT_FACTOR
default compression factor
void SetNormalizer(int)
Set normalize volume parameters.
void ResetNormalizer(void)
void Normalize(uint16_t *, int)
Normalize audio samples.
int m_normalizeIndex
index into normalize average table
int m_amplifier
software volume amplify factor
static constexpr int NORMALIZE_MAX_INDEX
number of normalize average samples
void SetEqualizer(int[18])
Set equalizer bands.
float m_equalizerBand[18]
equalizer band
int m_normalizeReady
index normalize counter
int m_compressionFactor
current compression factor
static constexpr int NORMALIZE_DEFAULT_FACTOR
default normalize factor
int m_normalizeMaxFactor
max. normalize factor
int m_compressionMaxFactor
max. compression factor
std::string GetEqualizerOptions(void) const
Get equalizer filter options.
const int m_bytesPerSample
uint32_t m_normalizeAverage[NORMALIZE_MAX_INDEX]
average of n last normalize sample blocks
int m_normalizeFactor
current normalize factor
int m_normalizeCounter
normalize sample counter
void Amplify(int16_t *, int, int)
Amplify the samples in software.
static constexpr int COMPRESSION_DEFAULT_MAX_FACTOR
default compression max. factor
void SetCompressor(int)
Set volume compression parameters.
static constexpr int NORMALIZE_SAMPLES
number of normalize samples
void Compress(uint16_t *, int)
Compress audio samples.
static constexpr int NORMALIZE_MIN_FACTOR
min. normalize factor
void ResetCompressor(void)
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
Definition logger.h:47
@ L_SOUND
sound logs
Definition logger.h:58
Logger Header File.