Commit 415ca627 authored by lmoesch's avatar lmoesch

Merge branch 'ma_2018/moesch' of https://git.rwth-aachen.de/ita/VACore into ma_2018/moesch

parents bb7f2ad7 1efa1b43
......@@ -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,35 +35,65 @@
#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 )
, m_bResetAck( false )
, m_pSampler( NULL )
, m_pDataSource( NULL )
{
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( "SignalSourceMixingEnabled", m_bSignalSourceMixingEnabled, false );
conf.OptBool( "SamplerEnabled", m_bSamplerEnabled, true );
if( m_bSamplerEnabled )
{
m_pSampler = ITASoundSampler::Create( iNumChannels, dSampleRate, iBlockLength );
m_pSampler->AddTrack( iNumChannels ); // Add one track with all channels
}
}
CVAAmbientMixerAudioRenderer::~CVAAmbientMixerAudioRenderer()
{
delete m_pDataSource;
m_pDataSource = NULL;
m_pDataSource = nullptr;
delete m_pSampler;
m_pSampler = nullptr;
}
void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization*, const ITAStreamInfo* )
......@@ -70,6 +104,15 @@ void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization
m_bIndicateReset = false;
}
// Clear output buffers first
for( int n = 0; n < int( GetOutputDatasource()->GetNumberOfChannels() ); n++ )
{
float* pfOutBuf = m_pDataSource->GetWritePointer( ( unsigned int ) ( n ) );
fm_zero( pfOutBuf, m_pDataSource->GetBlocklength() );
}
// Mix sound source signals
if( m_pNewSceneState )
{
if( m_pCurSceneState )
......@@ -77,44 +120,59 @@ void CVAAmbientMixerAudioRenderer::HandleProcessStream( ITADatasourceRealization
m_pCurSceneState = m_pNewSceneState;
m_pNewSceneState = NULL;
}
else
{
if( m_pCurSceneState == nullptr )
return;
}
for( int n=0; n < int( m_pDataSource->GetNumberOfChannels() ); n++ )
if( m_bSignalSourceMixingEnabled && m_pCurSceneState )
{
float* pfOutBuf = m_pDataSource->GetWritePointer( (unsigned int)( n ) );
fm_zero( pfOutBuf, m_pDataSource->GetBlocklength() );
}
// Gather all incoming audio streams from sound sources and mix them to the output stream
std::vector< int > viSoundSourceIDs;
m_pCurSceneState->GetSoundSourceIDs( &viSoundSourceIDs );
std::vector< int > viSoundSourceIDs;
m_pCurSceneState->GetSoundSourceIDs( &viSoundSourceIDs );
for( auto iID : viSoundSourceIDs )
{
CVASoundSourceDesc* pDesc = m_oParams.pCore->GetSceneManager()->GetSoundSourceDesc( iID );
CVASoundSourceState* pState = m_pCurSceneState->GetSoundSourceState( iID );
for( size_t i=0; i < viSoundSourceIDs.size(); i++ )
{
int iID = viSoundSourceIDs[i];
CVASoundSourceDesc* pDesc = m_oParams.pCore->GetSceneManager()->GetSoundSourceDesc( iID );
CVASoundSourceState* pState = m_pCurSceneState->GetSoundSourceState( iID );
assert( pDesc && pState );
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.load() );
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
}
}
}
// Mix sound sampler output
if( m_bSamplerEnabled && 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_pSampler->IncrementBlockPointer();
}
m_pDataSource->IncrementWritePointer();
}
......@@ -144,4 +202,55 @@ void CVAAmbientMixerAudioRenderer::UpdateScene( CVASceneState* pNewState )
m_pNewSceneState = pNewState;
}
void CVAAmbientMixerAudioRenderer::SetParameters( const CVAStruct& oInArgs )
{
if( oInArgs.HasKey( "Sampler" ) )
{
const CVAStruct& oSamplerUpdate( oInArgs[ "Sampler" ] );
int iTrack = 0; // First track
if( oSamplerUpdate.HasKey( "NewTrack" ) )
{
iTrack = m_pSampler->AddTrack( oSamplerUpdate[ "NewTrack" ] );
}
if( oSamplerUpdate.HasKey( "SampleFilePath" ) )
{
std::string sFilePathRaw = oSamplerUpdate[ "SampleFilePath" ];
std::string sFilePath = m_oParams.pCore->FindFilePath( sFilePathRaw );
int iNewSampleID = m_pSampler->LoadSample( sFilePath );
int iSampleCount = 0; // Immediate playback
m_pSampler->AddPlaybackBySamplecount( iNewSampleID, iTrack, iSampleCount );
}
}
}
CVAStruct CVAAmbientMixerAudioRenderer::GetParameters( const CVAStruct& oInArgs ) const
{
CVAStruct oParameters;
oParameters[ "SamplerEnabled" ] = m_bSamplerEnabled;
oParameters[ "SignalSourceMixingEnabled" ] = m_bSignalSourceMixingEnabled;
oParameters[ "InitParams" ] = *( m_oParams.pConfig );
if( m_pSampler )
{
CVAStruct oSamplerInfo;
oSamplerInfo[ "NumChannels" ] = ( int ) m_pSampler->GetNumberOfChannels();
oSamplerInfo[ "SamplingRate" ] = m_pSampler->GetSampleRate();
oSamplerInfo[ "BlockLength" ] = ( int ) m_pSampler->GetBlocklength();
oSamplerInfo[ "SampleCount" ] = m_pSampler->GetSampleCount();
oParameters[ "Sampler" ] = oSamplerInfo;
}
if( oInArgs.HasKey( "help" ) || oInArgs.HasKey( "doc" ) || oInArgs.HasKey( "info" ) )
{
CVAStruct oHelpSampler;
oHelpSampler[ "AddTrack" ] = "To add a new sample, use ...";
CVAStruct oHelp;
oHelp[ "Sampler" ] = oHelpSampler;
}
return oParameters;
}
#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,34 @@ 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();
CVAStruct GetInfo() const;
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_bSamplerEnabled; //!< Flag for activated sampler in config
bool m_bSignalSourceMixingEnabled; //!< Flag for activated signal mixing in config
CVASceneState* m_pNewSceneState;
CVASceneState* m_pCurSceneState;
ITAAtomicBool m_bIndicateReset, m_bResetAck;
std::atomic< bool > m_bIndicateReset;
std::atomic< bool > m_bResetAck;
inline CVAAmbientMixerAudioRenderer operator=( const CVAAmbientMixerAudioRenderer & ) { VA_EXCEPT_NOT_IMPLEMENTED; };
};
......
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