164 lines
6.0 KiB
C++
164 lines
6.0 KiB
C++
#include <sample/wave.hpp>
|
|
#include <common/memfile.hpp>
|
|
#include <common/openfile.hpp>
|
|
|
|
WaveForm::WaveForm(String wavePathFileName)
|
|
{
|
|
initWaveForm();
|
|
wavePathFileName.lower();
|
|
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
|
mWavePathFileName=wavePathFileName;
|
|
FileHandle waveFile(wavePathFileName,FileHandle::Read,FileHandle::ShareReadWrite);
|
|
if(!waveFile.isOkay())return;
|
|
waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString));
|
|
waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData));
|
|
waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString));
|
|
mFormatChunk<<waveFile;
|
|
while(TRUE)
|
|
{
|
|
ChunkID chunkID;
|
|
chunkID<<waveFile;
|
|
waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent);
|
|
if(chunkID==String("data")){mDataChunk<<waveFile;break;}
|
|
mGenericChunks.insert(&GenericChunk());
|
|
mGenericChunks[mGenericChunks.size()-1]<<waveFile;
|
|
}
|
|
mSampleData.numSamples(mDataChunk.length());
|
|
mSampleData<<waveFile;
|
|
waveFile.close();
|
|
}
|
|
|
|
WaveForm WaveForm::operator+(const WaveForm &someWaveForm)
|
|
{
|
|
WaveForm waveForm(*this);
|
|
waveForm+=someWaveForm;
|
|
return waveForm;
|
|
}
|
|
|
|
WaveForm &WaveForm::operator=(const WaveForm &someWaveForm)
|
|
{
|
|
initWaveForm();
|
|
mLengthData=someWaveForm.mLengthData;
|
|
mFormatChunk=someWaveForm.mFormatChunk;
|
|
mDataChunk=someWaveForm.mDataChunk;
|
|
mSampleData=someWaveForm.mSampleData;
|
|
return *this;
|
|
}
|
|
|
|
WaveForm &WaveForm::operator+=(const WaveForm &someWaveForm)
|
|
{
|
|
if(mLengthData<someWaveForm.mLengthData)
|
|
{
|
|
mLengthData=someWaveForm.mLengthData;
|
|
mFormatChunk=someWaveForm.mFormatChunk;
|
|
mDataChunk=someWaveForm.mDataChunk;
|
|
}
|
|
mSampleData+=someWaveForm.mSampleData;
|
|
return *this;
|
|
}
|
|
|
|
bool WaveForm::operator==(const WaveForm &/*someWaveForm*/)const
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
bool WaveForm::operator<<(FileHandle &waveFile)
|
|
{
|
|
if(!waveFile.isOkay())return FALSE;
|
|
initWaveForm();
|
|
waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString));
|
|
waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData));
|
|
waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString));
|
|
mFormatChunk<<waveFile;
|
|
while(TRUE)
|
|
{
|
|
ChunkID chunkID;
|
|
chunkID<<waveFile;
|
|
waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent);
|
|
if(chunkID==String("data")){mDataChunk<<waveFile;break;}
|
|
mGenericChunks.insert(&GenericChunk());
|
|
mGenericChunks[mGenericChunks.size()-1]<<waveFile;
|
|
}
|
|
mSampleData.numSamples(mDataChunk.length());
|
|
mSampleData<<waveFile;
|
|
return TRUE;
|
|
}
|
|
|
|
void WaveForm::initWaveForm(void)
|
|
{
|
|
mLengthData=0;
|
|
mExtensionString=".wav";
|
|
mWaveString="WAVE";
|
|
mRiffString="RIFF";
|
|
::memcpy(mHeaderString,mRiffString,mRiffString.length());
|
|
::memcpy(mSubHeaderString,mWaveString,mWaveString.length());
|
|
}
|
|
|
|
bool WaveForm::save(String wavePathFileName)
|
|
{
|
|
DWORD waveFileLength((long)sizeof(mHeaderString)+(long)sizeof(mLengthData)+(long)sizeof(mSubHeaderString)+(long)sizeof(FormatChunk)+(long)sizeof(DataChunk)+(long)mSampleData.numSamples());
|
|
wavePathFileName.upper();
|
|
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
|
MemFile waveFile(wavePathFileName,waveFileLength);
|
|
mLengthData=mSampleData.numSamples()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
|
|
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
|
|
waveFile.write((char*)&mHeaderString,sizeof(mHeaderString));
|
|
waveFile.write((char*)&mLengthData,sizeof(mLengthData));
|
|
waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString));
|
|
mFormatChunk>>waveFile;
|
|
mDataChunk.length(mSampleData.numSamples());
|
|
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mGenericChunks[chunkIndex]>>waveFile;
|
|
mDataChunk>>waveFile;
|
|
mSampleData>>waveFile;
|
|
return waveFile.flushBuffer();
|
|
}
|
|
|
|
bool WaveForm::save(String wavePathFileName,const PureSample &somePureSample,DWORD samplesPerSecond,DWORD avgBytesPerSecond)
|
|
{
|
|
DWORD waveFileLength((long)sizeof(mHeaderString)+(long)sizeof(mLengthData)+(long)sizeof(mSubHeaderString)+(long)sizeof(FormatChunk)+(long)sizeof(DataChunk)+(long)somePureSample.numSamples());
|
|
|
|
wavePathFileName.upper();
|
|
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
|
|
MemFile waveFile(wavePathFileName,waveFileLength);
|
|
mLengthData=somePureSample.numSamples()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
|
|
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
|
|
waveFile.write((char*)&mHeaderString,sizeof(mHeaderString));
|
|
waveFile.write((char*)&mLengthData,sizeof(mLengthData));
|
|
waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString));
|
|
mFormatChunk.formatTag(FormatChunk::WaveFormatPCM);
|
|
mFormatChunk.channels(FormatChunk::NumChannels);
|
|
mFormatChunk.samplesPerSecond(samplesPerSecond);
|
|
mFormatChunk.averageBytesPerSecond(avgBytesPerSecond);
|
|
mFormatChunk.blockAlign(FormatChunk::BlockAlign);
|
|
mFormatChunk.bitsPerSample(FormatChunk::BitsPerSample);
|
|
mFormatChunk>>waveFile;
|
|
mDataChunk.length(somePureSample.numSamples());
|
|
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mGenericChunks[chunkIndex]>>waveFile;
|
|
mDataChunk>>waveFile;
|
|
somePureSample>>waveFile;
|
|
return waveFile.flushBuffer();
|
|
}
|
|
|
|
String WaveForm::toString(void)const
|
|
{
|
|
String strWaveForm;
|
|
|
|
strWaveForm+=String("<WAVEFORM>");
|
|
strWaveForm+=String(" Header=")+String(mHeaderString).quotes();
|
|
strWaveForm+=String(" LengthData=")+String().fromInt(mLengthData).quotes();
|
|
strWaveForm+=String(" SubHeader=")+String(mSubHeaderString).quotes();
|
|
strWaveForm+=String(" ")+mFormatChunk.toString();
|
|
for(int index=0;index<mGenericChunks.size();index++)
|
|
{
|
|
strWaveForm+=((Block<GenericChunk>&)mGenericChunks)[index].chunkID().toString();
|
|
}
|
|
strWaveForm+=mDataChunk.toString();
|
|
strWaveForm+=mSampleData.toString();
|
|
strWaveForm+=String(" WavePathFileName=")+mWavePathFileName.quotes();
|
|
strWaveForm+=String(" Extension=")+mExtensionString.quotes();
|
|
strWaveForm+=String(" WaveString=")+mWaveString.quotes();
|
|
strWaveForm+=String(" RiffString=")+mRiffString.quotes();
|
|
strWaveForm+=String("</WAVEFORM>");
|
|
return strWaveForm;
|
|
}
|