Commit 44f3c8e7 authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen
Browse files

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

parents 81159fb8 b31a24e1
conf/VACore.ini
conf/VACore.experimental.ini
HTML
*.bat
*.mat
......
......@@ -316,6 +316,7 @@ add_definitions( "-DVACORE_CMAKE_DATE=\"${VACORE_CMAKE_DATE}\"" )
if( ITA_VACORE_WITH_TTS_SIGNAL_SOURCE )
vista_use_package( CereVoice REQUIRED FIND_DEPENDENCIES)
vista_use_package( samplerate REQUIRED FIND_DEPENDENCIES)
if( VCEREVOICE_FOUND )
add_definitions( "-DVACORE_WITH_TTS_SIGNAL_SOURCE" )
endif( )
......@@ -370,3 +371,10 @@ if( ITA_VA_WITH_TESTS OR ITA_VACORE_WITH_TESTS )
set( VACORE_COMMON_BUILD TRUE )
add_subdirectory( "${CMAKE_CURRENT_SOURCE_DIR}/tests" )
endif( )
# benchmarks
if( ITA_VA_WITH_BENCHMARKS OR ITA_VACORE_WITH_BENCHMARKS )
set( VACORE_COMMON_BUILD TRUE )
add_subdirectory( "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks" )
endif( )
cmake_minimum_required( VERSION 2.8 )
project( VACoreBenchmarks )
add_subdirectory( "core" )
cmake_minimum_required( VERSION 2.8 )
project( VACoreBenchmarks )
list( APPEND CMAKE_MODULE_PATH "$ENV{VISTA_CMAKE_COMMON}" )
include( VistaCommon )
vista_use_package( VistaCoreLibs REQUIRED COMPONENTS VistaBase )
vista_use_package( VACore REQUIRED FIND_DEPENDENCIES )
add_executable( VACoreSourceManagementBenchmark VACoreSourceManagementBenchmark.cpp )
target_link_libraries( VACoreSourceManagementBenchmark ${VISTA_USE_PACKAGE_LIBRARIES} )
vista_configure_app( VACoreSourceManagementBenchmark )
vista_install( VACoreSourceManagementBenchmark )
vista_create_default_info_file( VACoreSourceManagementBenchmark )
set_property( TARGET VACoreSourceManagementBenchmark PROPERTY FOLDER "VA/Benchmarks/VACore" )
#include <VACore.h>
#include <VACoreEvent.h>
#include <VACoreFactory.h>
#include <VACoreVersion.h>
#include <VAException.h>
#include <iostream>
#include <vector>
#include <VistaBase/VistaTimeUtils.h>
#include <ITAStopWatch.h>
using namespace std;
int main( int, char** )
{
IVACore* pCore = NULL;
try
{
CVAStruct oConfig;
CVAStruct oSectionDebug;
oSectionDebug[ "loglevel" ] = 1;
oConfig[ "debug" ] = oSectionDebug;
CVAStruct oSectionDriver;
oSectionDriver[ "driver" ] = "Portaudio";
oConfig[ "audio driver" ] = oSectionDriver;
CVAStruct oDevice1;
oDevice1[ "type" ] = "HP";
oDevice1[ "channels" ] = "1,2";
oConfig[ "OutputDevice:MyHP" ] = oDevice1;
CVAStruct oOutput1;
oOutput1[ "devices" ] = "MyHP";
oConfig[ "Output:MyDesktopHP" ] = oOutput1;
CVAStruct oReproduction;
oReproduction[ "class" ] = "Talkthrough";
oReproduction[ "outputs" ] = "MyDesktopHP";
oConfig[ "Reproduction:MyTalkthroughHeadphones" ] = oReproduction;
CVAStruct oRenderer;
oRenderer[ "class" ] = "PrototypeDummy";
oRenderer[ "outputs" ] = "MyTalkthroughHeadphones";
oRenderer[ "outputgroup" ] = "MyDesktopHP";
oConfig[ "Renderer:BenchmarkDummyRenderer" ] = oRenderer;
pCore = VACore::CreateCoreInstance( oConfig );
pCore->Initialize();
int iIterations = 100;
int iMaxNumParallelSources = 200;
for( int i = 1; i < iMaxNumParallelSources; i++ )
{
ITAStopWatch swIterations;
for( int j = 0; j < iIterations; j++ )
{
swIterations.start();
std::vector< int > viSourceIDs( i );
for( int k = 0; k < i; k++ )
viSourceIDs[ k ] = pCore->CreateSoundSource( "BenchmarkSoundSource" );
for( int k = 0; k < i; k++ )
pCore->DeleteSoundSource( viSourceIDs[ k ] );
swIterations.stop();
}
cout << "Statistics for " << i << " parallel source: " << swIterations.ToString() << endl;
}
delete pCore;
}
catch( CVAException& e )
{
delete pCore;
cerr << "Error with core " << e.GetErrorCode() << ": " << e << endl;
return 255;
}
return 0;
}
......@@ -39,6 +39,9 @@ big_data_dir = @ITA_VACORE_BIG_DATA_DIR@
# Inside scene data directory
InsideSceneData = @INSIDE_SCENE_DATA@
# Path for TTS Voices of CereVoice
voices_dir = data/Voices
[Files]
......
......@@ -30,7 +30,7 @@ Devices = LS_BF, LS_BR, LS_BB, LS_BL
[Output:VRLAB_LS_SUBWOOFER]
Description = ITA VRLab subwoofer loudspeaker setup
Enabled = false
Enabled = true
Devices = LS_SUB
[Output:VRLAB_HP_MAIN]
......
/*
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institut fr Technische Akustik (ITA)
* VVVV AAA RWTH Aachen (http://www.akustik.rwth-aachen.de)
*
* ---------------------------------------------------------------------------------
*
* Datei: VACoreDumper.h
*
* Zweck: Dumper-Klasse welche VACore-Calls als Strings ausgibt
*
* Autor(en): Frank Wefers (Frank.Wefers@akustik.rwth-aachen.de
*
* ---------------------------------------------------------------------------------
*/
// $Id: VACoreDumper.h 2729 2012-06-26 13:23:36Z fwefers $
#ifndef __VACORE_DUMPER_H__
#define __VACORE_DUMPER_H__
#include <VACoreDefinitions.h>
#include <VACore.h>
#include <iostream>
#include <string>
//! Dumper-Klasse welche Aufrufe und Ereignisse als Strings auf einem Stream ausgibt
class VACORE_API CVACoreDumper : public IVACore {
public:
CVACoreDumper(IVACore* pTarget=NULL, std::ostream* pOutputStream=&std::cout);
virtual ~CVACoreDumper();
//! Zielinstanz des Dumpers zurckgeben
IVACore* getCoreInstance() const;
//! Zielinstanz des Dumpers zurckgeben
void setCoreInstance(IVACore* pTarget);
//! Ausgabestream fr das Dump zurckgeben
std::ostream* getOutputStream() const;
//! Ausgabestream fr das Dump setzen
void setOutputStream(std::ostream* pOutputStream) const;
// --= Interface "IVACore" =--
private:
IVACore* m_pTarget;
std::ostream* m_pStream;
};
#endif // __VACORE_DUMPER_H__
......@@ -16,7 +16,6 @@
#include <VACoreDefinitions.h>
#include <VAReferenceableObject.h>
#include <VAUncopyable.h>
#include <string>
......@@ -120,95 +119,4 @@ protected:
friend class CVAPoolObject;
};
//! Pool objects base class
/**
* Pool objects are referencable and linked to a superior pool. The
* reference counter holds information on number of usages/links of
* the specific object. In case the reference counter states that
* no connections to the given object are available, it is marked
* for new usage (recycling). The object releases itself to
* the pool if no references are existent.
*/
class VACORE_API CVAPoolObject : public IVAUncopyable, public CVAReferenceableObject
{
public:
//! Redefined method to remove reference
/**
* Releases object to the pool if no reference available anymore
*/
virtual int RemoveReference() const;
protected:
//! Protected constructor [Jonas fragt Frank: so richtig?! (hinzugefgt, damit m_pParentPool auf nullptr gesetzt werden kann]
/**
* Can only be called by CVAObjectPool(), protected for users
*/
CVAPoolObject();
//! Protected destructor
/**
* Can only be called by CVAObjectPool(), protected for users
*/
virtual ~CVAPoolObject();
//! Pre request method
/**
* The PreRequest method is called before the object is used
*/
virtual void PreRequest() {};
//! Pre release method
/**
* The PreRelease method is called after the object has been released
*/
virtual void PreRelease() {};
private:
IVAObjectPool* m_pParentPool; //!< Pointer to the pool
friend class CVAObjectPool;
friend class CVALockfreeObjectPool;
};
//! Pool object factory interface
/**
* Interface for the creation of a pool object (factory method)
*/
class VACORE_API IVAPoolObjectFactory
{
public:
inline virtual ~IVAPoolObjectFactory() {};
//! Factory method (abstract)
/**
* Interface method to create a new pool object
*
* \return Pointer to the new pool object
*/
virtual CVAPoolObject* CreatePoolObject() = 0;
};
//! Default factory for pool objects with standard constructor
/**
* Pool object factory for objects using the default constructor
*/
template< class T > class CVAPoolObjectDefaultFactory : public IVAPoolObjectFactory
{
public:
//! Factory method
/**
* Creates new pool object using the standard constructor of the template object
*
* \return Pointer to the new pool object
*/
inline virtual CVAPoolObject* CreatePoolObject()
{
return new T;
}
};
#endif // IW_VACORE_OBJECT_POOL
\ No newline at end of file
/*
* --------------------------------------------------------------------------------------------
*
* VVV VVV A
* VVV VVV AAA Virtual Acoustics (VA)
* VVV VVV AAA Real-time auralisation for virtual reality
* VVV VVV AAA
* VVVVVV AAA (c) Copyright Institute of Technical Acoustics (ITA), 2015-2017
* VVVV AAA RWTH Aachen University (http://www.akustik.rwth-aachen.de)
*
* --------------------------------------------------------------------------------------------
*/
#ifndef IW_VA_POOL_OBJECT
#define IW_VA_POOL_OBJECT
#include <VACoreDefinitions.h>
#include <VAReferenceableObject.h>
#include <VAUncopyable.h>
class IVAObjectPool;
//! Pool objects base class
/**
* Pool objects are referencable and linked to a superior pool. The
* reference counter holds information on number of usages/links of
* the specific object. In case the reference counter states that
* no connections to the given object are available, it is marked
* for new usage (recycling). The object releases itself to
* the pool if no references are existent.
*/
class VACORE_API CVAPoolObject : public IVAUncopyable, public CVAReferenceableObject
{
public:
//! Redefined method to remove reference
/**
* Releases object to the pool if no reference available anymore
*/
virtual int RemoveReference() const;
protected:
//! Protected constructor [Jonas fragt Frank: so richtig?! (hinzugefgt, damit m_pParentPool auf nullptr gesetzt werden kann]
/**
* Can only be called by CVAObjectPool(), protected for users
*/
CVAPoolObject();
//! Protected destructor
/**
* Can only be called by CVAObjectPool(), protected for users
*/
virtual ~CVAPoolObject();
//! Pre request method
/**
* The PreRequest method is called before the object is used
*/
virtual inline void PreRequest() {};
//! Pre release method
/**
* The PreRelease method is called after the object has been released
*/
virtual inline void PreRelease() {};
private:
IVAObjectPool* m_pParentPool; //!< Pointer to the pool
friend class CVAObjectPool;
friend class CVALockfreeObjectPool;
};
//! Pool object factory interface
/**
* Interface for the creation of a pool object (factory method)
*/
class VACORE_API IVAPoolObjectFactory
{
public:
inline virtual ~IVAPoolObjectFactory() {};
//! Factory method (abstract)
/**
* Interface method to create a new pool object
*
* \return Pointer to the new pool object
*/
virtual CVAPoolObject* CreatePoolObject() = 0;
};
//! Default factory for pool objects with standard constructor
/**
* Pool object factory for objects using the default constructor
*/
template< class T > class CVAPoolObjectDefaultFactory : public IVAPoolObjectFactory
{
public:
//! Factory method
/**
* Creates new pool object using the standard constructor of the template object
*
* \return Pointer to the new pool object
*/
inline virtual CVAPoolObject* CreatePoolObject()
{
return new T;
}
};
#endif // IW_VA_POOL_OBJECT
......@@ -5,10 +5,10 @@ set( RelativeSourceGroup "include" )
set( DirFiles
VACoreDefinitions.h
#VACoreDumper.h
VACoreFactory.h
VANetworkStreamAudioSignalSource.h
VAObjectPool.h
VAPoolObject.h
VAReferenceableObject.h
VAUncopyable.h
_SourceFiles.cmake
......
......@@ -7,6 +7,7 @@
#include <ITAException.h>
#include <ITABufferDataSource.h>
#include <ITASampleFrame.h>
#include <ITAAudioSample.h>
#include <sstream>
#include <assert.h>
......@@ -43,7 +44,8 @@ CVAAudiofileSignalSource::CVAAudiofileSignalSource( const std::string& sFileName
{
m_sbOutBuffer.Init( iBlockLength, true );
ITASampleFrame sfFileBuffer( sFileName );
CITAAudioSample sfFileBuffer(dSampleRate);
sfFileBuffer.LoadWithSampleRateConversion(sFileName);
std::vector< float* > vfBufferPointer;
......
......@@ -18,11 +18,15 @@
#include <iomanip>
#include <VistaTools/VistaFileSystemDirectory.h>
#include <VistaTools/VistaFileSystemFile.h>
#ifdef VACORE_WITH_TTS_SIGNAL_SOURCE
#include <cerevoice_eng.h>
#endif
//#define TTS_USE_WAV
CVATextToSpeechSignalSource::CVATextToSpeechSignalSource( const double dSampleRate, const int iBlockLength )
: ITADatasourceRealization(1, dSampleRate, (unsigned int)(iBlockLength))
......@@ -79,7 +83,7 @@ const float* CVATextToSpeechSignalSource::GetStreamBlock( const CVAAudiostreamSt
delete m_pFrameToDelete;
m_pFrameToDelete = NULL;
}
VA_INFO("CVATextToSpeechSignalSource", "TTS to VA_PLAYBACK_ACTION_STOP");
//VA_INFO("CVATextToSpeechSignalSource", "TTS to VA_PLAYBACK_ACTION_STOP");
}
}
......@@ -94,7 +98,6 @@ const float* CVATextToSpeechSignalSource::GetStreamBlock( const CVAAudiostreamSt
// return pAudioFile->GetStreamBlock(pStreamInfo);
}
// @todo: take samples from generated WAV file
return m_sbOut.data();
}
......@@ -102,6 +105,11 @@ const float* CVATextToSpeechSignalSource::GetStreamBlock( const CVAAudiostreamSt
void CVATextToSpeechSignalSource::HandleRegistration( IVACore* pCore )
{
m_pAssociatedCore = pCore;
std::string voices_dir = pCore->SubstituteMacros("$(voices_dir)");
if (voices_dir != "$(voices_dir)")
TTSEngine::getInstance().SetAdditionalVoicePath(voices_dir);
if (TTSEngine::getInstance().getEngine() == NULL)
TTSEngine::getInstance().Init();
}
void CVATextToSpeechSignalSource::HandleUnregistration( IVACore* )
......@@ -158,14 +166,16 @@ CVAStruct CVATextToSpeechSignalSource::GetParameters( const CVAStruct& oArgs ) c
int num_voices = CPRCEN_engine_get_voice_count(TTSEngine::getInstance().getEngine());
oRet["number"] = num_voices;
for (int i = 0; i < num_voices; i++) {
CVAStruct oVoice;
std::string voicename = CPRCEN_engine_get_voice_info(TTSEngine::getInstance().getEngine(), i, "VOICE_NAME");
oRet["voice_" + std::to_string(i)] = voicename;
oVoice["name"] = voicename;
std::string language = CPRCEN_engine_get_voice_info(TTSEngine::getInstance().getEngine(), i, "LANGUAGE_CODE_ISO");
oRet["language_" + std::to_string(i)] = language;
oVoice["language"] = language;
std::string country = CPRCEN_engine_get_voice_info(TTSEngine::getInstance().getEngine(), i, "COUNTRY_CODE_ISO");
oRet["country_" + std::to_string(i)] = country;
oVoice["country"] = country;
std::string sex = CPRCEN_engine_get_voice_info(TTSEngine::getInstance().getEngine(), i, "SEX");
oRet["sex_" + std::to_string(i)] = sex;
oVoice["sex"] = sex;
oRet[std::to_string(i)] = oVoice;
}
return oRet;
}
......@@ -209,14 +219,14 @@ void CVATextToSpeechSignalSource::SetParameters( const CVAStruct& oParams )
if (oParams.HasKey("voice") && oParams["voice"].IsString())
sVoice = oParams["voice"];
bool direct_replay = false;
if (oParams.HasKey("direct_replay") && oParams["direct_replay"].IsBool() && oParams["direct_replay"]){
direct_replay = true;
bool direct_playback = false;
if (oParams.HasKey("direct_playback") && oParams["direct_playback"].IsBool() && oParams["direct_playback"]){
direct_playback = true;
}
std::string id = "tmp";
if (!oParams.HasKey("id") || !oParams["id"].IsString()){
if (!direct_replay){
if (!direct_playback){
VA_WARN("CVATextToSpeechSignalSource", "No id is given for the prepare speech request, the user application has to give an unique id.");
return;
}
......@@ -242,23 +252,40 @@ void CVATextToSpeechSignalSource::SetParameters( const CVAStruct& oParams )
CPRCEN_engine_channel_reset(TTSEngine::getInstance().getEngine(), chan);
CPRCEN_engine_clear_callback(TTSEngine::getInstance().getEngine(), chan);
CPRCEN_engine_set_callback(TTSEngine::getInstance().getEngine(), chan, (void*)&data, VisemeProcessing);
//CPRCEN_engine_channel_to_file(TTSEngine::getInstance().getEngine(), chan, "D:/work/tts.wav", CPRCEN_RIFF); /* File output on channel */
#ifdef TTS_USE_WAV
CPRCEN_engine_channel_to_file(TTSEngine::getInstance().getEngine(), chan, "D:/work/tts.wav", CPRCEN_RIFF); /* File output on channel */
#endif
CPRC_abuf* buf = CPRCEN_engine_channel_speak(TTSEngine::getInstance().getEngine(), chan, sText.c_str(), sText.length(), true);
int sRate = CPRC_abuf_wav_srate(buf);
std::cout << "CereVoice rate is: " << sRate << " while sound signal rate is: " << GetSampleRate() << std::endl;
if (buf == NULL){
VA_WARN("CVATextToSpeechSignalSource", "Cannot create an audio file, probably no voice is available!");
return;
}
data.visemes += "</speech>\n";
data.visemes += "<event id=\"" + id + "\" start=\"0\" message=\"speech started\" />";
//data.visemes += "<event id=\"" + id + "\" start=\"0\" message=\"speech started\" />";
m_Visemes[id] = data.visemes;
#ifdef TTS_USE_WAV
ITASampleFrame* pAudioBuffer = new ITASampleFrame("D:/work/tts.wav");
CITAAudioSample* pAudioSample = new CITAAudioSample();
//pAudioSample->Load(*pAudioBuffer, 44100.0f);
pAudioSample->Load(*pAudioBuffer, TTSEngine::getInstance().getSampleRate());
m_AudioSampleFrames[id] = pAudioSample;
#else
ITASampleFrame* pAudioBuffer = new ITASampleFrame();
pAudioBuffer->init(1, data.floatBuffer.size(), false);
(*pAudioBuffer)[0].write(&data.floatBuffer[0], data.floatBuffer.size());
m_AudioSampleFrames[id] = pAudioBuffer;
pAudioBuffer->mul_scalar(0.95); //this way clipping is avoided
if (direct_replay){
CITAAudioSample* pAudioSample = new CITAAudioSample();
pAudioSample->Load(*pAudioBuffer, TTSEngine::getInstance().getSampleRate());
m_AudioSampleFrames[id] = pAudioSample;
#endif
if (direct_playback){
CVAStruct oParams_play;
oParams_play["play_speech"] = id;
oParams_play["free_after"] = true;
......@@ -305,6 +332,8 @@ void CVATextToSpeechSignalSource::SetParameters( const CVAStruct& oParams )
ITASampleFrame* pAudioBuffer = it->second;
if (m_pBufferDataSource != NULL)
delete m_pBufferDataSource;
m_pBufferDataSource = new ITABufferDatasource((*pAudioBuffer)[0].data(), pAudioBuffer->length(), GetSampleRate(), GetBlocklength());
......@@ -320,6 +349,7 @@ void CVATextToSpeechSignalSource::SetParameters( const CVAStruct& oParams )
m_Visemes[id] = "";
}
VA_INFO("CVATextToSpeechSignalSource", "Play TTS for id: \"" + id + "\"");
return;
}
......@@ -390,7 +420,7 @@ void CVATextToSpeechSignalSource::VisemeProcessing(CPRC_abuf * abuf, void * user
VA_INFO("CVATextToSpeechSignalSource", "ERROR: could not retrieve transcription at "+ std::to_string(i));
}
}
data->lastEnd = endTime;
data->lastEnd += endTime;
//we basically append the data in abuf to the data in floatBuffer and on the way convert it from short to float (since that's what we need for the SoundSignal)
std::size_t bufferLength = CPRC_abuf_wav_sz(abuf);
......@@ -401,29 +431,62 @@ void CVATextToSpeechSignalSource::VisemeProcessing(CPRC_abuf * abuf, void * user