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