Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

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.23  2005/11/30 12:47:37  csoutheren
00032  * Removed tabs, reformatted some code, and changed tags for Doxygen
00033  *
00034  * Revision 1.22  2005/10/30 23:25:51  csoutheren
00035  * Fixed formatting
00036  * Removed throw() declarations (PWLib does not do exceptions)
00037  * Removed duplicate destructor declarations and definitions
00038  *
00039  * Revision 1.21  2005/10/30 19:41:53  dominance
00040  * fixed most of the warnings occuring during compilation
00041  *
00042  * Revision 1.20  2005/06/09 00:33:12  csoutheren
00043  * Fixed crash problem caused by recent leak fix
00044  * Removed bogus error when reading all of file contents in a single read
00045  *
00046  * Revision 1.19  2005/05/12 05:25:04  csoutheren
00047  * PWAVFile format abstract factory must use a PCaseless as a key
00048  *
00049  * Revision 1.18  2005/03/19 02:52:53  csoutheren
00050  * Fix warnings from gcc 4.1-20050313 shapshot
00051  *
00052  * Revision 1.17  2005/01/04 07:44:02  csoutheren
00053  * More changes to implement the new configuration methodology, and also to
00054  * attack the global static problem
00055  *
00056  * Revision 1.16  2004/11/11 07:34:50  csoutheren
00057  * Added #include <ptlib.h>
00058  *
00059  * Revision 1.15  2004/11/08 04:07:40  csoutheren
00060  * Fixed crash opportunity under some conditions
00061  * Fixed incorrect WAV file type display
00062  *
00063  * Revision 1.14  2004/07/15 03:12:41  csoutheren
00064  * Migrated changes from crs_vxnml_devel branch into main trunk
00065  *
00066  * Revision 1.13.4.4  2004/07/13 08:13:04  csoutheren
00067  * Lots of implementation of factory-based PWAVFile
00068  *
00069  * Revision 1.13.4.3  2004/07/12 09:17:19  csoutheren
00070  * Fixed warnings and errors under Linux
00071  *
00072  * Revision 1.13.4.2  2004/07/12 08:30:16  csoutheren
00073  * More fixes for abstract factory implementation of PWAVFile
00074  *
00075  * Revision 1.13.4.1  2004/07/07 07:07:41  csoutheren
00076  * Changed PWAVFile to use abstract factories (extensively)
00077  * Removed redundant blocking/unblocking when using G.723.1
00078  * More support for call transfer
00079  *
00080  * Revision 1.13  2003/03/07 06:12:05  robertj
00081  * Added more WAV file "magic numbers".
00082  *
00083  * Revision 1.12  2002/09/16 01:08:59  robertj
00084  * Added #define so can select if #pragma interface/implementation is used on
00085  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00086  *
00087  * Revision 1.11  2002/06/20 00:51:38  craigs
00088  * Added virtuals to allow overriding
00089  *
00090  * Revision 1.10  2002/05/21 01:56:53  robertj
00091  * Removed the enum which made yet another set of magic numbers for audio
00092  *   formats, now uses the WAV file format numbers.
00093  * Fixed failure to write header when destroying object without and explicit
00094  *   call to Close().
00095  * Fixed missing Open() function which does not have file name parameter.
00096  * Added ability to set the audio format after construction.
00097  *
00098  * Revision 1.9  2002/01/22 03:55:07  craigs
00099  * Added #define guards when file moved to PTCLib
00100  *
00101  * Revision 1.8  2002/01/13 21:00:41  rogerh
00102  * The type of new .WAV files must now be specified in the class constructor.
00103  * Take out Open() function from the last commit and create a new Open()
00104  * function which replaces the one in the PFile base class.
00105  *
00106  * Revision 1.7  2002/01/11 16:33:46  rogerh
00107  * Create a PWAVFile Open() function, which processes the WAV header
00108  *
00109  * Revision 1.6  2001/10/16 13:27:37  rogerh
00110  * Add support for writing G.723.1 WAV files.
00111  * MS Windows can play G.723.1 WAV Files in Media Player and Sound Recorder.
00112  * Sound Recorder can also convert them to normal PCM format WAV files.
00113  * Thanks go to M.Stoychev <M.Stoychev@cnsys.bg> for sample WAV files.
00114  *
00115  * Revision 1.5  2001/10/15 11:48:15  rogerh
00116  * Add GetFormat to return the format of a WAV file
00117  *
00118  * Revision 1.4  2001/07/23 01:20:20  rogerh
00119  * Add updates from Shawn - ensure isvalidWAV is false for zero length files.
00120  * GetDataLength uses actual file size to support file updates as well as appends.
00121  * Add updates from Roger - Update Header() just writes to specific fields which
00122  * preserves any 'extra' data in an existing header between FORMAT and DATA chunks.
00123  *
00124  * Revision 1.3  2001/07/20 07:06:27  rogerh
00125  * Fix a typo
00126  *
00127  * Revision 1.2  2001/07/20 03:30:59  robertj
00128  * Minor cosmetic changes to new PWAVFile class.
00129  *
00130  * Revision 1.1  2001/07/19 09:55:48  rogerh
00131  * Add PWAVFile, a class to read and write .wav files, written by
00132  * Roger Hardiman and <roger@freebsd.org> and
00133  * Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
00134  *
00135  *
00136  */
00137 
00138 #ifndef _PWAVFILE
00139 #define _PWAVFILE
00140 
00141 //#ifdef P_USE_PRAGMA
00142 //#pragma interface
00143 //#endif
00144 
00145 #include <ptlib.h>
00146 
00147 class PWAVFile;
00148 
00149 namespace PWAV {
00150 
00151 #ifdef __GNUC__
00152 #define P_PACKED    __attribute__ ((packed));
00153 #else
00154 #define P_PACKED
00155 #pragma pack(1)
00156 #endif
00157 
00158 struct ChunkHeader
00159 {
00160   char    tag[4] P_PACKED;
00161   PInt32l len    P_PACKED;
00162 };
00163 
00164 struct RIFFChunkHeader 
00165 {
00166   ChunkHeader hdr    P_PACKED;
00167   char        tag[4] P_PACKED;
00168 };
00169 
00170 struct FMTChunk
00171 {
00172   ChunkHeader hdr          P_PACKED;  
00173   PUInt16l format          P_PACKED;  
00174   PUInt16l numChannels     P_PACKED;  
00175   PUInt32l sampleRate      P_PACKED;  
00176   PUInt32l bytesPerSec     P_PACKED;  
00177   PUInt16l bytesPerSample  P_PACKED;  
00178   PUInt16l bitsPerSample   P_PACKED;  
00179 };
00180 
00181 }; // namespace PWAV
00182 
00183 #ifdef __GNUC__
00184 #undef P_PACKED
00185 #else
00186 #pragma pack()
00187 #endif
00188 
00192 class PWAVFileFormat
00193 {
00194   public:
00195     virtual ~PWAVFileFormat() { }
00196 
00200     virtual unsigned GetFormat() const = 0;
00201 
00205     virtual PString GetFormatString() const = 0;
00206 
00210     virtual PString GetDescription() const = 0;
00211 
00215     virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00216 
00220     virtual BOOL WriteExtraChunks(PWAVFile & /*file*/)
00221     { return TRUE; }
00222 
00226     virtual BOOL ReadExtraChunks(PWAVFile & /*file*/)
00227     { return TRUE; }
00228 
00232     virtual void OnStart()
00233     { }
00234 
00238     virtual void OnStop()
00239     { }
00240 
00244     virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00245 
00249     virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00250 };
00251 
00252 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00253 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00254 
00258 class PWAVFileConverter 
00259 {
00260   public:
00261     virtual ~PWAVFileConverter() { }
00262     virtual unsigned GetFormat    (const PWAVFile & file) const = 0;
00263     virtual off_t GetPosition     (const PWAVFile & file) const = 0;
00264     virtual BOOL SetPosition      (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00265     virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00266     virtual off_t GetDataLength   (PWAVFile & file) = 0;
00267     virtual BOOL Read             (PWAVFile & file, void * buf, PINDEX len)  = 0;
00268     virtual BOOL Write            (PWAVFile & file, const void * buf, PINDEX len) = 0;
00269 };
00270 
00271 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00272 
00275 class PWAVFile : public PFile
00276 {
00277   PCLASSINFO(PWAVFile, PFile);
00278 
00279   public:
00285     enum {
00286       fmt_PCM         = 1,      
00287       fmt_ALaw        = 6,      
00288       fmt_uLaw        = 7,      
00289       fmt_GSM         = 0x31,   
00290       fmt_G728        = 0x41,   
00291       fmt_G723        = 0x42,   
00292       fmt_MSG7231     = 0x42,   
00293       fmt_G726        = 0x64,   
00294       fmt_G722        = 0x65,   
00295       fmt_G729        = 0x84,   
00296       fmt_VivoG7231   = 0x111,  
00297 
00298       // For backward compatibility
00299       PCM_WavFile     = fmt_PCM,
00300       G7231_WavFile   = fmt_VivoG7231,
00301 
00302       // allow opening files without knowing the format
00303       fmt_NotKnown    = 0x10000
00304     };
00305 
00315     PWAVFile(
00316       unsigned format = fmt_PCM 
00317     );
00318     static PWAVFile * format(
00319       const PString & format    
00320     );
00321 
00334     PWAVFile(
00335       OpenMode mode,          
00336       int opts = ModeDefault, 
00337       unsigned format = fmt_PCM 
00338     );
00339     static PWAVFile * format(
00340       const PString & format,  
00341       PFile::OpenMode mode,          
00342       int opts = PFile::ModeDefault 
00343     );
00344 
00354     PWAVFile(
00355       const PFilePath & name,     
00356       OpenMode mode = ReadWrite,  
00357       int opts = ModeDefault,     
00358       unsigned format = fmt_PCM 
00359     );
00360     PWAVFile(
00361       const PString & format,  
00362       const PFilePath & name,     
00363       OpenMode mode = PFile::ReadWrite,  
00364       int opts = PFile::ModeDefault     
00365     );
00366 
00369     ~PWAVFile();
00371 
00381     virtual BOOL Read(
00382       void * buf,   
00383       PINDEX len    
00384     );
00385 
00393     virtual BOOL Write(
00394       const void * buf,   
00395       PINDEX len    
00396     );
00397 
00409     virtual BOOL Open(
00410       OpenMode mode = ReadWrite,  
00411       int opts = ModeDefault      
00412     );
00413 
00427     virtual BOOL Open(
00428       const PFilePath & name,    
00429       OpenMode mode = ReadWrite, 
00430       int opts = ModeDefault     
00431     );
00432 
00438     virtual BOOL Close();
00439 
00454     virtual BOOL SetPosition(
00455       off_t pos,                         
00456       FilePositionOrigin origin = Start  
00457     );
00458 
00466     virtual off_t GetPosition() const;
00468 
00473     virtual BOOL SetFormat(unsigned fmt);
00474     virtual BOOL SetFormat(const PString & format);
00475 
00478     virtual unsigned GetFormat() const;
00479     virtual PString GetFormatAsString() const;
00480 
00484     virtual unsigned GetChannels() const;
00485     virtual void SetChannels(unsigned v);
00486 
00489     virtual unsigned GetSampleRate() const;
00490     virtual void SetSampleRate(unsigned v);
00491 
00494     virtual unsigned GetSampleSize() const;
00495     virtual void SetSampleSize(unsigned v);
00496 
00499     off_t GetHeaderLength() const;
00500 
00503     virtual off_t GetDataLength();
00504 
00511     BOOL IsValid() const { return isValidWAV; }
00512 
00516     PString GetFormatString() const
00517     { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00518 
00522     void SetAutoconvert();
00523 
00525  
00526     friend class PWAVFileConverter;
00527 
00528     BOOL RawRead(void * buf, PINDEX len);
00529     BOOL RawWrite(const void * buf, PINDEX len);
00530 
00531     BOOL FileRead(void * buf, PINDEX len);
00532     BOOL FileWrite(const void * buf, PINDEX len);
00533 
00534     off_t RawGetPosition() const;
00535     BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00536     off_t RawGetDataLength();
00537 
00538     void SetLastReadCount(PINDEX v) { lastReadCount = v; } 
00539 
00540     PWAV::FMTChunk wavFmtChunk;
00541     PBYTEArray extendedHeader;
00542 
00543   protected:
00544     void Construct();
00545     void SelectFormat(unsigned fmt);
00546     void SelectFormat(const PString & format);
00547 
00548     PBYTEArray wavHeaderData;
00549 
00550     BOOL ProcessHeader();
00551     BOOL GenerateHeader();
00552     BOOL UpdateHeader();
00553 
00554     BOOL     isValidWAV;
00555 
00556     PWAVFileFormat * formatHandler;
00557 
00558     BOOL     autoConvert;
00559     PWAVFileConverter * autoConverter;
00560 
00561     off_t lenHeader;
00562     off_t lenData;
00563 
00564     BOOL     header_needs_updating;
00565 };
00566 
00567 #endif
00568 
00569 // End Of File ///////////////////////////////////////////////////////////////

Generated on Thu Jun 15 15:24:28 2006 for PWLib by  doxygen 1.4.2