summaryrefslogtreecommitdiff
path: root/audio.c
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2012-04-19 16:01:20 +0200
committerJohns <johns98@gmx.net>2012-04-19 16:01:20 +0200
commit44ca71fedb800ddef183feccdb9c1a69492aa89e (patch)
tree6d53d43f8a8505b1d1969b3ae7b8338f8e4d76bd /audio.c
parent8039e8ae041e0a53db31fc01365ebd3c3cd5d4e6 (diff)
downloadvdr-plugin-softhddevice-44ca71fedb800ddef183feccdb9c1a69492aa89e.tar.gz
vdr-plugin-softhddevice-44ca71fedb800ddef183feccdb9c1a69492aa89e.tar.bz2
Adds audio normalize support.
Diffstat (limited to 'audio.c')
-rw-r--r--audio.c90
1 files changed, 79 insertions, 11 deletions
diff --git a/audio.c b/audio.c
index 9342585..a025752 100644
--- a/audio.c
+++ b/audio.c
@@ -48,6 +48,7 @@
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
+#include <math.h>
#include <libintl.h>
#define _(str) gettext(str) ///< gettext shortcut
@@ -163,6 +164,8 @@ static char AudioNormalize; ///< flag use volume normalize
static char AudioCompression; ///< flag use compress volume
static char AudioMute; ///< flag muted
static int AudioAmplifier; ///< software volume factor
+static int AudioNormalizeFactor; ///< current normalize factor
+static const int AudioMinNormalize = 100; ///< min. normalize factor
static int AudioMaxNormalize; ///< max. normalize factor
static int AudioCompressionFactor; ///< current compression factor
static int AudioMaxCompression; ///< max. compression factor
@@ -205,12 +208,13 @@ static const unsigned AudioRatesTable[AudioRatesMax] = {
// filter
//----------------------------------------------------------------------------
-static const int AudioNormSamples = 32768; ///< number of samples
+static const int AudioNormSamples = 4096; ///< number of samples
-#define AudioNormIndexes 128 ///< number of average values
+#define AudioNormMaxIndex 128 ///< number of average values
/// average of n last sample blocks
-static uint32_t AudioNormAverage[AudioNormIndexes];
+static uint32_t AudioNormAverage[AudioNormMaxIndex];
static int AudioNormIndex; ///< index into average table
+static int AudioNormReady; ///< index counter
static int AudioNormCounter; ///< sample counter
/**
@@ -222,21 +226,77 @@ static int AudioNormCounter; ///< sample counter
static void AudioNormalizer(int16_t * samples, int count)
{
int i;
+ int l;
int n;
uint32_t avg;
+ int factor;
+ int16_t *data;
// average samples
- avg = 0;
- n = count / AudioBytesProSample;
- for (i = 0; i < n; ++i) {
+ l = count / AudioBytesProSample;
+ data = samples;
+ do {
+ n = l;
+ if (AudioNormCounter + n > AudioNormSamples) {
+ n = AudioNormSamples - AudioNormCounter;
+ }
+ avg = AudioNormAverage[AudioNormIndex];
+ for (i = 0; i < n; ++i) {
+ int t;
+
+ t = data[i];
+ avg += (t * t) / AudioNormSamples;
+ }
+ AudioNormAverage[AudioNormIndex] = avg;
+ AudioNormCounter += n;
+ if (AudioNormCounter >= AudioNormSamples) {
+ if (AudioNormReady < AudioNormMaxIndex) {
+ AudioNormReady++;
+ } else {
+ avg = 0;
+ for (i = 0; i < AudioNormMaxIndex; ++i) {
+ avg += AudioNormAverage[i] / AudioNormMaxIndex;
+ }
+
+ // calculate normalize factor
+ if (avg > 0) {
+ factor = ((INT16_MAX / 8) * 1000U) / (uint32_t) sqrt(avg);
+ // smooth normalize
+ AudioNormalizeFactor =
+ (AudioNormalizeFactor * 500 + factor * 500) / 1000;
+ if (AudioNormalizeFactor < AudioMinNormalize) {
+ AudioNormalizeFactor = AudioMinNormalize;
+ }
+ if (AudioNormalizeFactor > AudioMaxNormalize) {
+ AudioNormalizeFactor = AudioMaxNormalize;
+ }
+ } else {
+ factor = 1000;
+ }
+ Debug(4, "audio/noramlize: avg %8d, fac=%6.3f, norm=%6.3f\n",
+ avg, factor / 1000.0, AudioNormalizeFactor / 1000.0);
+ }
+
+ AudioNormIndex = (AudioNormIndex + 1) % AudioNormMaxIndex;
+ AudioNormCounter = 0;
+ AudioNormAverage[AudioNormIndex] = 0U;
+ }
+ data += n;
+ l -= n;
+ } while (l > 0);
+
+ // apply normalize factor
+ for (i = 0; i < count / AudioBytesProSample; ++i) {
int t;
- t = samples[i];
- avg += t * t;
- avg /= 2;
+ t = (samples[i] * AudioNormalizeFactor) / 1000;
+ if (t < INT16_MIN) {
+ t = INT16_MIN;
+ } else if (t > INT16_MAX) {
+ t = INT16_MAX;
+ }
+ samples[i] = t;
}
-
- // FIXME: more todo
}
/**
@@ -244,6 +304,14 @@ static void AudioNormalizer(int16_t * samples, int count)
*/
static void AudioResetNormalizer(void)
{
+ int i;
+
+ AudioNormCounter = 0;
+ AudioNormReady = 0;
+ for (i = 0; i < AudioNormMaxIndex; ++i) {
+ AudioNormAverage[i] = 0U;
+ }
+ AudioNormalizeFactor = 1000;
}
/**