Commit 9474797a authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Adding default HRIR support for Ambisonics binaural downmix reproduction - so...

Adding default HRIR support for Ambisonics binaural downmix reproduction - so user does not have to assign a directivity for an Ambisonics sound receiver
parent b346e3ea
......@@ -38,6 +38,7 @@
#include <cassert>
#include <vector>
#include <cmath>
#include <algorithm>
// 3rdParty includes
#include <tbb/concurrent_queue.h>
......@@ -653,10 +654,16 @@ void CVAPTGenericPathAudioRenderer::ResetInternalData()
void CVAPTGenericPathAudioRenderer::UpdateGenericSoundPath( int iListenerID, int iSourceID, const std::string& sIRFilePath )
{
ITASampleFrame sfIR( sIRFilePath );
if( sfIR.channels() != m_pOutput->GetNumberOfChannels() )
VA_EXCEPT2( INVALID_PARAMETER, "Filter has mismatching channels" );
UpdateGenericSoundPath( iListenerID, iSourceID, sfIR );
try
{
ITASampleFrame sfIR( sIRFilePath );
UpdateGenericSoundPath( iListenerID, iSourceID, sfIR );
}
catch( ITAException e )
{
VA_ERROR( "PTGenericPathAudioRenderer", "IR file path '" << sIRFilePath << "' could not be loaded for an update in generic path renderer." );
}
}
void CVAPTGenericPathAudioRenderer::UpdateGenericSoundPath( int iListenerID, int iSourceID, int iChannelIndex, const std::string& sIRFilePath )
......@@ -707,13 +714,18 @@ void CVAPTGenericPathAudioRenderer::UpdateGenericSoundPath( int iListenerID, int
if( sfIR.length() > m_iIRFilterLengthSamples )
VA_WARN( "PTGenericPathAudioRenderer", "Filter length for generic sound path too long, cropping." );
int iNumChannels = min( m_iNumChannels, sfIR.GetNumChannels() );
if( m_iNumChannels != sfIR.GetNumChannels() )
VA_WARN( "PTGenericPathAudioRenderer", "Found " << sfIR.GetNumChannels() << " channels in the IR file, but renderer is running with " << m_iNumChannels << ". Will update only first " << iNumChannels << " channel(s)." );
std::list< CVAPTGenericSoundPath* >::const_iterator spcit = m_lSoundPaths.begin();
while( spcit != m_lSoundPaths.end() )
{
CVAPTGenericSoundPath* pPath( *spcit++ );
if( pPath->pListener->pData->iID == iListenerID && pPath->pSource->pData->iID == iSourceID )
{
for( int n = 0; n < m_iNumChannels; n++ )
for( int n = 0; n < iNumChannels; n++ )
{
ITAUPConvolution* pConvolver( pPath->vpFIRConvolver[ n ] );
ITAUPFilter* pFilter = pConvolver->RequestFilter();
......@@ -947,6 +959,12 @@ void CVAPTGenericPathAudioRenderer::SetParameters( const CVAStruct& oArgs )
const std::string& sFilePathRaw( oArgs[ "filepath" ] );
std::string sFilePath = m_pCore->FindFilePath( sFilePathRaw );
if( sFilePath.empty() )
{
VA_WARN( "PTGenericPathAudioRenderer", "Given IR filter '" << sFilePathRaw << "' could not be found. Skipping this update." );
return;
}
if( oArgs.HasKey( "channel" ) )
{
int iChannelNumber = oArgs[ "channel" ];
......
......@@ -57,18 +57,35 @@ public:
CVAAmbisonicsBinauralMixdownReproduction::CVAAmbisonicsBinauralMixdownReproduction( const CVAAudioReproductionInitParams& oParams )
: m_oParams( oParams )
, m_pdsStreamFilter( NULL )
, m_pdsStreamFilter( nullptr )
, m_iListenerID( -1 )
, m_pDefaultHRIR( nullptr )
{
CVAConfigInterpreter conf( *(m_oParams.pConfig) );
conf.ReqInteger( "TruncationOrder", m_iAmbisonicsTruncationOrder ); // Sollte aus der Zahl der Eingangskanle berechnet werden
conf.OptInteger( "HRIRFilterLength", m_iHRIRFilterLength, 128 );
conf.OptInteger( "TrackedListenerID", m_iListenerID, 1 );
double dSampleRate = m_oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate;
int iBlockLength = oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize;
conf.ReqInteger( "TruncationOrder", m_iAmbisonicsTruncationOrder ); // Sollte aus der Zahl der Eingangskanle berechnet werden
conf.OptInteger( "HRIRFilterLength", m_iHRIRFilterLength, 128 );
conf.OptInteger( "TrackedListenerID", m_iListenerID, -1 );
std::string sDefaultHRIRPathRAW;
conf.OptString( "DefaultHRIR", sDefaultHRIRPathRAW );
if( !sDefaultHRIRPathRAW.empty() )
{
std::string sDefaultHRIRPath = oParams.pCore->FindFilePath( sDefaultHRIRPathRAW );
if( sDefaultHRIRPath.empty() )
{
VA_WARN( "AmbisonicsBinauralMixdownReproduction", "Could not find default HRIR '" << sDefaultHRIRPathRAW << "', you have to provide a HRIR with the tracked listener." );
}
else
{
m_pDefaultHRIR = new CVADirectivityDAFFHRIR( sDefaultHRIRPath, "AmbisonicsBinauralMixdownReproduction_DefaultHRIR", dSampleRate );
}
}
m_sfHRIRTemp.init( 2, m_iHRIRFilterLength, true );
// Binaural output
......@@ -154,6 +171,9 @@ CVAAmbisonicsBinauralMixdownReproduction::~CVAAmbisonicsBinauralMixdownReproduct
delete m_pDecoderMatrixPatchBay;
m_pDecoderMatrixPatchBay = NULL;
if( m_pDefaultHRIR )
delete m_pDefaultHRIR;
}
void CVAAmbisonicsBinauralMixdownReproduction::SetInputDatasource( ITADatasource* p )
......@@ -184,16 +204,21 @@ void CVAAmbisonicsBinauralMixdownReproduction::SetTrackedListener( const int iID
void CVAAmbisonicsBinauralMixdownReproduction::UpdateScene( CVASceneState* pNewState )
{
if( m_iListenerID == -1 )
if( m_iListenerID == -1 )
return;
CVAReceiverState* pLIstenerState( pNewState->GetReceiverState( m_iListenerID ) );
if( pLIstenerState == nullptr )
return;
const CVADirectivityDAFFHRIR* pHRIRSet = ( CVADirectivityDAFFHRIR*) pLIstenerState->GetDirectivity();
const CVADirectivityDAFFHRIR* pReceiverHRIR = ( CVADirectivityDAFFHRIR*) pLIstenerState->GetDirectivity();
if( pHRIRSet == nullptr )
const CVADirectivityDAFFHRIR* pHRIR;
if( pReceiverHRIR )
pHRIR = pReceiverHRIR;
else if( m_pDefaultHRIR )
pHRIR = m_pDefaultHRIR;
else
return;
VAVec3 vListenerPos, vListenerView, vListenerUp;
......@@ -212,18 +237,18 @@ void CVAAmbisonicsBinauralMixdownReproduction::UpdateScene( CVASceneState* pNewS
double dDistance = ( pDevice->vPos - vListenerPos ).Length();
// Re-init temp buffer to match with current HRIR length
int iHRIRFilterLength = pHRIRSet->GetProperties()->iFilterLength;
int iHRIRFilterLength = pHRIR->GetProperties()->iFilterLength;
if( m_sfHRIRTemp.length() != iHRIRFilterLength )
m_sfHRIRTemp.init( 2, iHRIRFilterLength, false );
int iIndex;
pHRIRSet->GetNearestNeighbour( float( dAzimuth ), float( dElevation ), &iIndex );
pHRIR->GetNearestNeighbour( float( dAzimuth ), float( dElevation ), &iIndex );
// Skip if still same HRIR
if( iIndex == m_viLastHRIRIndex[i] )
continue;
pHRIRSet->GetHRIRByIndex( &m_sfHRIRTemp, iIndex, 0 );
pHRIR->GetHRIRByIndex( &m_sfHRIRTemp, iIndex, 0 );
m_viLastHRIRIndex[i] = iIndex;
ITAUPFilter* pFilterChL = m_pdsStreamFilter->pFilterPool->RequestFilter();
......
......@@ -28,6 +28,7 @@
class ITADatasource;
class ITAStreamPatchbay;
class CMixdownStreamFilter;
class CVADirectivityDAFFHRIR;
class CVAAmbisonicsBinauralMixdownReproduction : public IVAAudioReproduction
{
......@@ -66,6 +67,8 @@ private:
int m_iListenerID;
const CVADirectivityDAFFHRIR* m_pDefaultHRIR;
ITASampleFrame m_sfHRIRTemp;
CMixdownStreamFilter* m_pdsStreamFilter;
ITAStreamPatchbay* m_pDecoderMatrixPatchBay;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment