Fixing samplerate conversion test and added some more useful methods for CITAAudioSample

parent 9d390cf2
......@@ -37,6 +37,12 @@ public:
* Requires initialization or load to be used, otherwise methods will throw ITAException.
*/
CITAAudioSample( const float fSampleRate = 44100.0f );
//! Create audio sample from file
/**
* Requires initialization or load to be used, otherwise methods will throw ITAException.
*/
CITAAudioSample( const std::string& sFilePath );
//! Create (empty) audio sample with given parameters
/**
......@@ -87,6 +93,9 @@ public:
//! Load audio sample from file and convert sample rate, if necessary
void LoadWithSampleTypeConversion( const std::string& sFilePath );
//! Load audio sample from file and convert sample rate, if necessary
void LoadWithSampleTypeConversion( const CITAAudioSample& asSource );
private:
//! Disable this Init method from sample buffer
......
#include <ITAAudioSample.h>
#include <ITAException.h>
#include <cassert>
#include <samplerate.h>
CITAAudioSample::CITAAudioSample( const float fSampleRate )
......@@ -26,6 +27,12 @@ CITAAudioSample::CITAAudioSample( const CITAAudioSample& sfSource )
ITASampleFrame::write( sfSource, sfSource.GetLength() );
}
CITAAudioSample::CITAAudioSample( const std::string& sFilePath )
:CITAAudioSample()
{
Load( sFilePath );
}
void CITAAudioSample::Init( const int iNumChannels, const int iLength, const float fSampleRate, const bool bZeroInit /*= true */ )
{
m_fSampleRate = fSampleRate;
......@@ -45,12 +52,25 @@ void CITAAudioSample::LoadWithSampleTypeConversion( const std::string& sFilePath
Load( sfRaw, GetSampleRate() );
}
void CITAAudioSample::LoadWithSampleTypeConversion( const CITAAudioSample& asSource )
{
ITASampleFrame* psfSource = ( ITASampleFrame* ) &asSource;
Load( *psfSource, asSource.GetSampleRate() );
}
void CITAAudioSample::Load( const CITAAudioSample& oSource )
{
Load( oSource, oSource.GetSampleRate() );
}
void CITAAudioSample::Load( const std::string& sFilePath )
{
double dSampleRate;
ITASampleFrame::Load( sFilePath, dSampleRate );
m_fSampleRate = float( dSampleRate );
}
float CITAAudioSample::GetSampleRate() const
{
return m_fSampleRate;
......@@ -70,26 +90,33 @@ void CITAAudioSample::Load( const ITASampleFrame& sfSource, const float fSourceS
}
const float fSRCRation = GetSampleRate() / fSourceSampleRate;
const int iTargetLength = (int) ceil( sfSource.GetLength() * fSRCRation ); // @tbd test!
Init( sfSource.GetNumChannels(), iTargetLength, m_fSampleRate );
const float fTargetLengthSamples = sfSource.GetLength() * fSRCRation;
int iTargetLengthSamples = ( int ) floor( fTargetLengthSamples );
const float fTargetLengthSubsampleFraction = fTargetLengthSamples - float( iTargetLengthSamples );
// Account for exact match, then the "last" sample is not resampled anymore and can be skipped
if( fTargetLengthSubsampleFraction == 0.0f )
iTargetLengthSamples--;
Init( sfSource.GetNumChannels(), iTargetLengthSamples, m_fSampleRate );
const int iConverter = SRC_SINC_MEDIUM_QUALITY;
for( int i = 0; i < sfSource.GetNumChannels(); i++ )
{
int iSRCError;
SRC_STATE* pSRCStace = src_new( iConverter, sfSource.GetNumChannels(), &iSRCError );
SRC_STATE* pSRCStace = src_new( iConverter, 1, &iSRCError ); // single channel conversion, samplerate expets interleaved. this is not compatible with ITASampleBuffer/Frame
if( pSRCStace == nullptr )
ITA_EXCEPT_INVALID_PARAMETER( "Could not create sample rate converter, samplerate error was: " + std::string( src_strerror( iSRCError ) ) );
SRC_DATA oSRCData;
oSRCData.data_in = sfSource[ i ].GetData();
oSRCData.data_out = ( *this )[ i ].GetData();
oSRCData.input_frames = 1;
oSRCData.output_frames = 1;
oSRCData.input_frames = sfSource.GetLength(); // In samplerate, one frame is "one sample" of multi channel audio
oSRCData.output_frames = iTargetLengthSamples;
oSRCData.src_ratio = fSRCRation;
if( ( iSRCError = src_process( pSRCStace, &oSRCData ) ) != 0 )
ITA_EXCEPT_INVALID_PARAMETER( "Could not convert sample rate: " + std::string( src_strerror( iSRCError ) ) );
assert( oSRCData.output_frames_gen == iTargetLengthSamples );
src_delete( pSRCStace );
}
}
\ No newline at end of file
}
......@@ -7,6 +7,20 @@ using namespace std;
int main( int, char** )
{
try
{
CITAAudioSample asTTS48kHz( "tts.wav" );
CITAAudioSample asTTS44kHz;
asTTS44kHz.LoadWithSampleTypeConversion( asTTS48kHz );
asTTS44kHz.Store( "tts_44khz.wav" );
cout << "Converted files." << endl;
}
catch( ITAException& err )
{
cerr << "File test error: " << err << endl;
}
try
{
CITAAudioSample as44kfs;
......@@ -18,13 +32,15 @@ int main( int, char** )
as44kfs[ 0 ][ 0 ] = 1.0f;
as44kfs[ 0 ][ as44kfs.GetLength() - 1 ] = -1.0f;
as48kfs.Load( as44kfs );
as96kfs.Load( as48kfs );
as128kfs.Load( as96kfs );
as48kfs.LoadWithSampleTypeConversion( as44kfs );
as96kfs.LoadWithSampleTypeConversion( as48kfs );
as128kfs.LoadWithSampleTypeConversion( as96kfs );
cout << "Converted." << endl;
}
catch( ITAException& err )
{
cerr << "Error: " << err << endl;
cerr << "Generic test error: " << err << endl;
}
return 0;
......
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