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.16  2004/11/11 07:34:50  csoutheren
00032  * Added #include <ptlib.h>
00033  *
00034  * Revision 1.15  2004/11/08 04:07:40  csoutheren
00035  * Fixed crash opportunity under some conditions
00036  * Fixed incorrect WAV file type display
00037  *
00038  * Revision 1.14  2004/07/15 03:12:41  csoutheren
00039  * Migrated changes from crs_vxnml_devel branch into main trunk
00040  *
00041  * Revision 1.13.4.4  2004/07/13 08:13:04  csoutheren
00042  * Lots of implementation of factory-based PWAVFile
00043  *
00044  * Revision 1.13.4.3  2004/07/12 09:17:19  csoutheren
00045  * Fixed warnings and errors under Linux
00046  *
00047  * Revision 1.13.4.2  2004/07/12 08:30:16  csoutheren
00048  * More fixes for abstract factory implementation of PWAVFile
00049  *
00050  * Revision 1.13.4.1  2004/07/07 07:07:41  csoutheren
00051  * Changed PWAVFile to use abstract factories (extensively)
00052  * Removed redundant blocking/unblocking when using G.723.1
00053  * More support for call transfer
00054  *
00055  * Revision 1.13  2003/03/07 06:12:05  robertj
00056  * Added more WAV file "magic numbers".
00057  *
00058  * Revision 1.12  2002/09/16 01:08:59  robertj
00059  * Added #define so can select if #pragma interface/implementation is used on
00060  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00061  *
00062  * Revision 1.11  2002/06/20 00:51:38  craigs
00063  * Added virtuals to allow overriding
00064  *
00065  * Revision 1.10  2002/05/21 01:56:53  robertj
00066  * Removed the enum which made yet another set of magic numbers for audio
00067  *   formats, now uses the WAV file format numbers.
00068  * Fixed failure to write header when destroying object without and explicit
00069  *   call to Close().
00070  * Fixed missing Open() function which does not have file name parameter.
00071  * Added ability to set the audio format after construction.
00072  *
00073  * Revision 1.9  2002/01/22 03:55:07  craigs
00074  * Added #define guards when file moved to PTCLib
00075  *
00076  * Revision 1.8  2002/01/13 21:00:41  rogerh
00077  * The type of new .WAV files must now be specified in the class constructor.
00078  * Take out Open() function from the last commit and create a new Open()
00079  * function which replaces the one in the PFile base class.
00080  *
00081  * Revision 1.7  2002/01/11 16:33:46  rogerh
00082  * Create a PWAVFile Open() function, which processes the WAV header
00083  *
00084  * Revision 1.6  2001/10/16 13:27:37  rogerh
00085  * Add support for writing G.723.1 WAV files.
00086  * MS Windows can play G.723.1 WAV Files in Media Player and Sound Recorder.
00087  * Sound Recorder can also convert them to normal PCM format WAV files.
00088  * Thanks go to M.Stoychev <M.Stoychev@cnsys.bg> for sample WAV files.
00089  *
00090  * Revision 1.5  2001/10/15 11:48:15  rogerh
00091  * Add GetFormat to return the format of a WAV file
00092  *
00093  * Revision 1.4  2001/07/23 01:20:20  rogerh
00094  * Add updates from Shawn - ensure isvalidWAV is false for zero length files.
00095  * GetDataLength uses actual file size to support file updates as well as appends.
00096  * Add updates from Roger - Update Header() just writes to specific fields which
00097  * preserves any 'extra' data in an existing header between FORMAT and DATA chunks.
00098  *
00099  * Revision 1.3  2001/07/20 07:06:27  rogerh
00100  * Fix a typo
00101  *
00102  * Revision 1.2  2001/07/20 03:30:59  robertj
00103  * Minor cosmetic changes to new PWAVFile class.
00104  *
00105  * Revision 1.1  2001/07/19 09:55:48  rogerh
00106  * Add PWAVFile, a class to read and write .wav files, written by
00107  * Roger Hardiman and <roger@freebsd.org> and
00108  * Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
00109  *
00110  *
00111  */
00112 
00113 #ifndef _PWAVFILE
00114 #define _PWAVFILE
00115 
00116 //#ifdef P_USE_PRAGMA
00117 //#pragma interface
00118 //#endif
00119 
00120 #include <ptlib.h>
00121 
00122 class PWAVFile;
00123 
00124 namespace PWAV {
00125 
00126 #ifdef __GNUC__
00127 #define P_PACKED    __attribute__ ((packed));
00128 #else
00129 #define P_PACKED
00130 #pragma pack(1)
00131 #endif
00132 
00133 struct ChunkHeader
00134 {
00135   char    tag[4] P_PACKED;
00136   PInt32l len    P_PACKED;
00137 };
00138 
00139 struct RIFFChunkHeader 
00140 {
00141   ChunkHeader hdr    P_PACKED;
00142   char        tag[4] P_PACKED;
00143 };
00144 
00145 struct FMTChunk
00146 {
00147   ChunkHeader hdr          P_PACKED;  // chunk header
00148   PUInt16l format          P_PACKED;  // Format 
00149   PUInt16l numChannels     P_PACKED;  // Channels 0x01 = mono, 0x02 = stereo
00150   PUInt32l sampleRate      P_PACKED;  // Sample Rate in Hz
00151   PUInt32l bytesPerSec     P_PACKED;  // Average bytes Per Second
00152   PUInt16l bytesPerSample  P_PACKED;  // Bytes Per Sample, eg 2
00153   PUInt16l bitsPerSample   P_PACKED;  // Bits Per Sample, eg 16
00154 };
00155 
00156 }; // namespace PWAV
00157 
00158 #ifdef __GNUC__
00159 #undef P_PACKED
00160 #else
00161 #pragma pack()
00162 #endif
00163 
00167 class PWAVFileFormat
00168 {
00169   public:
00173     virtual unsigned GetFormat() const = 0;
00174 
00178     virtual PString GetFormatString() const = 0;
00179 
00183     virtual PString GetDescription() const = 0;
00184 
00188     virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00189 
00193     virtual BOOL WriteExtraChunks(PWAVFile & /*file*/)
00194     { return TRUE; }
00195 
00199     virtual BOOL ReadExtraChunks(PWAVFile & /*file*/)
00200     { return TRUE; }
00201 
00205     virtual void OnStart()
00206     { }
00207 
00211     virtual void OnStop()
00212     { }
00213 
00217     virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00218 
00222     virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00223 };
00224 
00225 typedef PFactory<PWAVFileFormat> PWAVFileFormatByFormatFactory;
00226 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00227 
00231 class PWAVFileConverter 
00232 {
00233   public:
00234     virtual unsigned GetFormat    (const PWAVFile & file) const = 0;
00235     virtual off_t GetPosition     (const PWAVFile & file) const = 0;
00236     virtual BOOL SetPosition      (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00237     virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00238     virtual off_t GetDataLength   (PWAVFile & file) = 0;
00239     virtual BOOL Read             (PWAVFile & file, void * buf, PINDEX len)  = 0;
00240     virtual BOOL Write            (PWAVFile & file, const void * buf, PINDEX len) = 0;
00241 };
00242 
00243 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00244 
00247 class PWAVFile : public PFile
00248 {
00249   PCLASSINFO(PWAVFile, PFile);
00250 
00251   public:
00257     enum {
00258       fmt_PCM         = 1,      
00259       fmt_ALaw        = 6,      
00260       fmt_uLaw        = 7,      
00261       fmt_GSM         = 0x31,   
00262       fmt_G728        = 0x41,   
00263       fmt_G723        = 0x42,   
00264       fmt_MSG7231     = 0x42,   
00265       fmt_G726        = 0x64,   
00266       fmt_G722        = 0x65,   
00267       fmt_G729        = 0x84,   
00268       fmt_VivoG7231   = 0x111,  
00269 
00270       // For backward compatibility
00271       PCM_WavFile     = fmt_PCM,
00272       G7231_WavFile   = fmt_VivoG7231,
00273 
00274       // allow opening files without knowing the format
00275       fmt_NotKnown    = 0x10000
00276     };
00277 
00287     PWAVFile(
00288       unsigned format = fmt_PCM 
00289     );
00290     static PWAVFile * format(
00291       const PString & format    
00292     );
00293 
00306     PWAVFile(
00307       OpenMode mode,          
00308       int opts = ModeDefault, 
00309       unsigned format = fmt_PCM 
00310     );
00311     static PWAVFile * format(
00312       const PString & format,  
00313       PFile::OpenMode mode,          
00314       int opts = PFile::ModeDefault 
00315     );
00316 
00326     PWAVFile(
00327       const PFilePath & name,     
00328       OpenMode mode = ReadWrite,  
00329       int opts = ModeDefault,     
00330       unsigned format = fmt_PCM 
00331     );
00332     PWAVFile(
00333       const PString & format,  
00334       const PFilePath & name,     
00335       OpenMode mode = PFile::ReadWrite,  
00336       int opts = PFile::ModeDefault     
00337     );
00338 
00341     ~PWAVFile() { Close(); }
00343 
00353     virtual BOOL Read(
00354       void * buf,   
00355       PINDEX len    
00356     );
00357 
00365     virtual BOOL Write(
00366       const void * buf,   
00367       PINDEX len    
00368     );
00369 
00381     virtual BOOL Open(
00382       OpenMode mode = ReadWrite,  // Mode in which to open the file.
00383       int opts = ModeDefault      // Options for open operation.
00384     );
00385 
00399     virtual BOOL Open(
00400       const PFilePath & name,    // Name of file to open.
00401       OpenMode mode = ReadWrite, // Mode in which to open the file.
00402       int opts = ModeDefault     // #OpenOptions enum# for open operation.
00403     );
00404 
00410     virtual BOOL Close();
00411 
00426     virtual BOOL SetPosition(
00427       off_t pos,                         
00428       FilePositionOrigin origin = Start  
00429     );
00430 
00438     virtual off_t GetPosition() const;
00440 
00445     virtual BOOL SetFormat(unsigned fmt);
00446     virtual BOOL SetFormat(const PString & format);
00447 
00450     virtual unsigned GetFormat() const;
00451     virtual PString GetFormatAsString() const;
00452 
00456     virtual unsigned GetChannels() const;
00457     virtual void SetChannels(unsigned v);
00458 
00461     virtual unsigned GetSampleRate() const;
00462     virtual void SetSampleRate(unsigned v);
00463 
00466     virtual unsigned GetSampleSize() const;
00467     virtual void SetSampleSize(unsigned v);
00468 
00471     off_t GetHeaderLength() const;
00472 
00475     virtual off_t GetDataLength();
00476 
00483     BOOL IsValid() const { return isValidWAV; }
00484 
00488     PString GetFormatString() const
00489     { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00490 
00494     void SetAutoconvert();
00495 
00497  
00498     friend class PWAVFileConverter;
00499 
00500     BOOL RawRead(void * buf, PINDEX len);
00501     BOOL RawWrite(const void * buf, PINDEX len);
00502 
00503     BOOL FileRead(void * buf, PINDEX len);
00504     BOOL FileWrite(const void * buf, PINDEX len);
00505 
00506     off_t RawGetPosition() const;
00507     BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00508     off_t RawGetDataLength();
00509 
00510     void SetLastReadCount(PINDEX v) { lastReadCount = v; } 
00511 
00512     PWAV::FMTChunk wavFmtChunk;
00513     PBYTEArray extendedHeader;
00514 
00515   protected:
00516     void Construct();
00517     void SelectFormat(unsigned fmt);
00518     void SelectFormat(const PString & format);
00519 
00520     PBYTEArray wavHeaderData;
00521 
00522     BOOL ProcessHeader();
00523     BOOL GenerateHeader();
00524     BOOL UpdateHeader();
00525 
00526     BOOL     isValidWAV;
00527 
00528     PWAVFileFormat * formatHandler;
00529 
00530     BOOL     autoConvert;
00531     PWAVFileConverter * autoConverter;
00532 
00533     off_t lenHeader;
00534     off_t lenData;
00535 
00536     BOOL     header_needs_updating;
00537 };
00538 
00539 #ifdef _WIN32
00540 
00541 #  ifndef P_DISABLE_FACTORY_INSTANCES
00542 
00543 #    ifndef  P_FACTORY_INSTANCE_PWAVFileConverter
00544 #      define P_FACTORY_INSTANCE_PWAVFileConverter 1
00545 #        pragma message("Including PWAVFileConverter factory loader")
00546          PLOAD_FACTORY(PWAVFileConverter, unsigned)
00547 #    endif
00548 
00549 #    ifndef  P_FACTORY_INSTANCE_PWAVFileFormat
00550 #      define P_FACTORY_INSTANCE_PWAVFileFormat 1
00551 #        pragma message("Including PWAVFileFormat factory loader")
00552          PLOAD_FACTORY(PWAVFileFormat, unsigned)
00553 #    endif
00554 
00555 # endif
00556 
00557 #endif
00558 
00559 
00560 #endif
00561 
00562 // End Of File ///////////////////////////////////////////////////////////////

Generated on Wed Sep 28 10:27:33 2005 for PWLib by  doxygen 1.4.4