Files
Work/sample/holdii/Wave.cpp
2024-08-07 09:16:27 -04:00

170 lines
6.1 KiB
C++

#include <sample/wave.hpp>
#include <common/memfile.hpp>
#include <common/openfile.hpp>
WaveForm::WaveForm(const String &wavePathFileName)
{
open(wavePathFileName);
}
bool WaveForm::open(String wavePathFileName)
{
initWaveForm();
wavePathFileName.lower();
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
mWavePathFileName=wavePathFileName;
FileHandle waveFile(wavePathFileName,FileHandle::Read,FileHandle::ShareReadWrite);
if(!waveFile.isOkay())return false;
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();
return true;
}
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;
}