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

238 lines
8.9 KiB
C++

#include <sample/wave.hpp>
#include <common/memfile.hpp>
#include <common/openfile.hpp>
#include <common/stringbuffer.hpp>
WaveForm::WaveForm(const String &wavePathFileName)
{
bool result = 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;
if(!waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString)))return false;
if(!waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData)))return false;
if(!waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString)))return false;
if(!mFormatChunk.read(waveFile))return false;
while(true)
{
ChunkID chunkID;
if(!chunkID.read(waveFile))return false;
if(FileHandle::ErrorReturn==waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent))return false;
if(chunkID==String("data"))
{
if(!mDataChunk.read(waveFile))return false;
break;
}
mGenericChunks.insert(&GenericChunk());
mGenericChunks[mGenericChunks.size()-1].read(waveFile);
}
mSampleData.initialize(PureSampleEx::BitsPerSample(mFormatChunk.bitsPerSample()),mDataChunk.length(),PureSampleEx::ParamIsSizeBytes);
if(!mSampleData.read(waveFile))return false;
waveFile.close();
return mSampleData.getNumSamples()?true:false;
}
*/
bool WaveForm::open(String wavePathFileName)
{
if(wavePathFileName.isNull())return false;
wavePathFileName.lower();
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
mWavePathFileName=wavePathFileName;
FileHandle waveFile(wavePathFileName,FileHandle::Read,FileHandle::ShareReadWrite);
if(!read(waveFile))return false;
waveFile.close();
return mSampleData.getNumSamples()?true:false;
}
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::read(FileHandle &waveFile)
{
if(!waveFile.isOkay())return FALSE;
initWaveForm();
if(!waveFile.read((BYTE*)&mHeaderString,sizeof(mHeaderString)))return false;
if(!waveFile.read((BYTE*)&mLengthData,sizeof(mLengthData)))return false;
if(!waveFile.read((BYTE*)&mSubHeaderString,sizeof(mSubHeaderString)))return false;
if(!mFormatChunk.read(waveFile))return false;
while(true)
{
ChunkID chunkID;
if(!chunkID.read(waveFile))return false;
if(FileHandle::ErrorReturn==waveFile.seek(-chunkID.size(),FileHandle::SeekCurrent))return false;
if(chunkID==String("data"))
{
if(!mDataChunk.read(waveFile))return false;
break;
}
mGenericChunks.insert(&GenericChunk());
if(!mGenericChunks[mGenericChunks.size()-1].read(waveFile))return false;
}
mSampleData.initialize(PureSampleEx::BitsPerSample(mFormatChunk.bitsPerSample()),mDataChunk.length(),PureSampleEx::ParamIsSizeBytes);
// mSampleData.initialize(PureSampleEx::BitsPerSample(mFormatChunk.bitsPerSample()),mDataChunk.length(),PureSampleEx::ParamIsNumSamples);
if(!mSampleData.read(waveFile))return false;
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.getSizeBytes());
wavePathFileName.lower();
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
MemFile waveFile(wavePathFileName,waveFileLength);
mLengthData=mSampleData.getSizeBytes()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
if(!waveFile.write((char*)&mHeaderString,sizeof(mHeaderString)))return false;
if(!waveFile.write((char*)&mLengthData,sizeof(mLengthData)))return false;
if(!waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString)))return false;
if(!mFormatChunk.write(waveFile))return false;
mDataChunk.length(mSampleData.getSizeBytes());
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)
{
if(!mGenericChunks[chunkIndex].write(waveFile))return false;
}
if(!mDataChunk.write(waveFile))return false;
if(!mSampleData.write(waveFile))return false;
return waveFile.flushBuffer();
}
bool WaveForm::save(String wavePathFileName,const PureSampleEx &pureSample,DWORD samplesPerSecond,DWORD avgBytesPerSecond)
{
DWORD waveFileLength((long)sizeof(mHeaderString)+(long)sizeof(mLengthData)+(long)sizeof(mSubHeaderString)+(long)sizeof(FormatChunk)+(long)sizeof(DataChunk)+(long)pureSample.getSizeBytes());
wavePathFileName.upper();
if(!wavePathFileName.strstr(mExtensionString))wavePathFileName+=mExtensionString;
MemFile waveFile(wavePathFileName,waveFileLength);
mLengthData=pureSample.getSizeBytes()+sizeof(mSubHeaderString)+mFormatChunk.size()+mDataChunk.size();
for(short chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)mLengthData+=mGenericChunks[chunkIndex].chunkLength();
if(!waveFile.write((char*)&mHeaderString,sizeof(mHeaderString)))return false;
if(!waveFile.write((char*)&mLengthData,sizeof(mLengthData)))return false;
if(!waveFile.write((char*)&mSubHeaderString,sizeof(mSubHeaderString)))return false;
mFormatChunk.formatTag(FormatChunk::WaveFormatPCM);
mFormatChunk.channels(FormatChunk::NumChannels);
mFormatChunk.samplesPerSecond(samplesPerSecond);
mFormatChunk.averageBytesPerSecond(avgBytesPerSecond);
mFormatChunk.blockAlign(FormatChunk::BlockAlign);
mFormatChunk.bitsPerSample(pureSample.getBitsPerSample());
if(!mFormatChunk.write(waveFile))return false;
mDataChunk.length(pureSample.getSizeBytes());
for(chunkIndex=0;chunkIndex<mGenericChunks.size();chunkIndex++)
{
if(!mGenericChunks[chunkIndex].write(waveFile))return false;
}
if(!mDataChunk.write(waveFile))return false;
if(!pureSample.write(waveFile))return false;
return waveFile.flushBuffer();
}
bool WaveForm::convert(PureSampleEx::BitsPerSample bitsPerSample)
{
if(!isOkay())return false;
if(bitsPerSample==mSampleData.getBitsPerSample())return true;
mSampleData.convert(bitsPerSample);
mFormatChunk.bitsPerSample((int)bitsPerSample);
return true;
}
String WaveForm::toString(void)const
{
StringBuffer strWaveForm;
String crlf("\r\n");
strWaveForm.append("<WAVEFORM>").append(crlf);
strWaveForm.append(" Header=").append(String(mHeaderString).quotes()).append(crlf);
strWaveForm.append(" LengthData=").append(String().fromInt(mLengthData).quotes()).append(crlf);
strWaveForm.append(" SubHeader=").append(String(mSubHeaderString).quotes()).append(crlf);
strWaveForm.append(" ").append(mFormatChunk.toString()).append(crlf);
for(int index=0;index<mGenericChunks.size();index++)
{
strWaveForm.append(((Block<GenericChunk>&)mGenericChunks)[index].chunkID().toString()).append(crlf);
}
strWaveForm.append(mDataChunk.toString()).append(crlf);
strWaveForm.append(" WavePathFileName=").append(mWavePathFileName.quotes()).append(crlf);
strWaveForm.append(" Extension=").append(mExtensionString.quotes()).append(crlf);
strWaveForm.append(" WaveString=").append(mWaveString.quotes()).append(crlf);
strWaveForm.append(" RiffString=").append(mRiffString.quotes()).append(crlf);
strWaveForm.append("</WAVEFORM>").append(crlf);
return strWaveForm.toString();
}
/*
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+=String(" WavePathFileName=")+mWavePathFileName.quotes();
strWaveForm+=String(" Extension=")+mExtensionString.quotes();
strWaveForm+=String(" WaveString=")+mWaveString.quotes();
strWaveForm+=String(" RiffString=")+mRiffString.quotes();
strWaveForm+=String("</WAVEFORM>");
return strWaveForm;
}
*/