Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2012-07-02 13:31:51 +0400
committerHendrik Leppkes <h.leppkes@gmail.com>2012-07-02 17:35:33 +0400
commit8c7bec11ba09c369e0e4de71aaa2195b1c28ca31 (patch)
treee1aeffec0f08279de37e30b4a31b74230da2a2ae /decoder/LAVAudio
parent3c813a547c5ef0503c6b579e52f390fa0b94b159 (diff)
mixing: Add options for matrix normalization and clip protection
Diffstat (limited to 'decoder/LAVAudio')
-rw-r--r--decoder/LAVAudio/AudioSettingsProp.cpp18
-rw-r--r--decoder/LAVAudio/LAVAudio.cpp11
-rw-r--r--decoder/LAVAudio/LAVAudio.h2
-rw-r--r--decoder/LAVAudio/LAVAudio.rc2
-rw-r--r--decoder/LAVAudio/LAVAudioSettings.h2
-rw-r--r--decoder/LAVAudio/PostProcessor.cpp29
-rw-r--r--decoder/LAVAudio/resource.h4
7 files changed, 64 insertions, 4 deletions
diff --git a/decoder/LAVAudio/AudioSettingsProp.cpp b/decoder/LAVAudio/AudioSettingsProp.cpp
index 9861b99d..75b54624 100644
--- a/decoder/LAVAudio/AudioSettingsProp.cpp
+++ b/decoder/LAVAudio/AudioSettingsProp.cpp
@@ -386,6 +386,12 @@ HRESULT CLAVAudioMixingProp::OnApplyChanges()
bVal = (BOOL)SendDlgItemMessage(m_Dlg, IDC_UNTOUCHED_STEREO, BM_GETCHECK, 0, 0);
if (bVal) dwMixingFlags |= LAV_MIXING_FLAG_UNTOUCHED_STEREO;
+ bVal = (BOOL)SendDlgItemMessage(m_Dlg, IDC_NORMALIZE_MATRIX, BM_GETCHECK, 0, 0);
+ if (bVal) dwMixingFlags |= LAV_MIXING_FLAG_NORMALIZE_MATRIX;
+
+ bVal = (BOOL)SendDlgItemMessage(m_Dlg, IDC_CLIP_PROTECTION, BM_GETCHECK, 0, 0);
+ if (bVal) dwMixingFlags |= LAV_MIXING_FLAG_CLIP_PROTECTION;
+
m_pAudioSettings->SetMixingFlags(dwMixingFlags);
LoadData();
@@ -424,6 +430,8 @@ HRESULT CLAVAudioMixingProp::OnActivate()
SendDlgItemMessage(m_Dlg, IDC_OUTPUT_SPEAKERS, CB_SETCURSEL, get_speaker_index(m_dwSpeakerLayout), 0);
SendDlgItemMessage(m_Dlg, IDC_UNTOUCHED_STEREO, BM_SETCHECK, !!(m_dwFlags & LAV_MIXING_FLAG_UNTOUCHED_STEREO), 0);
+ SendDlgItemMessage(m_Dlg, IDC_NORMALIZE_MATRIX, BM_SETCHECK, !!(m_dwFlags & LAV_MIXING_FLAG_NORMALIZE_MATRIX), 0);
+ SendDlgItemMessage(m_Dlg, IDC_CLIP_PROTECTION, BM_SETCHECK, !!(m_dwFlags & LAV_MIXING_FLAG_CLIP_PROTECTION), 0);
}
return hr;
@@ -461,6 +469,16 @@ INT_PTR CLAVAudioMixingProp::OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wPara
if (lValue == !(m_dwFlags & LAV_MIXING_FLAG_UNTOUCHED_STEREO)) {
SetDirty();
}
+ } else if (LOWORD(wParam) == IDC_NORMALIZE_MATRIX && HIWORD(wParam) == BN_CLICKED) {
+ lValue = SendDlgItemMessage(m_Dlg, LOWORD(wParam), BM_GETCHECK, 0, 0);
+ if (lValue == !(m_dwFlags & LAV_MIXING_FLAG_NORMALIZE_MATRIX)) {
+ SetDirty();
+ }
+ } else if (LOWORD(wParam) == IDC_CLIP_PROTECTION && HIWORD(wParam) == BN_CLICKED) {
+ lValue = SendDlgItemMessage(m_Dlg, LOWORD(wParam), BM_GETCHECK, 0, 0);
+ if (lValue == !(m_dwFlags & LAV_MIXING_FLAG_CLIP_PROTECTION)) {
+ SetDirty();
+ }
}
break;
case WM_HSCROLL:
diff --git a/decoder/LAVAudio/LAVAudio.cpp b/decoder/LAVAudio/LAVAudio.cpp
index 833f0bcb..9cf2edab 100644
--- a/decoder/LAVAudio/LAVAudio.cpp
+++ b/decoder/LAVAudio/LAVAudio.cpp
@@ -85,6 +85,8 @@ CLAVAudio::CLAVAudio(LPUNKNOWN pUnk, HRESULT* phr)
, m_bInputPadded(FALSE)
, m_avrContext(NULL)
, m_bAVResampleFailed(FALSE)
+ , m_bMixingSettingsChanged(FALSE)
+ , m_fMixingClipThreshold(0.0f)
{
#ifdef DEBUG
DbgSetModuleLevel (LOG_CUSTOM1, DWORD_MAX); // FFMPEG messages use custom1
@@ -193,7 +195,7 @@ HRESULT CLAVAudio::LoadDefaults()
m_settings.MixingEnabled = FALSE;
m_settings.MixingLayout = AV_CH_LAYOUT_STEREO;
- m_settings.MixingFlags = 0;
+ m_settings.MixingFlags = LAV_MIXING_FLAG_CLIP_PROTECTION;
return S_OK;
}
@@ -633,6 +635,8 @@ STDMETHODIMP CLAVAudio::SetMixingEnabled(BOOL bEnabled)
m_settings.MixingEnabled = bEnabled;
SaveSettings();
+ m_bMixingSettingsChanged = TRUE;
+
return S_OK;
}
@@ -646,6 +650,8 @@ STDMETHODIMP CLAVAudio::SetMixingLayout(DWORD dwLayout)
m_settings.MixingLayout = dwLayout;
SaveSettings();
+ m_bMixingSettingsChanged = TRUE;
+
return S_OK;
}
@@ -659,6 +665,8 @@ STDMETHODIMP CLAVAudio::SetMixingFlags(DWORD dwFlags)
m_settings.MixingFlags = dwFlags;
SaveSettings();
+ m_bMixingSettingsChanged = TRUE;
+
return S_OK;
}
@@ -1321,6 +1329,7 @@ HRESULT CLAVAudio::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, doubl
m_dRate = dRate;
else
m_dRate = 1.0;
+ m_fMixingClipThreshold = 0.0f;
return __super::NewSegment(tStart, tStop, dRate);
}
diff --git a/decoder/LAVAudio/LAVAudio.h b/decoder/LAVAudio/LAVAudio.h
index aeb4de8b..3f670d81 100644
--- a/decoder/LAVAudio/LAVAudio.h
+++ b/decoder/LAVAudio/LAVAudio.h
@@ -268,6 +268,8 @@ private:
LAVAudioSampleFormat m_sfRemixFormat;
DWORD m_dwRemixLayout;
BOOL m_bAVResampleFailed;
+ BOOL m_bMixingSettingsChanged;
+ float m_fMixingClipThreshold;
// Settings
struct AudioSettings {
diff --git a/decoder/LAVAudio/LAVAudio.rc b/decoder/LAVAudio/LAVAudio.rc
index 1e6dd81d..ea83beba 100644
--- a/decoder/LAVAudio/LAVAudio.rc
+++ b/decoder/LAVAudio/LAVAudio.rc
@@ -115,6 +115,8 @@ BEGIN
COMBOBOX IDC_OUTPUT_SPEAKERS,121,30,90,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Settings",IDC_MIX_SETTINGS,225,7,133,53
CONTROL "Don't mix Stereo sources",IDC_UNTOUCHED_STEREO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,237,19,100,10
+ CONTROL "Normalize Matrix",IDC_NORMALIZE_MATRIX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,237,33,100,10
+ CONTROL "Clipping Protection",IDC_CLIP_PROTECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,237,47,100,10
END
IDD_PROPPAGE_FORMATS DIALOGEX 0, 0, 369, 215
diff --git a/decoder/LAVAudio/LAVAudioSettings.h b/decoder/LAVAudio/LAVAudioSettings.h
index 6c1dbf75..d8689f74 100644
--- a/decoder/LAVAudio/LAVAudioSettings.h
+++ b/decoder/LAVAudio/LAVAudioSettings.h
@@ -148,6 +148,8 @@ interface ILAVAudioSettings : public IUnknown
STDMETHOD_(DWORD,GetMixingLayout)() = 0;
#define LAV_MIXING_FLAG_UNTOUCHED_STEREO 0x0001
+#define LAV_MIXING_FLAG_NORMALIZE_MATRIX 0x0002
+#define LAV_MIXING_FLAG_CLIP_PROTECTION 0x0004
// Enable/Disable Mixing
STDMETHOD(SetMixingFlags)(DWORD dwFlags) = 0;
STDMETHOD_(DWORD,GetMixingFlags)() = 0;
diff --git a/decoder/LAVAudio/PostProcessor.cpp b/decoder/LAVAudio/PostProcessor.cpp
index 49f04e31..89f487f1 100644
--- a/decoder/LAVAudio/PostProcessor.cpp
+++ b/decoder/LAVAudio/PostProcessor.cpp
@@ -560,8 +560,9 @@ HRESULT CLAVAudio::PerformMixing(BufferDetails *buffer)
ConvertSampleFormat(buffer, SampleFormat_32);
}
- if (buffer->dwChannelMask != m_DecodeLayoutSanified || (!m_avrContext && !m_bAVResampleFailed) || m_settings.MixingLayout != m_dwRemixLayout) {
+ if (buffer->dwChannelMask != m_DecodeLayoutSanified || (!m_avrContext && !m_bAVResampleFailed) || m_bMixingSettingsChanged) {
m_bAVResampleFailed = FALSE;
+ m_bMixingSettingsChanged = FALSE;
if (m_avrContext) {
avresample_close(m_avrContext);
avresample_free(&m_avrContext);
@@ -574,6 +575,11 @@ HRESULT CLAVAudio::PerformMixing(BufferDetails *buffer)
if (m_sfRemixFormat == SampleFormat_24)
m_sfRemixFormat = SampleFormat_32;
+ BOOL bNormalize = !!(m_settings.MixingFlags & LAV_MIXING_FLAG_NORMALIZE_MATRIX);
+ // Force FP32 output from remixing when not performing normalization
+ if (!bNormalize)
+ m_sfRemixFormat = SampleFormat_FP32;
+
m_avrContext = avresample_alloc_context();
av_opt_set_int(m_avrContext, "in_channel_layout", buffer->dwChannelMask, 0);
av_opt_set_int(m_avrContext, "in_sample_fmt", get_ff_sample_fmt(buffer->sfFormat), 0);
@@ -586,7 +592,7 @@ HRESULT CLAVAudio::PerformMixing(BufferDetails *buffer)
int out_ch = av_get_channel_layout_nb_channels(m_settings.MixingLayout);
double *matrix_dbl = (double *)av_mallocz(in_ch * out_ch * sizeof(*matrix_dbl));
- ret = avresample_build_matrix(buffer->dwChannelMask, m_settings.MixingLayout, M_SQRT1_2, M_SQRT1_2, 0.0, 1, matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
+ ret = avresample_build_matrix(buffer->dwChannelMask, m_settings.MixingLayout, M_SQRT1_2, M_SQRT1_2, 0.0, bNormalize, matrix_dbl, in_ch, AV_MATRIX_ENCODING_NONE);
if (ret < 0) {
DbgLog((LOG_ERROR, 10, L"avresample_build_matrix failed, layout in: %x, out: %x, sample fmt in: %d, out: %d", buffer->dwChannelMask, m_settings.MixingLayout, buffer->sfFormat, m_sfRemixFormat));
av_free(matrix_dbl);
@@ -626,6 +632,25 @@ HRESULT CLAVAudio::PerformMixing(BufferDetails *buffer)
return S_FALSE;
}
+ if (!(m_settings.MixingFlags & LAV_MIXING_FLAG_NORMALIZE_MATRIX) && (m_settings.MixingFlags & LAV_MIXING_FLAG_CLIP_PROTECTION)) {
+ ASSERT(m_sfRemixFormat == SampleFormat_FP32);
+
+ DWORD dwSamples = av_get_channel_layout_nb_channels(m_dwRemixLayout) * buffer->nSamples;
+ BOOL bNeedNormalize = (m_fMixingClipThreshold > 1.0f);
+ float *pfOut = (float *)pOut;
+ for (DWORD i = 0; i < dwSamples; i++) {
+ float fVal = abs(pfOut[i]);
+ if (fVal > 1.0f && fVal > m_fMixingClipThreshold) {
+ m_fMixingClipThreshold = fVal;
+ bNeedNormalize = TRUE;
+ DbgLog((LOG_TRACE, 10, L"PerformMixing: Clipping Protection engaged with coeff of %f", m_fMixingClipThreshold));
+ }
+ if (bNeedNormalize) {
+ pfOut[i] /= m_fMixingClipThreshold;
+ }
+ }
+ }
+
delete buffer->bBuffer;
buffer->bBuffer = pcmOut;
buffer->dwChannelMask = m_dwRemixLayout;
diff --git a/decoder/LAVAudio/resource.h b/decoder/LAVAudio/resource.h
index 6bbf9149..8e149f36 100644
--- a/decoder/LAVAudio/resource.h
+++ b/decoder/LAVAudio/resource.h
@@ -95,6 +95,8 @@
#define IDC_MIX_SETTINGS 1110
#define IDC_LBL_OUTPUT_SPEAKERS 1111
#define IDC_LBL_MIXING 1112
+#define IDC_NORMALIZE_MATRIX 1113
+#define IDC_CLIP_PROTECTION 1114
// Next default values for new objects
//
@@ -102,7 +104,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1113
+#define _APS_NEXT_CONTROL_VALUE 1115
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif