pwavfile.h

Go to the documentation of this file.
00001 /*
00002  * pwavfile.h
00003  *
00004  * WAV file I/O channel class.
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 2001 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is
00023  * Roger Hardiman <roger@freebsd.org>
00024  * and Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
00025  *
00026  * All Rights Reserved.
00027  *
00028  * Contributor(s): ______________________________________.
00029  *
00030  * $Log: pwavfile.h,v $
00031  * Revision 1.31  2007/05/09 12:20:15  csoutheren
00032  * Applied 1712697 - WAVE form registration number for G.729A
00033  * Thanks to Borko Jandras
00034  *
00035  * Revision 1.30  2007/04/23 01:15:14  csoutheren
00036  * Removed warnings on Windows
00037  *
00038  * Revision 1.29  2007/04/20 07:59:29  csoutheren
00039  * Applied 1675658 - various pwavfile.[h|cxx] improvments
00040  * Thanks to Drazen Dimoti
00041  *
00042  * Revision 1.28  2007/04/19 04:33:53  csoutheren
00043  * Fixed problems with pre-compiled headers
00044  *
00045  * Revision 1.27  2006/08/08 08:14:59  rjongbloed
00046  * Fixed GCC warnings on packed structures that do not need packing.
00047  *
00048  * Revision 1.26  2006/06/21 05:19:38  csoutheren
00049  * Fixed build with latest PWLib
00050  *
00051  * Revision 1.25  2006/04/10 23:57:25  csoutheren
00052  * Checked in changes to remove some warnings with gcc effc++ flag
00053  *
00054  * Revision 1.24  2006/04/06 00:39:37  csoutheren
00055  * Ensure autoconvert format is preserved across file close
00056  *
00057  * Revision 1.23  2005/11/30 12:47:37  csoutheren
00058  * Removed tabs, reformatted some code, and changed tags for Doxygen
00059  *
00060  * Revision 1.22  2005/10/30 23:25:51  csoutheren
00061  * Fixed formatting
00062  * Removed throw() declarations (PWLib does not do exceptions)
00063  * Removed duplicate destructor declarations and definitions
00064  *
00065  * Revision 1.21  2005/10/30 19:41:53  dominance
00066  * fixed most of the warnings occuring during compilation
00067  *
00068  * Revision 1.20  2005/06/09 00:33:12  csoutheren
00069  * Fixed crash problem caused by recent leak fix
00070  * Removed bogus error when reading all of file contents in a single read
00071  *
00072  * Revision 1.19  2005/05/12 05:25:04  csoutheren
00073  * PWAVFile format abstract factory must use a PCaseless as a key
00074  *
00075  * Revision 1.18  2005/03/19 02:52:53  csoutheren
00076  * Fix warnings from gcc 4.1-20050313 shapshot
00077  *
00078  * Revision 1.17  2005/01/04 07:44:02  csoutheren
00079  * More changes to implement the new configuration methodology, and also to
00080  * attack the global static problem
00081  *
00082  * Revision 1.16  2004/11/11 07:34:50  csoutheren
00083  * Added #include <ptlib.h>
00084  *
00085  * Revision 1.15  2004/11/08 04:07:40  csoutheren
00086  * Fixed crash opportunity under some conditions
00087  * Fixed incorrect WAV file type display
00088  *
00089  * Revision 1.14  2004/07/15 03:12:41  csoutheren
00090  * Migrated changes from crs_vxnml_devel branch into main trunk
00091  *
00092  * Revision 1.13.4.4  2004/07/13 08:13:04  csoutheren
00093  * Lots of implementation of factory-based PWAVFile
00094  *
00095  * Revision 1.13.4.3  2004/07/12 09:17:19  csoutheren
00096  * Fixed warnings and errors under Linux
00097  *
00098  * Revision 1.13.4.2  2004/07/12 08:30:16  csoutheren
00099  * More fixes for abstract factory implementation of PWAVFile
00100  *
00101  * Revision 1.13.4.1  2004/07/07 07:07:41  csoutheren
00102  * Changed PWAVFile to use abstract factories (extensively)
00103  * Removed redundant blocking/unblocking when using G.723.1
00104  * More support for call transfer
00105  *
00106  * Revision 1.13  2003/03/07 06:12:05  robertj
00107  * Added more WAV file "magic numbers".
00108  *
00109  * Revision 1.12  2002/09/16 01:08:59  robertj
00110  * Added #define so can select if #pragma interface/implementation is used on
00111  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00112  *
00113  * Revision 1.11  2002/06/20 00:51:38  craigs
00114  * Added virtuals to allow overriding
00115  *
00116  * Revision 1.10  2002/05/21 01:56:53  robertj
00117  * Removed the enum which made yet another set of magic numbers for audio
00118  *   formats, now uses the WAV file format numbers.
00119  * Fixed failure to write header when destroying object without and explicit
00120  *   call to Close().
00121  * Fixed missing Open() function which does not have file name parameter.
00122  * Added ability to set the audio format after construction.
00123  *
00124  * Revision 1.9  2002/01/22 03:55:07  craigs
00125  * Added #define guards when file moved to PTCLib
00126  *
00127  * Revision 1.8  2002/01/13 21:00:41  rogerh
00128  * The type of new .WAV files must now be specified in the class constructor.
00129  * Take out Open() function from the last commit and create a new Open()
00130  * function which replaces the one in the PFile base class.
00131  *
00132  * Revision 1.7  2002/01/11 16:33:46  rogerh
00133  * Create a PWAVFile Open() function, which processes the WAV header
00134  *
00135  * Revision 1.6  2001/10/16 13:27:37  rogerh
00136  * Add support for writing G.723.1 WAV files.
00137  * MS Windows can play G.723.1 WAV Files in Media Player and Sound Recorder.
00138  * Sound Recorder can also convert them to normal PCM format WAV files.
00139  * Thanks go to M.Stoychev <M.Stoychev@cnsys.bg> for sample WAV files.
00140  *
00141  * Revision 1.5  2001/10/15 11:48:15  rogerh
00142  * Add GetFormat to return the format of a WAV file
00143  *
00144  * Revision 1.4  2001/07/23 01:20:20  rogerh
00145  * Add updates from Shawn - ensure isvalidWAV is false for zero length files.
00146  * GetDataLength uses actual file size to support file updates as well as appends.
00147  * Add updates from Roger - Update Header() just writes to specific fields which
00148  * preserves any 'extra' data in an existing header between FORMAT and DATA chunks.
00149  *
00150  * Revision 1.3  2001/07/20 07:06:27  rogerh
00151  * Fix a typo
00152  *
00153  * Revision 1.2  2001/07/20 03:30:59  robertj
00154  * Minor cosmetic changes to new PWAVFile class.
00155  *
00156  * Revision 1.1  2001/07/19 09:55:48  rogerh
00157  * Add PWAVFile, a class to read and write .wav files, written by
00158  * Roger Hardiman and <roger@freebsd.org> and
00159  * Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
00160  *
00161  *
00162  */
00163 
00164 #ifndef _PWAVFILE
00165 #define _PWAVFILE
00166 
00167 //#ifdef P_USE_PRAGMA
00168 //#pragma interface
00169 //#endif
00170 
00171 #ifndef _PTLIB_H
00172 #include <ptlib.h>
00173 #endif
00174 
00175 #include <ptlib/pfactory.h>
00176 
00177 class PWAVFile;
00178 
00179 namespace PWAV {
00180 
00181 #ifdef __GNUC__
00182 #define P_PACKED    __attribute__ ((packed));
00183 #else
00184 #define P_PACKED
00185 #pragma pack(1)
00186 #endif
00187 
00188 struct ChunkHeader
00189 {
00190   char    tag[4];
00191   PInt32l len    P_PACKED;
00192 };
00193 
00194 struct RIFFChunkHeader 
00195 {
00196   ChunkHeader hdr;
00197   char        tag[4];
00198 };
00199 
00200 struct FMTChunk
00201 {
00202   ChunkHeader hdr;                    
00203   PUInt16l format          P_PACKED;  
00204   PUInt16l numChannels     P_PACKED;  
00205   PUInt32l sampleRate      P_PACKED;  
00206   PUInt32l bytesPerSec     P_PACKED;  
00207   PUInt16l bytesPerSample  P_PACKED;  
00208   PUInt16l bitsPerSample   P_PACKED;  
00209 };
00210 
00211 }; // namespace PWAV
00212 
00213 #ifdef __GNUC__
00214 #undef P_PACKED
00215 #else
00216 #pragma pack()
00217 #endif
00218 
00222 class PWAVFileFormat
00223 {
00224   public:
00225     virtual ~PWAVFileFormat() { }
00226 
00230     virtual unsigned GetFormat() const = 0;
00231 
00235     virtual PString GetFormatString() const = 0;
00236 
00240     virtual PString GetDescription() const = 0;
00241 
00245     virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00246 
00250     virtual void UpdateHeader(PWAV::FMTChunk & /*header*/, PBYTEArray & /*extendedHeader*/)
00251     { }
00252 
00256     virtual BOOL WriteExtraChunks(PWAVFile & /*file*/)
00257     { return TRUE; }
00258 
00262     virtual BOOL ReadExtraChunks(PWAVFile & /*file*/)
00263     { return TRUE; }
00264 
00268     virtual void OnStart()
00269     { }
00270 
00274     virtual void OnStop()
00275     { }
00276 
00280     virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00281 
00285     virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00286 };
00287 
00288 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00289 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00290 
00294 class PWAVFileConverter 
00295 {
00296   public:
00297     virtual ~PWAVFileConverter() { }
00298     virtual unsigned GetFormat    (const PWAVFile & file) const = 0;
00299     virtual off_t GetPosition     (const PWAVFile & file) const = 0;
00300     virtual BOOL SetPosition      (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00301     virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00302     virtual off_t GetDataLength   (PWAVFile & file) = 0;
00303     virtual BOOL Read             (PWAVFile & file, void * buf, PINDEX len)  = 0;
00304     virtual BOOL Write            (PWAVFile & file, const void * buf, PINDEX len) = 0;
00305 };
00306 
00307 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00308 
00311 class PWAVFile : public PFile
00312 {
00313   PCLASSINFO(PWAVFile, PFile);
00314 
00315   public:
00321     enum {
00322       fmt_PCM         = 1,      
00323       fmt_MSADPCM     = 2,      
00324       fmt_ALaw        = 6,      
00325       fmt_uLaw        = 7,      
00326       fmt_VOXADPCM    = 0x10,   
00327       fmt_IMAADPCM    = 0x11,   
00328       fmt_GSM         = 0x31,   
00329       fmt_G728        = 0x41,   
00330       fmt_G723        = 0x42,   
00331       fmt_MSG7231     = 0x42,   
00332       fmt_G726        = 0x64,   
00333       fmt_G722        = 0x65,   
00334       fmt_G729        = 0x83,   
00335       fmt_VivoG7231   = 0x111,  
00336 
00337       // For backward compatibility
00338       PCM_WavFile     = fmt_PCM,
00339       G7231_WavFile   = fmt_VivoG7231,
00340 
00341       // allow opening files without knowing the format
00342       fmt_NotKnown    = 0x10000
00343     };
00344 
00354     PWAVFile(
00355       unsigned format = fmt_PCM 
00356     );
00357     static PWAVFile * format(
00358       const PString & format    
00359     );
00360 
00373     PWAVFile(
00374       OpenMode mode,          
00375       int opts = ModeDefault, 
00376       unsigned format = fmt_PCM 
00377     );
00378     static PWAVFile * format(
00379       const PString & format,  
00380       PFile::OpenMode mode,          
00381       int opts = PFile::ModeDefault 
00382     );
00383 
00393     PWAVFile(
00394       const PFilePath & name,     
00395       OpenMode mode = ReadWrite,  
00396       int opts = ModeDefault,     
00397       unsigned format = fmt_PCM 
00398     );
00399     PWAVFile(
00400       const PString & format,  
00401       const PFilePath & name,     
00402       OpenMode mode = PFile::ReadWrite,  
00403       int opts = PFile::ModeDefault     
00404     );
00405 
00408     ~PWAVFile();
00410 
00420     virtual BOOL Read(
00421       void * buf,   
00422       PINDEX len    
00423     );
00424 
00432     virtual BOOL Write(
00433       const void * buf,   
00434       PINDEX len    
00435     );
00436 
00448     virtual BOOL Open(
00449       OpenMode mode = ReadWrite,  
00450       int opts = ModeDefault      
00451     );
00452 
00466     virtual BOOL Open(
00467       const PFilePath & name,    
00468       OpenMode mode = ReadWrite, 
00469       int opts = ModeDefault     
00470     );
00471 
00477     virtual BOOL Close();
00478 
00493     virtual BOOL SetPosition(
00494       off_t pos,                         
00495       FilePositionOrigin origin = Start  
00496     );
00497 
00505     virtual off_t GetPosition() const;
00507 
00512     virtual BOOL SetFormat(unsigned fmt);
00513     virtual BOOL SetFormat(const PString & format);
00514 
00517     virtual unsigned GetFormat() const;
00518     virtual PString GetFormatAsString() const;
00519 
00523     virtual unsigned GetChannels() const;
00524     virtual void SetChannels(unsigned v);
00525 
00528     virtual unsigned GetSampleRate() const;
00529     virtual void SetSampleRate(unsigned v);
00530 
00533     virtual unsigned GetSampleSize() const;
00534     virtual void SetSampleSize(unsigned v);
00535 
00538     virtual unsigned GetBytesPerSecond() const;
00539     virtual void SetBytesPerSecond(unsigned v);
00540 
00543     off_t GetHeaderLength() const;
00544 
00547     virtual off_t GetDataLength();
00548 
00555     BOOL IsValid() const { return isValidWAV; }
00556 
00560     PString GetFormatString() const
00561     { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00562 
00566     void SetAutoconvert();
00567 
00569  
00570     friend class PWAVFileConverter;
00571 
00572     BOOL RawRead(void * buf, PINDEX len);
00573     BOOL RawWrite(const void * buf, PINDEX len);
00574 
00575     BOOL FileRead(void * buf, PINDEX len);
00576     BOOL FileWrite(const void * buf, PINDEX len);
00577 
00578     off_t RawGetPosition() const;
00579     BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00580     off_t RawGetDataLength();
00581 
00582     void SetLastReadCount(PINDEX v) { lastReadCount = v; } 
00583 
00584     PWAV::FMTChunk wavFmtChunk;
00585     PBYTEArray extendedHeader;
00586 
00587   protected:
00588     void Construct();
00589     void SelectFormat(unsigned fmt);
00590     void SelectFormat(const PString & format);
00591 
00592     PBYTEArray wavHeaderData;
00593 
00594     BOOL ProcessHeader();
00595     BOOL GenerateHeader();
00596     BOOL UpdateHeader();
00597 
00598     BOOL     isValidWAV;
00599 
00600     unsigned int origFmt;
00601     PWAVFileFormat * formatHandler;
00602 
00603     BOOL     autoConvert;
00604     PWAVFileConverter * autoConverter;
00605 
00606     off_t lenHeader;
00607     off_t lenData;
00608 
00609     BOOL     header_needs_updating;
00610 };
00611 
00612 #endif
00613 
00614 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1