Commit 69d9f5f2 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

Moving initialization method to init impl file in core

parent ecfcb587
......@@ -5,7 +5,7 @@ set( SubDirs )
set( DirFiles
impl.h
impl.cpp
core_init.cpp
init.cpp
_SourceFiles.cmake
)
set( DirFiles_SourceGroup "${RelativeSourceGroup}" )
......
......@@ -276,198 +276,6 @@ int CVACoreImpl::GetState() const
return m_iState;
}
void CVACoreImpl::Initialize() {
VA_NO_REENTRANCE;
// TODO: Prfen ob im Fehlerfall zurck in den sauberen Grundzustand [WICHTIG!]
VA_VERBOSE( "Core", "Initializing core" );
VA_TRY
{
if( m_iState == VA_CORESTATE_READY )
VA_EXCEPT2( MODAL_ERROR, "Core already initialized." );
if( m_iState == VA_CORESTATE_FAIL )
VA_EXCEPT2( MODAL_ERROR, "Core corrupted, reinitialization impossible" );
m_pCoreThread = new CVACoreThread( this );
SetProgress( "Setting up audio hardware", "", 1 );
InitializeAudioDriver();
m_pR2RPatchbay = new ITAStreamPatchbay( m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize );
// Create output patch bay with a single output that uses all available physical audio outputs from sound card
m_pOutputPatchbay = new ITAStreamPatchbay( m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize );
int iPhysicalHardwareOutput = m_pOutputPatchbay->AddOutput( m_oCoreConfig.oAudioDriverConfig.iOutputChannels );
m_pOutputPatchbay->SetOutputGain( iPhysicalHardwareOutput, m_dOutputGain );
m_iGlobalAuralizationMode = VA_AURAMODE_ALL;
// Set up input stream network
ITADatasource* pInputTail = nullptr;
if( m_oCoreConfig.oAudioDriverConfig.iInputChannels > 0 )
{
pInputTail = m_pAudioDriverBackend->getInputStreamDatasource();
if( pInputTail )
{
m_pInputAmp = new ITAStreamAmplifier( pInputTail, ( float ) m_dInputGain );
m_pInputStreamDetector = new ITAStreamDetector( m_pInputAmp );
m_pInputStreamDetector->SetProfilerEnabled( true );
pInputTail = m_pInputStreamDetector;
if( m_oCoreConfig.bRecordDeviceInputEnabled )
{
VistaFileSystemFile oRecordFile( m_oCoreConfig.sRecordDeviceInputFileName );
VistaFileSystemDirectory oRecordBaseFolder( m_oCoreConfig.sRecordDeviceInputBaseFolder );
if( !oRecordBaseFolder.Exists() )
{
if( oRecordBaseFolder.CreateWithParentDirectories() )
{
VA_INFO( "Core", "Created device input record base folder " << oRecordBaseFolder.GetName() << " with parent directories" );
}
else
{
VA_EXCEPT2( INVALID_PARAMETER, "Could not create non-existent device input record base folder '" + oRecordBaseFolder.GetName() + "'" );
}
}
std::string sFilePath = oRecordBaseFolder.GetName() + "/" + oRecordFile.GetLocalName();
if( VistaFileSystemFile( sFilePath ).Exists() )
VA_INFO( "Core", "Device input record file '" << sFilePath << "' exists, will overwrite" );
m_pStreamProbeDeviceInput = new ITAStreamProbe( pInputTail, sFilePath );
pInputTail = m_pStreamProbeDeviceInput;
}
}
}
SetProgress( "Setting up resource managers", "", 2 );
assert( m_oCoreConfig.oAudioDriverConfig.iInputChannels >= 0 );
m_pSignalSourceManager = new CVAAudioSignalSourceManager( this, m_oCoreConfig.oAudioDriverConfig, pInputTail );
m_pGlobalSamplePool = ITASoundSamplePool::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate );
m_pGlobalSampler = ITASoundSampler::Create( 1, m_oCoreConfig.oAudioDriverConfig.dSampleRate, m_oCoreConfig.oAudioDriverConfig.iBuffersize, m_pGlobalSamplePool );
m_pGlobalSampler->AddMonoTrack();
m_pDirectivityManager = new CVADirectivityManager( this, m_oCoreConfig.oAudioDriverConfig.dSampleRate );
m_pDirectivityManager->Initialize();
SetProgress( "Setting up scene management", "", 3 );
m_pSceneManager = new CVASceneManager( m_pClock );
m_pSceneManager->Initialize();
m_pCurSceneState = m_pSceneManager->GetHeadSceneState();
SetProgress( "Setting up medium environment", "", 4 );
oHomogeneousMedium = m_oCoreConfig.oInitialHomogeneousMedium;
SetProgress( "Initializing rendering modules", "", 5 );
// Register all renderers and initialize
CVAAudioRendererRegistry::GetInstance()->RegisterInternalCoreFactoryMethods();
InitializeAudioRenderers();
if( m_voRenderers.empty() )
VA_EXCEPT1( "No audio renderers created" );
SetProgress( "Initializing reproduction modules", "", 6 );
// Register all reproductions and initialize
CVAAudioReproductionRegistry::GetInstance()->RegisterInternalCoreFactoryMethods();
InitializeReproductionModules();
if( m_voReproductionModules.empty() )
VA_EXCEPT1( "No audio reproduction modules created" );
SetProgress( "Patching audio i/o of rendering and reproduction modules", "", 7 );
// Patch renderer and reproduction modules
PatchRendererToReproductionModules();
// Patch audio reproduction to output
PatchReproductionModulesToOutput();
// Create output peak detector that uses patch bay output stream
m_pOutputStreamDetector = new ITAStreamDetector( m_pOutputPatchbay->GetOutputDatasource( iPhysicalHardwareOutput ) );
m_pOutputStreamDetector->SetProfilerEnabled( true );
// Setup output dump (if set)
ITADatasource* pOutputTail = m_pOutputStreamDetector;
if( m_oCoreConfig.bRecordDeviceOutputEnabled )
{
VistaFileSystemFile oRecordFile( m_oCoreConfig.sRecordDeviceOutputFileName );
VistaFileSystemDirectory oRecordBaseFolder( m_oCoreConfig.sRecordDeviceOutputBaseFolder );
if( !oRecordBaseFolder.Exists() )
{
if( oRecordBaseFolder.CreateWithParentDirectories() )
{
VA_INFO( "Core", "Created device output record base folder " << oRecordBaseFolder.GetName() << " with parent directories" );
}
else
{
VA_EXCEPT2( INVALID_PARAMETER, "Could not create non-existent device output record base folder '" + oRecordBaseFolder.GetName() + "'" );
}
}
std::string sFilePath = oRecordBaseFolder.GetName() + "/" + oRecordFile.GetLocalName();
if( VistaFileSystemFile( sFilePath ).Exists() )
VA_INFO( "Core", "Device output record file '" << sFilePath << "' exists, will overwrite" );
m_pStreamProbeDeviceOutput = new ITAStreamProbe( pOutputTail, sFilePath );
pOutputTail = m_pStreamProbeDeviceOutput;
}
// Attach the stream tracker
m_pOutputTracker = new CVAAudiostreamTracker( pOutputTail, m_pClock, &m_fCoreClockOffset, &m_lSyncModOwner, m_pSignalSourceManager );
pOutputTail = m_pOutputTracker;
// Give output stream datasource to audio driver
m_pAudioDriverBackend->setOutputStreamDatasource( pOutputTail );
// Core-Clock auf 0 initialisieren
double dNow = m_pClock->getTime();
m_fCoreClockOffset = ( float ) dNow;
m_dStreamClockOffset = -1;
// Timer erzeugen und konfigurieren (wird fr Peak-Events benutzt)
m_pTicker = new VistaTicker();
m_pTicker->AddTrigger( new VistaTicker::TriggerContext( m_oCoreConfig.iTriggerUpdateMilliseconds, true ) );
m_pTicker->SetAfterPulseFunctor( this );
// Audio-Streaming starten
SetProgress( "Starting audio streaming", "", 8 );
m_pAudioDriverBackend->startStreaming();
// Timer fr Peak-Events starten
m_pTicker->StartTicker();
// Initialisierung erfolgreich!
m_iState = VA_CORESTATE_READY;
SetProgress( "Initialization finished", "", 9 );
FinishProgress();
}
VA_FINALLY
{
// Aufrumen und Exception weiterwerfen
Tidyup();
throw;
}
}
void CVACoreImpl::Reset()
{
VA_CHECK_INITIALIZED;
......
......@@ -12,270 +12,9 @@
*/
#include "impl.h"
IVAInterface* VACore::CreateCoreInstance( const CVAStruct& oArgs, std::ostream* pOutputStream )
{
VA_TRACE( "Config", oArgs );
return new CVACoreImpl( oArgs, pOutputStream );
}
void VACore::StoreCoreConfigToFile( const CVAStruct& oConfig, const std::string& sConfigFilePath )
{
StoreStructToINIFile( sConfigFilePath, oConfig );
}
CVAStruct VACore::LoadCoreConfigFromFile( const std::string& sConfigFilePath )
{
CVAStruct oFinalCoreConfigStruct, oCurrentConfig;
VistaFileSystemFile oConfigFile( sConfigFilePath );
std::list< VistaFileSystemFile > voConfigFiles;
std::vector< VistaFileSystemDirectory > voIncludePaths;
if( oConfigFile.Exists() && oConfigFile.GetParentDirectory().empty() == false )
voIncludePaths.push_back( oConfigFile.GetParentDirectory() );
voConfigFiles.push_back( VistaFileSystemFile( sConfigFilePath ) );
VA_INFO( "Core", "Working directory: '" << VistaFileSystemDirectory::GetCurrentWorkingDirectory() << "'" );
while( voConfigFiles.empty() == false )
{
VistaFileSystemFile oCurrentConfigFile( voConfigFiles.front() );
voConfigFiles.pop_front();
if( oCurrentConfigFile.Exists() == false )
{
for( size_t n = 0; n < voIncludePaths.size(); n++ )
{
std::string sCombinedFilePath = voIncludePaths[ n ].GetName() + PATH_SEPARATOR + oCurrentConfigFile.GetLocalName();
oCurrentConfigFile.SetName( sCombinedFilePath );
if( oCurrentConfigFile.Exists() && oCurrentConfigFile.IsFile() )
{
VA_INFO( "Config", "Including further configuration file '" + oCurrentConfigFile.GetLocalName() +
"' from include path '" + voIncludePaths[ n ].GetName() + "'" );
break;
}
}
if( !oCurrentConfigFile.Exists() )
{
VA_EXCEPT2( FILE_NOT_FOUND, "Configuration file '" + oCurrentConfigFile.GetLocalName() + "' not found, aborting." );
}
}
VA_VERBOSE( "Config", std::string( "Reading INI file '" ) + oCurrentConfigFile.GetLocalName() + "'" );
LoadStructFromINIFIle( oCurrentConfigFile.GetName(), oCurrentConfig );
if( oCurrentConfig.HasKey( "paths" ) )
{
const CVAStruct& oPaths( oCurrentConfig[ "paths" ] );
CVAStruct::const_iterator it = oPaths.Begin();
while( it != oPaths.End() )
{
const CVAStructValue& oIncludePath( ( it++ )->second );
VistaFileSystemDirectory oNewPathDir( oIncludePath );
if( oNewPathDir.Exists() && oNewPathDir.IsDirectory() )
voIncludePaths.push_back( oNewPathDir );
}
}
if( oCurrentConfig.HasKey( "files" ) )
{
const CVAStruct& oPaths( oCurrentConfig[ "files" ] );
CVAStruct::const_iterator it = oPaths.Begin();
while( it != oPaths.End() )
{
const CVAStructValue& oIncludeFile( ( it++ )->second );
voConfigFiles.push_back( VistaFileSystemFile( oIncludeFile ) );
}
}
oCurrentConfig.RemoveKey( "files" );
// Merge structs (check for uniqueness)
oFinalCoreConfigStruct.Merge( oCurrentConfig, true );
}
return oFinalCoreConfigStruct;
}
#ifdef WIN32
// Trick um DLL-Pfad zu ermitteln
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#endif
std::string VACore::GetCoreLibFilePath()
{
#ifdef WIN32
CHAR pszPath[ MAX_PATH + 1 ] = { 0 };
GetModuleFileNameA( ( HINSTANCE ) &__ImageBase, pszPath, _countof( pszPath ) );
return std::string( pszPath );
#else
VA_EXCEPT2( NOT_IMPLEMENTED, "This function is not implemented for your platform. Sorry." );
return "";
#endif // WIN32
}
CVACoreImpl::CVACoreImpl( const CVAStruct& oArgs, std::ostream* pOutputStream )
: m_pAudioDriverBackend( nullptr )
, m_pGlobalSamplePool( nullptr )
, m_pGlobalSampler( nullptr )
, m_pSignalSourceManager( nullptr )
, m_pDirectivityManager( nullptr )
, m_pSceneManager( nullptr )
, m_pNewSceneState( nullptr )
, m_iCurActiveSoundReceiver( -1 )
, m_iNewActiveSoundReceiver( -1 )
, m_iUpdActiveSoundReceiver( -1 )
, m_pEventManager( nullptr )
, m_pCoreThread( nullptr )
, m_pInputAmp( nullptr )
, m_pR2RPatchbay( nullptr )
, m_pOutputPatchbay( nullptr )
, m_pInputStreamDetector( nullptr )
, m_pOutputStreamDetector( nullptr )
, m_pOutputTracker( nullptr )
, m_pStreamProbeDeviceInput( nullptr )
, m_pStreamProbeDeviceOutput( nullptr )
, m_pCurSceneState( nullptr )
, m_pClock( ITAClock::getDefaultClock() )
, m_pTicker( NULL )
, m_lSyncModOwner( -1 )
, m_lSyncModSpinCount( 0 )
, m_iState( VA_CORESTATE_CREATED )
, m_iGlobalAuralizationMode( IVAInterface::VA_AURAMODE_ALL )
, m_dOutputGain( 1 )
, m_dInputGain( 1 )
, m_bOutputMuted( false )
, m_bInputMuted( false )
, m_dStreamClockOffset( 0 )
, m_fCoreClockOffset( 0 )
, m_oCoreThreadLoopTotalDuration( "Core thread loop" )
{
VA_NO_REENTRANCE;
if( pOutputStream )
SetOutputStream( pOutputStream );
VA_TRY
{
// read configuration
m_oCoreConfig.Init( oArgs );
// register core itself as a module
SetObjectName( "VACore" );
m_oModules.RegisterObject( this );
VA_VERBOSE( "Core", "Registered core module with name '" << GetObjectName() << "'" );
// Der Event-Manager muss immer verfgbar sein,
// unabhnging davon ob der Core initialisiert wurde oder nicht.
m_pEventManager = new CVACoreEventManager;
m_iState = VA_CORESTATE_CREATED;
VA_TRACE( "Core", "CVACoreImpl instance created [" << this << "]" );
}
VA_RETHROW;
}
CVACoreImpl::~CVACoreImpl()
{
VA_NO_REENTRANCE;
// Implizit finalisieren, falls dies nicht durch den Benutzer geschah
if( m_iState == VA_CORESTATE_READY )
{
VA_TRY
{
Finalize();
}
VA_FINALLY
{
// Fehler beim Finalisieren ignorieren
};
}
// Nachricht senden [blocking], das die Kerninstanz gelscht wird.
CVAEvent ev;
ev.iEventType = CVAEvent::DESTROY;
ev.pSender = this;
m_pEventManager->BroadcastEvent( ev );
// Module deregistrieren
m_oModules.Clear();
// Nachrichten-Manager freigeben
VA_TRY
{
delete m_pEventManager;
}
VA_RETHROW;
VA_TRACE( "Core", "CVACoreImpl instance deleted [" << this << "]" );
// Profiling ausgeben
VA_VERBOSE( "Core", m_oCoreThreadLoopTotalDuration.ToString() );
}
void CVACoreImpl::SetOutputStream( std::ostream* posDebug )
{
VALog_setOutputStream( posDebug );
VALog_setErrorStream( posDebug );
}
void CVACoreImpl::GetVersionInfo( CVAVersionInfo* pVersionInfo ) const
{
if( !pVersionInfo )
return;
std::stringstream ss;
ss << VACORE_VERSION_MAJOR << "." << VACORE_VERSION_MINOR;
pVersionInfo->sVersion = ss.str();
ss.clear();
#ifdef VACORE_CMAKE_DATE
ss << VACORE_CMAKE_DATE;
#else
ss << "Unkown date";
#endif
pVersionInfo->sDate = ss.str();
pVersionInfo->sFlags = "";
#ifdef DEBUG
pVersionInfo->sComments = "debug";
#else
pVersionInfo->sComments = "release";
#endif
}
void CVACoreImpl::AttachEventHandler( IVAEventHandler* pCoreEventHandler )
{
VA_TRY
{
// Immer mglich. Unabhngig vom Zustand. Thread-safety wird im Manager geregelt.
m_pEventManager->AttachHandler( pCoreEventHandler );
}
VA_RETHROW;
}
void CVACoreImpl::DetachEventHandler( IVAEventHandler* pCoreEventHandler )
{
VA_TRY
{
// Immer mglich. Unabhngig vom Zustand. Thread-safety wird im Manager geregelt.
m_pEventManager->DetachHandler( pCoreEventHandler );
}
VA_RETHROW;
}
int CVACoreImpl::GetState() const
void CVACoreImpl::Initialize()
{
VA_VERBOSE( "Core", "Core state requested, current state is " << m_iState );
return m_iState;
}
void CVACoreImpl::Initialize() {
VA_NO_REENTRANCE;
// TODO: Prfen ob im Fehlerfall zurck in den sauberen Grundzustand [WICHTIG!]
......@@ -466,5172 +205,3 @@ void CVACoreImpl::Initialize() {
throw;
}
}
void CVACoreImpl::Reset()
{
VA_CHECK_INITIALIZED;
// Wait for core thread
while( !m_pCoreThread->TryBreak() )
VASleep( 20 );
VA_NO_REENTRANCE;
if( GetUpdateLocked() )
{
VA_WARN( "Core", "Encountered locked scene during reset. Please unlock before resetting, skipping." );
m_pCoreThread->Continue();
}
VA_TRY
{
VA_INFO( "Core", "Resetting core" );
// Reset audio renderers
std::vector< CVAAudioRendererDesc >::iterator it = m_voRenderers.begin();
while( it != m_voRenderers.end() )
{
CVAAudioRendererDesc& oRend( *it++ );
oRend.pInstance->Reset();
}
if( m_pCurSceneState )
{
// Referenz entfernen welche in CoreThreadLoop hinzugefgt wurde
m_pCurSceneState->RemoveReference();
m_pCurSceneState = nullptr;
}
// Alle Szenenobjekte lschen
m_pSceneManager->Reset();
m_pSignalSourceManager->Reset();
m_pDirectivityManager->Reset();
// TODO: Check if the pool and sampler must really be recreated
/*
delete m_pGlobalSamplePool;
m_pGlobalSamplePool = nullptr;
m_pGlobalSamplePool = ITASoundSamplePool::Create(1, m_oCoreConfig.oAudioDriverConfig.dSamplerate);
// This causes a crash in patch bay
delete m_pGlobalSampler;
m_pGlobalSampler = nullptr;
m_pGlobalSampler = ITASoundSampler::Create(1, m_oCoreConfig.oAudioDriverConfig.dSamplerate, m_oCoreConfig.oAudioDriverConfig.iBuffersize, m_pGlobalSamplePool);
m_pGlobalSampler->AddMonoTrack();
*/
//m_pGlobalSampler->RemoveAllPlaybacks();
// Werte neusetzen
m_pCurSceneState = m_pSceneManager->GetHeadSceneState();
m_iCurActiveSoundReceiver = -1;
m_iNewActiveSoundReceiver = -1;
m_pCoreThread;
// Core-Thread fortsetzen
m_pCoreThread->Continue();
// Ereignis generieren, wenn Operation erfolgreich
CVAEvent ev;
ev.iEventType = CVAEvent::RESET;
ev.pSender = this;
m_pEventManager->BroadcastEvent( ev );
}
VA_FINALLY
{
Tidyup();
throw;
}
}
void CVACoreImpl::Tidyup() {
/*
* Hinweis: Diese Hilfsmethode wird nur innerhalb des Reentrance-Locks
* aufgerufen - daher keine weiter Absicherung ntig.
*/
VA_TRY
{
if( m_pTicker )
{
m_pTicker->StopTicker();
m_pTicker->SetAfterPulseFunctor( NULL );
}
FinalizeAudioDriver();
FinalizeRenderingModules();
FinalizeReproductionModules();
delete m_pTicker;
m_pTicker = nullptr;
delete m_pCoreThread;
m_pCoreThread = nullptr;
delete m_pInputAmp;
m_pInputAmp = nullptr;
delete m_pInputStreamDetector;
m_pInputStreamDetector = nullptr;
delete m_pR2RPatchbay;
m_pR2RPatchbay = nullptr;
delete m_pOutputPatchbay;
m_pOutputPatchbay = nullptr;
delete m_pOutputStreamDetector;
m_pOutputStreamDetector = nullptr;
delete m_pOutputTracker;
m_pOutputTracker = nullptr;
delete m_pStreamProbeDeviceInput;
m_pStreamProbeDeviceInput = nullptr;
delete m_pStreamProbeDeviceOutput;
m_pStreamProbeDeviceOutput = nullptr;
delete m_pSignalSourceManager;
m_pSignalSourceManager = nullptr;
delete m_pGlobalSampler;
m_pGlobalSampler = nullptr;
delete m_pGlobalSamplePool;
m_pGlobalSamplePool = nullptr;
if( m_pDirectivityManager )
m_pDirectivityManager->Finalize();
delete m_pDirectivityManager;
m_pDirectivityManager = nullptr;
if( m_pSceneManager )
m_pSceneManager->Finalize();
delete m_pSceneManager;
m_pSceneManager = nullptr;