Commit 93415bf1 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Improving generic path rendering parameter handling

parent dc097728
......@@ -156,8 +156,7 @@ CVAPTGenericSoundPath::~CVAPTGenericSoundPath()
// Renderer
CVAPTGenericPathAudioRenderer::CVAPTGenericPathAudioRenderer( const CVAAudioRendererInitParams& oParams )
: CVAObject( oParams.sClass + ":" + oParams.sID )
, m_pCore( oParams.pCore )
: m_pCore( oParams.pCore )
, m_pCurSceneState( nullptr )
, m_iIRFilterLengthSamples( -1 )
, m_iNumChannels( -1 )
......@@ -185,9 +184,6 @@ CVAPTGenericPathAudioRenderer::CVAPTGenericPathAudioRenderer( const CVAAudioRend
ctxAudio.m_iStatus = 0; // Stopped
m_iCurGlobalAuralizationMode = IVAInterface::VA_AURAMODE_DEFAULT;
// Register the renderer as a module
oParams.pCore->RegisterModule( this );
}
CVAPTGenericPathAudioRenderer::~CVAPTGenericPathAudioRenderer()
......@@ -249,7 +245,7 @@ void CVAPTGenericPathAudioRenderer::Reset()
}
m_lSoundPaths.clear();
// Iterate over listener and free items
// Iterate over sound receiver and free items
std::map< int, CVAPTGPListener* >::const_iterator lcit = m_mListeners.begin();
while( lcit != m_mListeners.end() )
{
......@@ -460,7 +456,7 @@ CVAPTGenericSoundPath* CVAPTGenericPathAudioRenderer::CreateSoundPath( CVAPTGPSo
assert( !pSource->bDeleted && !pListener->bDeleted );
VA_VERBOSE( "PTGenericPathAudioRenderer", "Creating sound path from source " << iSourceID << " -> listener " << iListenerID);
VA_VERBOSE( "PTGenericPathAudioRenderer", "Creating sound path from source " << iSourceID << " -> sound receiver " << iListenerID);
CVAPTGenericSoundPath* pPath = dynamic_cast<CVAPTGenericSoundPath*>( m_pSoundPathPool->RequestObject() );
......@@ -477,7 +473,7 @@ CVAPTGenericSoundPath* CVAPTGenericPathAudioRenderer::CreateSoundPath( CVAPTGPSo
void CVAPTGenericPathAudioRenderer::DeleteSoundPath( CVAPTGenericSoundPath* pPath )
{
VA_VERBOSE( "PTGenericPathAudioRenderer", "Marking sound path from source " << pPath->pSource->pData->iID << " -> listener " << pPath->pListener->pData->iID << " for deletion");
VA_VERBOSE( "PTGenericPathAudioRenderer", "Marking sound path from source " << pPath->pSource->pData->iID << " -> sound receiver " << pPath->pListener->pData->iID << " for deletion");
pPath->bDelete = true;
pPath->RemoveReference();
......@@ -486,7 +482,7 @@ void CVAPTGenericPathAudioRenderer::DeleteSoundPath( CVAPTGenericSoundPath* pPat
CVAPTGenericPathAudioRenderer::CVAPTGPListener* CVAPTGenericPathAudioRenderer::CreateListener( const int iID, const CVAListenerState* pListenerState )
{
VA_VERBOSE( "PTGenericPathAudioRenderer", "Creating listener with ID " << iID );
VA_VERBOSE( "PTGenericPathAudioRenderer", "Creating sound receiver with ID " << iID );
CVAPTGPListener* pListener = dynamic_cast< CVAPTGPListener* >( m_pListenerPool->RequestObject() ); // Reference = 1
......@@ -509,7 +505,7 @@ CVAPTGenericPathAudioRenderer::CVAPTGPListener* CVAPTGenericPathAudioRenderer::C
void CVAPTGenericPathAudioRenderer::DeleteListener( int iListenerID )
{
VA_VERBOSE( "PTGenericPathAudioRenderer", "Marking listener with ID " << iListenerID << " for removal" );
VA_VERBOSE( "PTGenericPathAudioRenderer", "Marking sound receiver with ID " << iListenerID << " for removal" );
std::map< int, CVAPTGPListener* >::iterator it = m_mListeners.find( iListenerID );
CVAPTGPListener* pListener = it->second;
m_mListeners.erase( it );
......@@ -710,7 +706,7 @@ void CVAPTGenericPathAudioRenderer::UpdateGenericSoundPath( int iListenerID, int
}
}
VA_ERROR( "PTGenericPathAudioRenderer", "Could not find sound path for listener " << iListenerID << " and source " << iSourceID );
VA_ERROR( "PTGenericPathAudioRenderer", "Could not find sound path for sound receiver " << iListenerID << " and source " << iSourceID );
}
......@@ -743,7 +739,7 @@ void CVAPTGenericPathAudioRenderer::UpdateGenericSoundPath( int iListenerID, int
}
}
VA_ERROR( "PTGenericPathAudioRenderer", "Could not find sound path for listener " << iListenerID << " and source " << iSourceID );
VA_ERROR( "PTGenericPathAudioRenderer", "Could not find sound path for sound receiver " << iListenerID << " and source " << iSourceID );
}
void CVAPTGenericPathAudioRenderer::UpdateGlobalAuralizationMode( int )
......@@ -813,7 +809,7 @@ void CVAPTGenericPathAudioRenderer::HandleProcessStream( ITADatasourceRealizatio
spit++;
}
// TODO: Select active listener
// TODO: Select active sound receiver
if( !m_mListeners.empty() )
{
CVAPTGPListener* pActiveListener = m_mListeners.begin()->second;
......@@ -837,11 +833,11 @@ void CVAPTGenericPathAudioRenderer::HandleProcessStream( ITADatasourceRealizatio
{
if( bDataPresent )
{
VA_TRACE( GetObjectName(), "RMS at active listener: <Ch1," << vfRMS[ 0 ] << "> <Ch2," << vfRMS[ 1 ] << "> " );
VA_TRACE( m_oParams.sID, "RMS at active sound receiver: <Ch1," << vfRMS[ 0 ] << "> <Ch2," << vfRMS[ 1 ] << "> " );
}
else
{
VA_WARN( GetObjectName(), "No data on output channel for active listener present (empty path filter?)" );
VA_WARN( m_oParams.sID, "No data on output channel for active sound receiver present (empty path filter?)" );
}
}
}
......@@ -861,7 +857,7 @@ std::string CVAPTGenericPathAudioRenderer::HelpText() const
{
std::stringstream ss;
ss << std::endl;
ss << " --- GenericPath renderer instance '" << GetObjectName() << "' ---" << std::endl;
ss << " --- GenericPath renderer instance '" << m_oParams.sID << "' ---" << std::endl;
ss << std::endl;
ss << "[help]" << std::endl;
ss << "If the call module struct contains a key with the name 'help', this help text will be shown and the return struct will be returned with the key name 'help'." << std::endl;
......@@ -870,11 +866,11 @@ std::string CVAPTGenericPathAudioRenderer::HelpText() const
ss << "If the call module struct contains a key with the name 'info', information on the static configuration of the renderer will be returned." << std::endl;
ss << std::endl;
ss << "[update]" << std::endl;
ss << "For every successful path update, the VA source and listener ID has to be passed like this:" << std::endl;
ss << " listener: <int>, the number of the listener identifier" << std::endl;
ss << "For every successful path update, the VA source and sound receiver ID has to be passed like this:" << std::endl;
ss << " receiver: <int>, the number of the sound receiver identifier" << std::endl;
ss << " source: <int>, the number of the source identifier" << std::endl;
ss << std::endl;
ss << "Updating the path filter (impulse response in time domain) for a listener and a source can be performed in two ways:" << std::endl;
ss << "Updating the path filter (impulse response in time domain) for a sound receiver and a source can be performed in two ways:" << std::endl;
ss << " a) using a path to a multi-channel WAV file:" << std::endl;
ss << " Provide a key with the name 'filepath' and the path to the WAV file (absolute or containing the macro '$(VADataDir)' or relative to the executable) [priority given to 'filepath' if b) also applies]" << std::endl;
ss << " b) sending floating-point data for each channel" << std::endl;
......@@ -885,7 +881,7 @@ std::string CVAPTGenericPathAudioRenderer::HelpText() const
return ss.str();
}
CVAStruct CVAPTGenericPathAudioRenderer::CallObject( const CVAStruct& oArgs )
CVAStruct CVAPTGenericPathAudioRenderer::GetParameters( const CVAStruct& oArgs ) const
{
CVAStruct oReturn;
......@@ -893,118 +889,104 @@ CVAStruct CVAPTGenericPathAudioRenderer::CallObject( const CVAStruct& oArgs )
{
// Print and return help text
VA_PRINT( HelpText() );
oReturn["help"] = HelpText();
return oReturn;
}
else if( oArgs.HasKey( "info" ) )
{
oReturn[ "numchannels" ] = m_iNumChannels;
oReturn[ "irfilterlengthsamples" ] = m_iIRFilterLengthSamples;
oReturn[ "numpaths" ] = int( m_lSoundPaths.size() );
oReturn[ "filterdelaysamples" ] = m_iFilterDelaySamples;
oReturn[ "help" ] = HelpText();
return oReturn;
}
else
{
// Update
if( oArgs.HasKey( "listener" ) == false || oArgs.HasKey( "source" ) == false )
VA_EXCEPT2( INVALID_PARAMETER, "PrototypeGenericPath filter update requires a listener and a source identifier" );
int iListenerID = oArgs["listener"];
int iSourceID = oArgs["source"];
oReturn[ "numchannels" ] = m_iNumChannels;
oReturn[ "irfilterlengthsamples" ] = m_iIRFilterLengthSamples;
oReturn[ "numpaths" ] = int( m_lSoundPaths.size() );
oReturn[ "filterdelaysamples" ] = m_iFilterDelaySamples;
return oReturn;
}
bool bVerbose = false;
if( oArgs.HasKey( "verbose" ) )
bVerbose = true;
void CVAPTGenericPathAudioRenderer::SetParameters( const CVAStruct& oArgs )
{
// Update
if( oArgs.HasKey( "receiver" ) == false || oArgs.HasKey( "source" ) == false )
VA_EXCEPT2( INVALID_PARAMETER, "PrototypeGenericPath filter update requires a receiver and a source identifier" );
if( oArgs.HasKey( "filepath" ) )
{
const std::string& sFilePathRaw( oArgs[ "filepath" ] );
std::string sFilePath = m_pCore->FindFilePath( sFilePathRaw );
int iReceiverID = oArgs["receiver"];
int iSourceID = oArgs["source"];
if( oArgs.HasKey( "channel" ) )
{
int iChannelNumber = oArgs[ "channel" ];
UpdateGenericSoundPath( iListenerID, iSourceID, iChannelNumber - 1, sFilePath );
}
else
{
UpdateGenericSoundPath( iListenerID, iSourceID, sFilePath );
}
bool bVerbose = false;
if( oArgs.HasKey( "verbose" ) )
bVerbose = true;
std::stringstream ssVerboseText;
if( bVerbose )
{
ssVerboseText << "Updated sound path <L" << iListenerID << ", S" << iSourceID << "> using (unrolled) file path '" << sFilePath << "'";
VA_PRINT( ssVerboseText.str() );
oReturn["info"] = ssVerboseText.str();
if( oArgs.HasKey( "filepath" ) )
{
const std::string& sFilePathRaw( oArgs[ "filepath" ] );
std::string sFilePath = m_pCore->FindFilePath( sFilePathRaw );
return oReturn;
}
return oReturn;
if( oArgs.HasKey( "channel" ) )
{
int iChannelNumber = oArgs[ "channel" ];
UpdateGenericSoundPath( iReceiverID, iSourceID, iChannelNumber - 1, sFilePath );
}
else
{
ITASampleBuffer sbIR( m_iIRFilterLengthSamples );
for( int n=0; n < int( m_pOutput->GetNumberOfChannels() ); n++ )
{
std::string sChKey = "ch" + IntToString( n + 1 );
if( !oArgs.HasKey( sChKey ) )
continue;
UpdateGenericSoundPath( iReceiverID, iSourceID, sFilePath );
}
std::stringstream ssVerboseText;
if( bVerbose )
{
ssVerboseText << "Updated sound path <L" << iReceiverID << ", S" << iSourceID << "> using (unrolled) file path '" << sFilePath << "'";
VA_PRINT( ssVerboseText.str() );
}
}
else
{
ITASampleBuffer sbIR( m_iIRFilterLengthSamples );
for( int n=0; n < int( m_pOutput->GetNumberOfChannels() ); n++ )
{
std::string sChKey = "ch" + IntToString( n + 1 );
if( !oArgs.HasKey( sChKey ) )
continue;
const CVAStructValue& oValue( oArgs[sChKey] );
int iNumSamples = 0;
const CVAStructValue& oValue( oArgs[sChKey] );
int iNumSamples = 0;
if( oValue.GetDatatype() == CVAStructValue::DATA )
{
int iBytes = oValue.GetDataSize();
iNumSamples = iBytes / int( sizeof( float ) ); // crop overlapping bytes for safety (by integer division)
if( oValue.GetDatatype() == CVAStructValue::DATA )
if( iNumSamples > m_iIRFilterLengthSamples )
{
int iBytes = oValue.GetDataSize();
iNumSamples = iBytes / int( sizeof( float ) ); // crop overlapping bytes for safety (by integer division)
if( iNumSamples > m_iIRFilterLengthSamples )
{
VA_WARN( "PTGenericPathAudioRenderer", "Given IR filter too long, cropping to fit internal filter length." );
iNumSamples = m_iIRFilterLengthSamples;
}
const float* pfData = (const float*)( oValue.GetData() );
sbIR.Zero();
sbIR.write( pfData, iNumSamples );
VA_WARN( "PTGenericPathAudioRenderer", "Given IR filter too long, cropping to fit internal filter length." );
iNumSamples = m_iIRFilterLengthSamples;
}
else if( oValue.GetDatatype() == CVAStructValue::SAMPLEBUFFER )
{
const CVASampleBuffer& oSampleBuffer = oValue;
iNumSamples = oSampleBuffer.GetNumSamples(); // crop overlapping bytes for safety (by integer division)
if( iNumSamples > m_iIRFilterLengthSamples )
{
VA_WARN( "PTGenericPathAudioRenderer", "Given IR filter too long, cropping to fit internal filter length." );
iNumSamples = m_iIRFilterLengthSamples;
}
sbIR.Zero();
sbIR.write( oSampleBuffer.GetDataReadOnly(), iNumSamples );
}
const float* pfData = (const float*)( oValue.GetData() );
sbIR.Zero();
sbIR.write( pfData, iNumSamples );
}
else if( oValue.GetDatatype() == CVAStructValue::SAMPLEBUFFER )
{
const CVASampleBuffer& oSampleBuffer = oValue;
UpdateGenericSoundPath( iListenerID, iSourceID, n, sbIR );
iNumSamples = oSampleBuffer.GetNumSamples(); // crop overlapping bytes for safety (by integer division)
std::stringstream ssVerboseText;
if( bVerbose )
if( iNumSamples > m_iIRFilterLengthSamples )
{
ssVerboseText << "Updated sound path <L" << iListenerID << ", S" << iSourceID << ", C" << n+1 << "> with " << iNumSamples << " new samples";
VA_PRINT( ssVerboseText.str() );
std::string sInfoKey = "info_"+sChKey;
oReturn[sInfoKey] = ssVerboseText.str();
VA_WARN( "PTGenericPathAudioRenderer", "Given IR filter too long, cropping to fit internal filter length." );
iNumSamples = m_iIRFilterLengthSamples;
}
sbIR.Zero();
sbIR.write( oSampleBuffer.GetDataReadOnly(), iNumSamples );
}
if( bVerbose )
return oReturn;
UpdateGenericSoundPath( iReceiverID, iSourceID, n, sbIR );
return oReturn;
std::stringstream ssVerboseText;
if( bVerbose )
{
ssVerboseText << "Updated sound path <L" << iReceiverID << ", S" << iSourceID << ", C" << n+1 << "> with " << iNumSamples << " new samples";
VA_PRINT( ssVerboseText.str() );
}
}
VA_EXCEPT2( INVALID_PARAMETER, "Invalid object call in module " + GetObjectName() );
}
}
......
......@@ -57,7 +57,7 @@ class CVAPTGenericSoundPathFactory;
* by the user, hence the name 'generic'.
*
*/
class CVAPTGenericPathAudioRenderer : public IVAAudioRenderer, public CVAObject, public ITADatasourceRealizationEventHandler
class CVAPTGenericPathAudioRenderer : public IVAAudioRenderer, public ITADatasourceRealizationEventHandler
{
public:
CVAPTGenericPathAudioRenderer( const CVAAudioRendererInitParams& oParams );
......@@ -71,7 +71,8 @@ public:
void HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* );
void HandlePostIncrementBlockPointer( ITADatasourceRealization* ) {};
CVAStruct CallObject( const CVAStruct& );
void SetParameters( const CVAStruct& );
CVAStruct GetParameters( const CVAStruct& ) const;
std::string HelpText() const;
......
......@@ -3253,12 +3253,12 @@ void CVACoreImpl::SetSoundReceiverRealWorldPose( const int iID, const VAVec3& v3
VA_EXCEPT_NOT_IMPLEMENTED;
}
VAQuat CVACoreImpl::GetSoundReceiverRealWorldTorsoOrientation( const int iID ) const
VAQuat CVACoreImpl::GetSoundReceiverRealWorldHeadAboveTorsoOrientation( const int iID ) const
{
VA_EXCEPT_NOT_IMPLEMENTED;
}
void CVACoreImpl::SetSoundReceiverRealWorldTorsoOrientation( const int iID, const VAQuat& qOrient )
void CVACoreImpl::SetSoundReceiverRealWorldHeadAboveTorsoOrientation( const int iID, const VAQuat& qOrient )
{
VA_EXCEPT_NOT_IMPLEMENTED;
}
......
......@@ -206,8 +206,8 @@ public:
void SetSoundReceiverRealWorldPositionOrientationVU( const int iID, const VAVec3& v3Pos, const VAVec3& v3View, const VAVec3& v3Up );
void GetSoundReceiverRealWorldPose( const int iID, VAVec3& v3Pos, VAQuat& qOrient ) const;
void SetSoundReceiverRealWorldPose( const int iID, const VAVec3& v3Pos, const VAQuat& qOrient );
VAQuat GetSoundReceiverRealWorldTorsoOrientation( const int iID ) const;
void SetSoundReceiverRealWorldTorsoOrientation( const int iID, const VAQuat& qOrient );
VAQuat GetSoundReceiverRealWorldHeadAboveTorsoOrientation( const int iID ) const;
void SetSoundReceiverRealWorldHeadAboveTorsoOrientation( const int iID, const VAQuat& qOrient );
// Homogeneous medium
......
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