AIFFFileIO.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 

Generated on Tue Jun 19 20:34:52 2007 for CLAM-Development by  doxygen 1.5.2