mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Adds audio normalize support.
This commit is contained in:
parent
8039e8ae04
commit
44ca71fedb
31
README.txt
31
README.txt
@ -157,27 +157,28 @@ Setup: /etc/vdr/setup.conf
|
|||||||
0 = none, 1 = downmix
|
0 = none, 1 = downmix
|
||||||
downmix AC-3 to stero.
|
downmix AC-3 to stero.
|
||||||
|
|
||||||
softhddevice.AudioSoftvol
|
softhddevice.AudioSoftvol = 0
|
||||||
FIXME:
|
0 = off, use hardware volume control
|
||||||
|
1 = on, use software volume control
|
||||||
|
|
||||||
softhddevice.AudioNormalize
|
softhddevice.AudioNormalize = 0
|
||||||
FIXME:
|
0 = off, 1 = enable audio normalize
|
||||||
|
|
||||||
softhddevice.AudioMaxNormalize
|
softhddevice.AudioMaxNormalize = 0
|
||||||
FIXME:
|
maximal volume factor/1000 of the normalize filter
|
||||||
|
|
||||||
softhddevice.AudioCompression
|
softhddevice.AudioCompression = 0
|
||||||
FIXME:
|
0 = off, 1 = enable audio compression
|
||||||
|
|
||||||
softhddevice.AudioMaxCompression
|
softhddevice.AudioMaxCompression = 0
|
||||||
FIXME:
|
maximal volume factor/1000 of the compression filter
|
||||||
|
|
||||||
softhddevice.AudioStereoDescent
|
softhddevice.AudioStereoDescent = 0
|
||||||
FIXME:
|
reduce volume level (/1000) for stereo sources
|
||||||
|
|
||||||
softhddevice.AudioBufferTime
|
|
||||||
FIXME:
|
|
||||||
|
|
||||||
|
softhddevice.AudioBufferTime = 0
|
||||||
|
0 = default (336 ms)
|
||||||
|
1 - 1000 = size of the buffer in ms
|
||||||
|
|
||||||
softhddevice.AutoCrop.Interval = 0
|
softhddevice.AutoCrop.Interval = 0
|
||||||
0 disables auto-crop
|
0 disables auto-crop
|
||||||
|
90
audio.c
90
audio.c
@ -48,6 +48,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
#define _(str) gettext(str) ///< gettext shortcut
|
#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 AudioCompression; ///< flag use compress volume
|
||||||
static char AudioMute; ///< flag muted
|
static char AudioMute; ///< flag muted
|
||||||
static int AudioAmplifier; ///< software volume factor
|
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 AudioMaxNormalize; ///< max. normalize factor
|
||||||
static int AudioCompressionFactor; ///< current compression factor
|
static int AudioCompressionFactor; ///< current compression factor
|
||||||
static int AudioMaxCompression; ///< max. compression factor
|
static int AudioMaxCompression; ///< max. compression factor
|
||||||
@ -205,12 +208,13 @@ static const unsigned AudioRatesTable[AudioRatesMax] = {
|
|||||||
// filter
|
// 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
|
/// 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 AudioNormIndex; ///< index into average table
|
||||||
|
static int AudioNormReady; ///< index counter
|
||||||
static int AudioNormCounter; ///< sample counter
|
static int AudioNormCounter; ///< sample counter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -222,21 +226,77 @@ static int AudioNormCounter; ///< sample counter
|
|||||||
static void AudioNormalizer(int16_t * samples, int count)
|
static void AudioNormalizer(int16_t * samples, int count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int l;
|
||||||
int n;
|
int n;
|
||||||
uint32_t avg;
|
uint32_t avg;
|
||||||
|
int factor;
|
||||||
|
int16_t *data;
|
||||||
|
|
||||||
// average samples
|
// average samples
|
||||||
avg = 0;
|
l = count / AudioBytesProSample;
|
||||||
n = count / AudioBytesProSample;
|
data = samples;
|
||||||
for (i = 0; i < n; ++i) {
|
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;
|
int t;
|
||||||
|
|
||||||
t = samples[i];
|
t = (samples[i] * AudioNormalizeFactor) / 1000;
|
||||||
avg += t * t;
|
if (t < INT16_MIN) {
|
||||||
avg /= 2;
|
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)
|
static void AudioResetNormalizer(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
AudioNormCounter = 0;
|
||||||
|
AudioNormReady = 0;
|
||||||
|
for (i = 0; i < AudioNormMaxIndex; ++i) {
|
||||||
|
AudioNormAverage[i] = 0U;
|
||||||
|
}
|
||||||
|
AudioNormalizeFactor = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -690,9 +690,9 @@ void cMenuSetupSoft::Create(void)
|
|||||||
Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol,
|
Add(new cMenuEditBoolItem(tr("Volume control"), &AudioSoftvol,
|
||||||
tr("Hardware"), tr("Software")));
|
tr("Hardware"), tr("Software")));
|
||||||
Add(new cMenuEditBoolItem(tr("Enable normalize volume"),
|
Add(new cMenuEditBoolItem(tr("Enable normalize volume"),
|
||||||
&AudioMaxNormalize, trVDR("no"), trVDR("yes")));
|
&AudioNormalize, trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditIntItem(tr(" Max normalize factor (/1000)"),
|
Add(new cMenuEditIntItem(tr(" Max normalize factor (/1000)"),
|
||||||
&AudioMaxNormalize, 0, 5000));
|
&AudioMaxNormalize, 0, 10000));
|
||||||
Add(new cMenuEditBoolItem(tr("Enable volume compression"),
|
Add(new cMenuEditBoolItem(tr("Enable volume compression"),
|
||||||
&AudioCompression, trVDR("no"), trVDR("yes")));
|
&AudioCompression, trVDR("no"), trVDR("yes")));
|
||||||
Add(new cMenuEditIntItem(tr(" Max compression factor (/1000)"),
|
Add(new cMenuEditIntItem(tr(" Max compression factor (/1000)"),
|
||||||
|
2
video.c
2
video.c
@ -1857,6 +1857,7 @@ static void VaapiCleanup(VaapiDecoder * decoder)
|
|||||||
decoder->SurfaceWrite = 0;
|
decoder->SurfaceWrite = 0;
|
||||||
decoder->SurfaceField = 0;
|
decoder->SurfaceField = 0;
|
||||||
|
|
||||||
|
decoder->SyncCounter = 0;
|
||||||
decoder->FrameCounter = 0;
|
decoder->FrameCounter = 0;
|
||||||
decoder->FramesDisplayed = 0;
|
decoder->FramesDisplayed = 0;
|
||||||
decoder->Closing = 0;
|
decoder->Closing = 0;
|
||||||
@ -5736,6 +5737,7 @@ static void VdpauCleanup(VdpauDecoder * decoder)
|
|||||||
decoder->SurfaceWrite = 0;
|
decoder->SurfaceWrite = 0;
|
||||||
decoder->SurfaceField = 0;
|
decoder->SurfaceField = 0;
|
||||||
|
|
||||||
|
decoder->SyncCounter = 0;
|
||||||
decoder->FrameCounter = 0;
|
decoder->FrameCounter = 0;
|
||||||
decoder->FramesDisplayed = 0;
|
decoder->FramesDisplayed = 0;
|
||||||
decoder->Closing = 0;
|
decoder->Closing = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user