Changing atomics to C++11 version and improving Ambient Mixer Renderer

parent 9474797a
......@@ -14,12 +14,16 @@
#include "VAAmbientMixerAudioRenderer.h"
// VA includes
#include <VAAudioSignalSource.h>
#include "../../../Scene/VASceneManager.h"
#include "../../../Scene/VASoundSourceDesc.h"
#include "../../../Scene/VASoundSourceState.h"
#include "../../../Utils/VAUtils.h"
#include "../../../core/core.h"
#include "../../../VAHardwareSetup.h"
#include "../../../Audiosignals/VAAudiofileSignalSource.h"
// ITA includes
#include <ITASampleFrame.h>
......@@ -31,8 +35,8 @@
#ifdef VACORE_WITH_RENDERER_AMBIENT_MIXER
CVAAmbientMixerAudioRenderer::CVAAmbientMixerAudioRenderer( const CVAAudioRendererInitParams& oParams_ )
: m_oParams( oParams_ )
CVAAmbientMixerAudioRenderer::CVAAmbientMixerAudioRenderer( const CVAAudioRendererInitParams& oParams )
: m_oParams( oParams )
, m_pNewSceneState( NULL )
, m_pCurSceneState( NULL )
, m_bIndicateReset( false )
......@@ -40,26 +44,53 @@ CVAAmbientMixerAudioRenderer::CVAAmbientMixerAudioRenderer( const CVAAudioRender
{
assert( m_oParams.vsReproductions.size() > 0 );
double dSampleRate = m_oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate;
int iBlockLength = m_oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize;
int iNumChannels = -1;
CVAConfigInterpreter conf( *m_oParams.pConfig );
std::string sOutput;
conf.ReqString( "OutputGroup", sOutput );
const CVAHardwareOutput* pOutput = m_oParams.pCore->GetCoreConfig()->oHardwareSetup.GetOutput( sOutput );
if( pOutput == nullptr )
VA_EXCEPT2( INVALID_PARAMETER, "AmbientMixerAudioRenderer: '" + sOutput + "' is not a valid hardware output group. Disabled?" );
int iNumChannels = int( pOutput->GetPhysicalOutputChannels().size() );
double dSampleRate = m_oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate;
int iBlockLength = m_oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize;
conf.OptString( "OutputGroup", sOutput );
if( !sOutput.empty() )
{
const CVAHardwareOutput* pOutput = m_oParams.pCore->GetCoreConfig()->oHardwareSetup.GetOutput( sOutput );
if( pOutput == nullptr )
VA_EXCEPT2( INVALID_PARAMETER, "AmbientMixerAudioRenderer: '" + sOutput + "' is not a valid hardware output group. Is the output group disabled?" );
iNumChannels = int( pOutput->GetPhysicalOutputChannels().size() );
}
int iNumChannelsExplicit = -1;
if( conf.OptInteger( "NumChannels", iNumChannelsExplicit, -1 ) )
{
if( iNumChannels > 0 && iNumChannelsExplicit != iNumChannels )
VA_EXCEPT2( INVALID_PARAMETER, "AmbientMixerAudioRenderer: '" + sOutput + "' and explicitly requested number of '" + std::to_string( long( iNumChannelsExplicit ) ) + "' channels do not match." );
iNumChannels = iNumChannelsExplicit;
}
m_pDataSource = new ITADatasourceRealization( iNumChannels, dSampleRate, iBlockLength );
m_pDataSource->SetStreamEventHandler( this );
conf.OptBool( "SignalSourceMixing", m_bSignalSourceMixingActivated, false );
conf.OptBool( "Sampler", m_bSamplerActivated, true );
if( m_bSamplerActivated )
{
m_pSampler = ITASoundSampler::Create( iNumChannels, dSampleRate, iBlockLength );
}
}
CVAAmbientMixerAudioRenderer::~CVAAmbientMixerAudioRenderer()
{
delete m_pDataSource;
m_pDataSource = NULL;
m_pDataSource = nullptr;
delete m_pSampler;
m_pSampler = nullptr;
}
void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* )
......@@ -69,7 +100,7 @@ void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization
m_bResetAck = true;
m_bIndicateReset = false;
}
if( m_pNewSceneState )
{
if( m_pCurSceneState )
......@@ -83,38 +114,63 @@ void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization
return;
}
for( int n=0; n < int( m_pDataSource->GetNumberOfChannels() ); n++ )
// Clear output buffers first
for( int n = 0; n < int( GetOutputDatasource()->GetNumberOfChannels() ); n++ )
{
float* pfOutBuf = m_pDataSource->GetWritePointer( (unsigned int)( n ) );
float* pfOutBuf = m_pDataSource->GetWritePointer( ( unsigned int ) ( n ) );
fm_zero( pfOutBuf, m_pDataSource->GetBlocklength() );
}
std::vector< int > viSoundSourceIDs;
m_pCurSceneState->GetSoundSourceIDs( &viSoundSourceIDs );
for( size_t i=0; i < viSoundSourceIDs.size(); i++ )
if( m_bSignalSourceMixingActivated )
{
int iID = viSoundSourceIDs[i];
CVASoundSourceDesc* pDesc = m_oParams.pCore->GetSceneManager()->GetSoundSourceDesc( iID );
CVASoundSourceState* pState = m_pCurSceneState->GetSoundSourceState( iID );
// Gather all incoming audio streams from sound sources and mix them to the output stream
std::vector< int > viSoundSourceIDs;
m_pCurSceneState->GetSoundSourceIDs( &viSoundSourceIDs );
assert( pDesc && pState );
for( auto iID : viSoundSourceIDs )
{
CVASoundSourceDesc* pDesc = m_oParams.pCore->GetSceneManager()->GetSoundSourceDesc( iID );
CVASoundSourceState* pState = m_pCurSceneState->GetSoundSourceState( iID );
assert( pDesc && pState );
bool bForThisRenderer = ( pDesc->sExplicitRendererID == m_oParams.sID || pDesc->sExplicitRendererID.empty() );
if( !bForThisRenderer || pDesc->bMuted )
continue;
bool bForThisRenderer = ( pDesc->sExplicitRendererID == m_oParams.sID || pDesc->sExplicitRendererID.empty() );
if( !bForThisRenderer || pDesc->bMuted )
continue;
const double dGainFactor = pState->GetVolume( m_oParams.pCore->GetCoreConfig()->dDefaultAmplitudeCalibration );
const ITASampleBuffer* psbInput = pDesc->pSignalSourceInputBuf;
double dGainFactor = pState->GetVolume( m_oParams.pCore->GetCoreConfig()->dDefaultAmplitudeCalibration );
assert( pDesc->pSignalSource );
const ITASampleBuffer* psbInput = pDesc->pSignalSourceInputBuf;
// Add samples to out buffer
for( unsigned int n = 0; n < m_pDataSource->GetNumberOfChannels(); n++ )
{
float* pfOutBuf = m_pDataSource->GetWritePointer( ( unsigned int ) ( n ) );
for( int j = 0; j< int( m_pDataSource->GetBlocklength() ); j++ )
pfOutBuf[ j ] += psbInput->data()[ j ] * float( dGainFactor ); // mixing
}
}
}
if( m_bSamplerActivated && m_pSampler )
{
// Add samples to out buffer
for( int n=0; n < int( m_pDataSource->GetNumberOfChannels() ); n++ )
for( unsigned int n = 0; n < m_pSampler->GetNumberOfChannels(); n++ )
{
float* pfOutBuf = m_pDataSource->GetWritePointer( (unsigned int)( n ) );
for( int j=0; j< int( m_pDataSource->GetBlocklength() ); j++ )
pfOutBuf[j] += psbInput->data()[j] * float( dGainFactor );
const float* pfInBuf = m_pSampler->GetBlockPointer( n, &oSamplerStreamInfo );
float* pfOutBuf = m_pDataSource->GetWritePointer( ( unsigned int ) ( n ) );
fm_add( pfOutBuf, pfInBuf, m_pDataSource->GetBlocklength() ); // mixing
}
oSamplerStreamInfo.dSysTimeCode = ITAClock::getDefaultClock()->getTime();
oSamplerStreamInfo.nSamples += m_pSampler->GetBlocklength();
double dSampleRate = m_pSampler->GetSampleRate();
assert( dSampleRate );
oSamplerStreamInfo.dStreamTimeCode = ( double ) ( oSamplerStreamInfo.nSamples ) / dSampleRate;
}
m_pDataSource->IncrementWritePointer();
}
......@@ -144,4 +200,22 @@ void CVAAmbientMixerAudioRenderer::UpdateScene( CVASceneState* pNewState )
m_pNewSceneState = pNewState;
}
void CVAAmbientMixerAudioRenderer::SetParameters( const CVAStruct& )
{
}
CVAStruct CVAAmbientMixerAudioRenderer::GetParameters( const CVAStruct& oInArgs ) const
{
if( oInArgs.IsEmpty() )
return GetInfo();
}
CVAStruct CVAAmbientMixerAudioRenderer::GetInfo()
{
CVAStruct s;
s[ "AmbientSamplerActivated" ] = m_bSamplerActivated;
s[ "SignalSourceMixingActivated" ] = m_bSignalSourceMixingActivated;
}
#endif // VACORE_WITH_RENDERER_AMBIENT_MIXER
......@@ -23,13 +23,21 @@
// ITA includes
#include <ITADataSourceRealization.h>
#include <ITASoundSampler.h>
#include <ITAStreamInfo.h>
// STL
#include <atomic>
//! Ambient Mixer Audio Renderer
/**
* The mixer for ambient sources routes all sound sources with
* a signal that are not explicitly used by another renderer to
* the listenr output. It applies the gains in the chain but does
* not consider any auralization modes.
* The mixer for ambient sound either routes all sound sources with
* a signal (that are not explicitly used by another renderer) to
* the output. It applies the gains in the chain but does
* not consider any auralization modes. It also provides an ambient
* sound sampler to load multi-track samples and control the playback
* via the parameter setter method.
*
*/
class CVAAmbientMixerAudioRenderer : public IVAAudioRenderer, ITADatasourceRealizationEventHandler
......@@ -41,17 +49,33 @@ public:
void Reset();
inline void LoadScene( const std::string& ) {};
void UpdateScene( CVASceneState* );
inline void UpdateGlobalAuralizationMode( int ) {};
void SetParameters( const CVAStruct& );
CVAStruct GetParameters( const CVAStruct& ) const;
ITADatasource* GetOutputDatasource();
void HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* );
inline void HandlePostIncrementBlockPointer( ITADatasourceRealization* ) {};
ITADatasource* GetOutputDatasource();
static CVAStruct GetHelp();
private:
ITADatasourceRealization* m_pDataSource;
const CVAAudioRendererInitParams m_oParams; //!< Create a const copy of the init params
ITADatasourceRealization* m_pDataSource; //!< Data source of the ambient mixer
ITASoundSampler* m_pSampler; //!< Multi-channel multi-track ambient sound sampler
ITAStreamInfo oSamplerStreamInfo; //!< Stream info
bool m_bSamplerActivated; //!< Flag for activated sampler in config
bool m_bSignalSourceMixingActivated; //!< Flag for activated signal mixing in config
CVASceneState* m_pNewSceneState;
CVASceneState* m_pCurSceneState;
ITAAtomicBool m_bIndicateReset, m_bResetAck;
std::atomic< bool > m_bIndicateReset, m_bResetAck;
inline CVAAmbientMixerAudioRenderer operator=( const CVAAmbientMixerAudioRenderer & ) { VA_EXCEPT_NOT_IMPLEMENTED; };
};
......
......@@ -826,7 +826,7 @@ void CVAPTGenericPathAudioRenderer::HandleProcessStream( ITADatasourceRealizatio
}
CVASoundSourceDesc* pSourceData = pPath->pSource->pData;
ITASampleBuffer* psbInput = pSourceData->pSignalSourceInputBuf;
const ITASampleBuffer* psbInput = pSourceData->pSignalSourceInputBuf;
pPath->pVariableDelayLine->Process( psbInput, &m_sfTempBuffer );
......
......@@ -52,23 +52,11 @@ class IVAAudioRenderer
public:
virtual inline ~IVAAudioRenderer() {};
virtual void Reset() = 0;
// --= Resource hooks =--
virtual void Reset() = 0;
virtual void LoadScene( const std::string& sFileName ) = 0;
virtual inline void PostLoadDirectivity( const IVADirectivity* ) {};
virtual inline void PreFreeDirectivity( const IVADirectivity* ) {};
virtual inline void PostLoadHRIRDataset( const IVADirectivity* ) {};
virtual inline void PreFreeHRIRDataset( const IVADirectivity* ) {};
virtual void UpdateScene( CVASceneState* pNewSceneState ) = 0;
// @todo refactor.
virtual void UpdateGlobalAuralizationMode( int iGlobalAuralisationMode ) = 0;
virtual inline int GetAuralizationMode() const { return IVAInterface::VA_AURAMODE_ALL; };
virtual inline void SetAuralizationMode( const int ) {};
......@@ -83,12 +71,13 @@ public:
class IVAAudioRendererFactory
{
public:
//! Create a factory for audio renderers
virtual inline ~IVAAudioRendererFactory() {};
// Return the class name
//! Return the class name
virtual std::string GetClassIdentifier() const = 0;
// Factory method
//! Factory create method
virtual IVAAudioRenderer* Create( const CVAAudioRendererInitParams& oParams ) = 0;
};
......@@ -98,6 +87,7 @@ template< class TRenderer >
class CVAAudioRendererDefaultFactory : public IVAAudioRendererFactory
{
public:
//! Default factory
inline CVAAudioRendererDefaultFactory( const std::string& sClassName )
: m_sClassIdentifier( sClassName )
{
......
......@@ -25,7 +25,7 @@
CVAReproductionLowFrequencyMixer::CVAReproductionLowFrequencyMixer( const CVAAudioReproductionInitParams& oParams )
: m_oParams( oParams )
, m_pdsInputDataSource( NULL )
, m_pdsOutputDataSource( NULL )
, m_pdsMixingTable( NULL )
{
CVAConfigInterpreter conf( *oParams.pConfig );
......@@ -41,18 +41,14 @@ CVAReproductionLowFrequencyMixer::CVAReproductionLowFrequencyMixer( const CVAAud
m_viMixingChannels.push_back( 1 ); // Use first channel as default input mixing channel
}
// Retrieve num channels from first output group
int iNumOutputChannels = int( m_oParams.vpOutputs[0]->GetPhysicalOutputChannels().size() );
m_pdsOutputDataSource = new ITADatasourceRealization( int( m_viMixingChannels.size() ), oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate, oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize );
m_pdsOutputDataSource->SetStreamEventHandler( this );
m_pdsMixingTable = new ITADatasourceRealization( int( m_viMixingChannels.size() ), oParams.pCore->GetCoreConfig()->oAudioDriverConfig.dSampleRate, oParams.pCore->GetCoreConfig()->oAudioDriverConfig.iBuffersize );
m_pdsMixingTable->SetStreamEventHandler( this );
}
CVAReproductionLowFrequencyMixer::~CVAReproductionLowFrequencyMixer()
{
delete m_pdsOutputDataSource;
return;
delete m_pdsMixingTable;
}
void CVAReproductionLowFrequencyMixer::SetInputDatasource( ITADatasource* pDataSource )
......@@ -62,13 +58,11 @@ void CVAReproductionLowFrequencyMixer::SetInputDatasource( ITADatasource* pDataS
for( size_t i = 0; i < m_viMixingChannels.size(); i++ )
if( m_viMixingChannels[ i ] > int( m_pdsInputDataSource->GetNumberOfChannels() ) )
VA_EXCEPT2( INVALID_PARAMETER, "Could not connect this data source to LFE mixer because mixing channel exceeds number of input channels" );
return;
}
ITADatasource* CVAReproductionLowFrequencyMixer::GetOutputDatasource()
{
return m_pdsOutputDataSource;
return m_pdsMixingTable;
}
void CVAReproductionLowFrequencyMixer::HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* pStreamInfo )
......@@ -76,24 +70,22 @@ void CVAReproductionLowFrequencyMixer::HandleProcessStream( ITADatasourceRealiza
if( m_pdsInputDataSource == nullptr )
return;
int iNumInputChannels = m_pdsInputDataSource->GetNumberOfChannels();
for( int i = 0; i< int( m_pdsOutputDataSource->GetNumberOfChannels() ); i++ )
for( int i = 0; i< int( m_pdsMixingTable->GetNumberOfChannels() ); i++ )
{
float* pfOut = m_pdsOutputDataSource->GetWritePointer( i );
fm_zero( pfOut, m_pdsOutputDataSource->GetBlocklength() );
float* pfOut = m_pdsMixingTable->GetWritePointer( i );
fm_zero( pfOut, m_pdsMixingTable->GetBlocklength() );
for( size_t j = 0; j < m_viMixingChannels.size(); j++ )
{
const float* pfIn = m_pdsInputDataSource->GetBlockPointer( m_viMixingChannels[ j ], pStreamInfo );
fm_add( pfOut, pfIn, m_pdsOutputDataSource->GetBlocklength() );
fm_add( pfOut, pfIn, m_pdsMixingTable->GetBlocklength() );
}
if( m_viMixingChannels.size() > 1 )
fm_mul( pfOut, 1 / float( m_viMixingChannels.size() ), m_pdsOutputDataSource->GetBlocklength() );
fm_mul( pfOut, 1 / float( m_viMixingChannels.size() ), m_pdsMixingTable->GetBlocklength() );
}
m_pdsOutputDataSource->IncrementWritePointer();
m_pdsMixingTable->IncrementWritePointer();
return;
}
......@@ -110,7 +102,7 @@ void CVAReproductionLowFrequencyMixer::HandlePostIncrementBlockPointer( ITADatas
int CVAReproductionLowFrequencyMixer::GetNumInputChannels() const
{
return m_pdsOutputDataSource->GetNumberOfChannels();
return m_pdsMixingTable->GetNumberOfChannels();
}
#endif // VACORE_WITH_REPRODUCTION_MIXER_LOW_FREQUENCY
......@@ -32,13 +32,13 @@ public:
void SetInputDatasource( ITADatasource* pDatasource);
ITADatasource* GetOutputDatasource();
int GetNumInputChannels() const;
inline void UpdateScene( CVASceneState* pNewState ) {};
inline void UpdateScene( CVASceneState* ) {};
void HandleProcessStream( ITADatasourceRealization* pSender, const ITAStreamInfo* pStreamInfo );
void HandlePostIncrementBlockPointer(ITADatasourceRealization* pSender );
private:
ITADatasource* m_pdsInputDataSource;
ITADatasourceRealization* m_pdsOutputDataSource;
ITADatasourceRealization* m_pdsMixingTable;
CVAAudioReproductionInitParams m_oParams;
std::vector< int > m_viMixingChannels; // Logical mixing channel numbers, so first channel = 1 and so on
};
......
......@@ -14,23 +14,25 @@
#ifndef IW_VACORE_SOUNDSOURCEDESC
#define IW_VACORE_SOUNDSOURCEDESC
#include <ITAAtomicPrimitives.h>
#include <VAPoolObject.h>
#include <VAAudioSignalSource.h>
class ITASampleBuffer;
#include <ITASampleBuffer.h>
//! Diese Klasse beschreibt die statischen (unversionierten) Daten einer Schallquelle
#include <atomic>
//! This class describes a static unversioned sound source
class CVASoundSourceDesc : public CVAPoolObject
{
public:
int iID; //!< Schallquellen-ID
std::string sName; //!< Angezeigter Name
ITAAtomicBool bMuted; //!< Stummgeschaltet? (jst: Berechnungen sollen trotzdem durchgefhrt werden? bActive dazu?)
ITAAtomicBool bEnabled; //!< Enabled/disable from rendering
ITAAtomicBool bInitPositionOrientation; //!< Wurde die Position/Orientierung initialisiert? (jst: really required?)
ITAAtomicPtr< IVAAudioSignalSource > pSignalSource; //!< Zugeordnete Signalquelle
ITAAtomicPtr<ITASampleBuffer> pSignalSourceInputBuf; //!< Puffer der Eingangsdaten der Signalquelle
int iID; //!< Identifier
std::string sName; //!< Verbose name (for debugging)
std::atomic< bool > bMuted; //!< Muting switch (jst: Berechnungen sollen trotzdem durchgefhrt werden? bActive dazu?)
std::atomic< bool > bEnabled; //!< Enabled/disable from rendering
std::atomic< bool > bInitPositionOrientation; //!< Flag to indicate if a pose has been set, which is required for spatialisation
IVAAudioSignalSource* pSignalSource; //!< Assigned signal source pointer
std::atomic< const ITASampleBuffer* > pSignalSourceInputBuf; //!< Puffer der Eingangsdaten der Signalquelle
float fSoundPower;
std::string sExplicitRendererID; //!< Explicit renderer for this sound source (empty = all)
......@@ -40,8 +42,8 @@ public:
sName = "";
bMuted = false;
bInitPositionOrientation = false;
pSignalSource = nullptr;
pSignalSourceInputBuf = nullptr;
pSignalSource = nullptr;
}
};
......
......@@ -279,7 +279,7 @@ std::string CVACoreImpl::GetSoundSourceSignalSource( int iSoundSourceID ) const
VA_TRY
{
CVASoundSourceDesc* pDesc = m_pSceneManager->GetSoundSourceDesc( iSoundSourceID );
if( pDesc->pSignalSource.get() != nullptr )
if( pDesc->pSignalSource )
return m_pSignalSourceManager->GetSignalSourceID( pDesc->pSignalSource );
else
return "";
......@@ -315,12 +315,12 @@ void CVACoreImpl::SetSoundSourceSignalSource( int iSoundSourceID, const std::str
pNewSrc = m_pSignalSourceManager->RequestSignalSource( sSignalSourceID, &pNewBuf );
// Vorherige Bindung auflsen und Signalquelle freigeben
if( pDesc->pSignalSource.get() != nullptr )
if( pDesc->pSignalSource )
m_pSignalSourceManager->ReleaseSignalSource( pDesc->pSignalSource );
// Vorhandene Signalquelle zu dieser SoundSource zuordnen (atomare Ops)
pDesc->pSignalSource.set( pNewSrc );
pDesc->pSignalSourceInputBuf.set( pNewBuf );
pDesc->pSignalSource = pNewSrc;
pDesc->pSignalSourceInputBuf = pNewBuf;
// Ereignis generieren
CVAEvent ev;
......
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