00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "extended.hxx"
00023 #include "AIFFFileIO.hxx"
00024 #include "ErrSoundFileIO.hxx"
00025
00026
00027 using namespace CLAM;
00028
00029 void AIFFFileIO::InitSelf(void)
00030 {
00031 #ifdef SOUNDFILEIO_LITTLE_ENDIAN
00032 mSwap = true;
00033 #endif
00034 }
00035
00036 #ifdef SOUNDFILEIO_LITTLE_ENDIAN
00037 #define SWAP(var) Swap(var)
00038 #else
00039 #define SWAP(var)
00040 #endif
00041
00042 int AIFFFileIO::ReadChunkHeader(ChunkHeader& h)
00043 {
00044 int ret = int( fread(&h,1,sizeof(h),mFile) );
00045 SWAP(h.len);
00046 return ret;
00047 }
00048
00049 int AIFFFileIO::WriteChunkHeader(const ChunkHeader& h)
00050 {
00051 ChunkHeader cp = h;
00052 SWAP(cp.len);
00053 return int(fwrite(&cp,1,sizeof(cp),mFile) );
00054 }
00055
00056 int AIFFFileIO::ReadID(ID& id)
00057 {
00058 return int( fread(&id,1,sizeof(id),mFile) );
00059 }
00060
00061 int AIFFFileIO::WriteID(ID& id)
00062 {
00063 return int( fwrite(&id,1,sizeof(id),mFile) );
00064 }
00065
00066 bool AIFFFileIO::CheckID(const ID& id,const ID& cmp)
00067 {
00068 return !memcmp(&id,&cmp,4);
00069 }
00070
00071 void AIFFFileIO::ReadHeader(void)
00072 {
00073 unsigned int i = 0;
00074 bool fmtFound = false;
00075 fseek(mFile,0,SEEK_SET);
00076 ID AIFFID;
00077 ChunkHeader form;
00078 ReadChunkHeader(form);
00079 if (!CheckID(form.id,"FORM"))
00080 {
00081 UnsupportedSoundFileFormat error( "Given file had not a valid AIFF header ");
00082 throw error;
00083 }
00084 i = 0;
00085 i += ReadID(AIFFID);
00086 if (!CheckID(AIFFID,"AIFF"))
00087 {
00088 UnsupportedSoundFileFormat error( "Given file had not a valid AIFF header " );
00089 throw error;
00090 }
00091
00092 while (i<form.len) {
00093 ChunkHeader h;
00094 i += ReadChunkHeader(h);
00095 if (CheckID(h.id,"COMM")) {
00096 AIFFCommChunk fmt;
00097 i += int( fread(&fmt,1,sizeof(fmt),mFile) );
00098
00099 if (sizeof(fmt)!=2+4+2+10)
00100 {
00101 UnsupportedSoundFileFormat error( "Incorrect size of AIFFCommChunk: check alignment" );
00102
00103 throw error;
00104 }
00105
00106 SWAP(fmt.channels);
00107 SWAP(fmt.numSampleFrames);
00108 SWAP(fmt.sampleWidth);
00109
00110 mHeader.mSampleWidth = fmt.sampleWidth;
00111 mHeader.mBytesPerSample = (mHeader.mSampleWidth+7)>>3;
00112 mHeader.mChannels = fmt.channels;
00113 mHeader.mSamplerate = tenbytefloat2int(fmt.samplerate.bytes);
00114 mSize = fmt.numSampleFrames;
00115 fmtFound = true;
00116 }
00117 else{
00118 if (CheckID(h.id,"SSND")) {
00119 unsigned int offset;
00120 unsigned int blockSize;
00121
00122 fread(&offset,1,sizeof(offset),mFile);
00123 fread(&blockSize,1,sizeof(blockSize),mFile);
00124
00125 mOffset = sizeof(form)+i;
00126 }
00127 i += h.len;
00128 fseek(mFile, sizeof(form)+i, SEEK_SET);
00129 }
00130 }
00131 if (!fmtFound)
00132 {
00133 UnsupportedSoundFileFormat error( "Given file had not a valid header!" );
00134 throw error;
00135 }
00136 if (mOffset == 0)
00137 {
00138 UnsupportedSoundFileFormat error( "Given file contained no audio data");
00139 throw error;
00140 }
00141 }
00142
00143 void AIFFFileIO::WriteHeader(void)
00144 {
00145 fseek(mFile,0,SEEK_SET);
00146 mOffset = 0;
00147 ChunkHeader formHeader("FORM");
00148 ChunkHeader fmtHeader("COMM",sizeof(AIFFCommChunk));
00149 ChunkHeader dataHeader("SSND",mSize*2);
00150
00151 AIFFCommChunk fmtChunk;
00152 ID AIFFID("AIFF");
00153
00154 if (mStdIO && mSize==0)
00155 {
00156 dataHeader.len = 0x7FFFFFFF;
00157 }
00158
00159 formHeader.len =
00160 sizeof(AIFFID) +
00161 sizeof(fmtHeader) + fmtHeader.len +
00162 sizeof(dataHeader) + dataHeader.len;
00163
00164 fmtChunk.channels = mHeader.mChannels;
00165 uint2tenbytefloat(mHeader.mSamplerate,fmtChunk.samplerate.bytes);
00166 fmtChunk.numSampleFrames = mSize;
00167 fmtChunk.sampleWidth = 16;
00168
00169 mOffset += WriteChunkHeader(formHeader);
00170 mOffset += WriteID(AIFFID);
00171 mOffset += WriteChunkHeader(fmtHeader);
00172
00173 SWAP(fmtChunk.channels);
00174 SWAP(fmtChunk.numSampleFrames);
00175 SWAP(fmtChunk.sampleWidth);
00176
00177 mOffset += int( fwrite(&fmtChunk,1,sizeof(fmtChunk),mFile) );
00178 mOffset += WriteChunkHeader(dataHeader);
00179
00180 unsigned int offset = 0;
00181 unsigned int blockSize = 0;
00182
00183 SWAP(offset);
00184 SWAP(blockSize);
00185
00186 mOffset += int( fwrite(&offset,1,sizeof(offset),mFile) );
00187 mOffset += int( fwrite(&blockSize,1,sizeof(blockSize),mFile) );
00188 }
00189
00190