/* * ---------------------------------------------------------------- * * ITA core libs * (c) Copyright Institute of Technical Acoustics (ITA) * RWTH Aachen University, Germany, 2015-2024 * * ---------------------------------------------------------------- * ____ __________ _______ * // / //__ ___/ // _ | * // / // / // /_| | * // / // / // ___ | * //__/ //__/ //__/ |__| * * ---------------------------------------------------------------- * * Benchmark uniform partitioned convolution * */ #include <ITAAudiofileWriter.h> #include <ITAConfigUtils.h> #include <ITAFileDataSource.h> #include <ITASampleBuffer.h> #include <ITASampleFrame.h> #include <ITAStopWatch.h> #include <ITAStreamFunctionGenerator.h> #include <ITAStreamInfo.h> #include <ITAStringUtils.h> #include <ITAUPConvolution.h> #include <ITAUPFilter.h> #include <iostream> #include <math.h> #include <stdio.h> #include <vector> using namespace std; ITASampleBuffer* pbfImpulse; struct ParameterSet { unsigned int iBlockLength; double dSampleRate; string sWAVOutFilePath; unsigned long iNumFrames; int iFilterLength; int iScalingApproximation; inline void SetSomeDefaults( ) { dSampleRate = 44.1e3; #ifdef DEBUG iNumFrames = 1000; #else iNumFrames = 1e2; #endif iScalingApproximation = 64; }; inline void WriteToINIFile( ) const { INIFileWriteInt( "BlockLength", iBlockLength ); INIFileWriteDouble( "SampleRate", dSampleRate ); INIFileWriteInt( "FilterLength", iFilterLength ); INIFileWriteInt( "NumFrames", iNumFrames ); INIFileWriteString( "WAVOutFilePath", sWAVOutFilePath ); INIFileWriteDouble( "BlockTimeSeconds", iBlockLength / dSampleRate ); INIFileWriteString( "BlockTime", timeToString( iBlockLength / dSampleRate ) ); INIFileWriteInt( "ScalingApproximation", iScalingApproximation ); }; }; void run_benchmark( const ParameterSet&, const std::string& ); int main( int, char** ) { pbfImpulse = new ITASampleBuffer( int( 1000 * 44.1e3 ), true ); srand( 100 ); int iLength = pbfImpulse->GetLength( ); for( unsigned int i = 0; i < iLength; i++ ) pbfImpulse->GetData( )[i] = (float)rand( ) / RAND_MAX; cout << "Starting uniformly partitioned block convolution benchmark" << endl; INIFileUseFile( "ITAConvolution_BM_UPConv.ini" ); ParameterSet pm; pm.SetSomeDefaults( ); for( auto BL: { 32, 64, 128, 256 } ) { for( auto BM: { 1, 2, 4, 8, 16 } ) { stringstream ss; ss << "ITAConvolution_BM_NUPConv_L" << BL << "_M" << BL * BM; string sBMID = ss.str( ); pm.iBlockLength = BL; pm.iFilterLength = BL * BM; pm.sWAVOutFilePath = sBMID + ".wav"; cout << "\tStarting " << sBMID << " "; // run_benchmark( pm, sBMID ); cout << "\tdone." << endl; } } INIFileUseFile( "ITAConvolution_BM_UPConv_ScalingBehavior.ini" ); for( auto BL: { 256 } ) { for( auto BM: { 1, 2, 4, 8, 16, 32, 64, 128, 512, 1024, 2048, 4096, 8182 } ) { stringstream ss; ss << "ITAConvolution_BM_NUPConv_ScalingBehavior_L" << BL << "_M" << BL * BM; string sBMID = ss.str( ); pm.iBlockLength = BL; pm.iFilterLength = BL * BM; pm.sWAVOutFilePath = sBMID + ".wav"; cout << "\tStarting " << sBMID << " "; run_benchmark( pm, sBMID ); cout << "\tdone." << endl; } } cout << "All done." << endl; return 255; } void run_benchmark( const ParameterSet& pm, const std::string& sName ) { INIFileUseSection( sName ); pm.WriteToINIFile( ); ITAStreamFunctionGenerator sinesignal( 1, pm.dSampleRate, pm.iBlockLength, ITAStreamFunctionGenerator::SINE, 500.0f, 0.9f, true ); ITADatasource* pIntputStream = &sinesignal; ITAUPConvolution* pFIRFilterEnginge = new ITAUPConvolution( pm.iBlockLength, pm.iFilterLength ); ITAUPFilter* pFIRFilter = pFIRFilterEnginge->RequestFilter( ); ; pFIRFilter->Load( pbfImpulse->GetData( ), std::min( pbfImpulse->GetLength( ), pm.iFilterLength ) ); pFIRFilterEnginge->ExchangeFilter( pFIRFilter ); pFIRFilter->Release( ); ITAAudiofileProperties props_out; props_out.iChannels = 1; props_out.dSampleRate = pm.dSampleRate; props_out.eQuantization = ITAQuantization::ITA_FLOAT; props_out.eDomain = ITADomain::ITA_TIME_DOMAIN; props_out.iLength = pm.iNumFrames * (unsigned int)( pm.iBlockLength ); props_out.iChannels = 1; ITAAudiofileWriter* writer_out = ITAAudiofileWriter::create( pm.sWAVOutFilePath, props_out ); ITAStreamInfo oState; ITASampleBuffer* psbInput = new ITASampleBuffer( pm.iBlockLength, true ); ITASampleFrame sfTemp( 1, pm.iBlockLength, true ); ITAStopWatch swBenchmark; long unsigned int n = 0; while( n < int( pm.iNumFrames ) ) { // Add new samples psbInput->write( pIntputStream->GetBlockPointer( 0, &oState ), pm.iBlockLength ); swBenchmark.start( ); pFIRFilterEnginge->Process( psbInput->GetData( ), sfTemp[0].GetData( ) ); swBenchmark.stop( ); INIFileWriteDouble( "ComputationMean", swBenchmark.mean( ) ); INIFileWriteDouble( "ComputationStdDev", swBenchmark.std_deviation( ) ); INIFileWriteDouble( "ComputationMinimum", swBenchmark.minimum( ) ); INIFileWriteDouble( "ComputationMaximum", swBenchmark.maximum( ) ); INIFileWriteDouble( "ComputationScalingApproximation", swBenchmark.mean( ) * pm.iScalingApproximation ); writer_out->write( &sfTemp, sfTemp.GetLength( ) ); n++; pIntputStream->IncrementBlockPointer( ); if( n % ( pm.iNumFrames / 10 ) == 0 ) cout << "."; } delete writer_out; delete psbInput; }