PTLib
Version 2.10.4
|
00001 /* 00002 * pwavfile.h 00003 * 00004 * WAV file I/O channel class. 00005 * 00006 * Portable Tools 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 * $Revision: 26303 $ 00031 * $Author: rjongbloed $ 00032 * $Date: 2011-08-12 03:44:54 -0500 (Fri, 12 Aug 2011) $ 00033 */ 00034 00035 #ifndef PTLIB_PWAVFILE_H 00036 #define PTLIB_PWAVFILE_H 00037 00038 //#ifdef P_USE_PRAGMA 00039 //#pragma interface 00040 //#endif 00041 00042 00043 #include <ptlib/pfactory.h> 00044 00045 class PWAVFile; 00046 00047 namespace PWAV { 00048 00049 #ifdef __GNUC__ 00050 #define P_PACKED __attribute__ ((packed)); 00051 #else 00052 #define P_PACKED 00053 #pragma pack(1) 00054 #endif 00055 00056 struct ChunkHeader 00057 { 00058 char tag[4]; 00059 PInt32l len P_PACKED; 00060 }; 00061 00062 struct RIFFChunkHeader 00063 { 00064 ChunkHeader hdr; 00065 char tag[4]; 00066 }; 00067 00068 struct FMTChunk 00069 { 00070 ChunkHeader hdr; 00071 PUInt16l format P_PACKED; 00072 PUInt16l numChannels P_PACKED; 00073 PUInt32l sampleRate P_PACKED; 00074 PUInt32l bytesPerSec P_PACKED; 00075 PUInt16l bytesPerSample P_PACKED; 00076 PUInt16l bitsPerSample P_PACKED; 00077 }; 00078 00079 }; // namespace PWAV 00080 00081 #ifdef __GNUC__ 00082 #undef P_PACKED 00083 #else 00084 #pragma pack() 00085 #endif 00086 00089 class PWAVFileFormat 00090 { 00091 public: 00092 virtual ~PWAVFileFormat() { } 00093 00096 virtual unsigned GetFormat() const = 0; 00097 00100 virtual PString GetFormatString() const = 0; 00101 00104 virtual PString GetDescription() const = 0; 00105 00108 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0; 00109 00112 virtual void UpdateHeader(PWAV::FMTChunk & /*header*/, PBYTEArray & /*extendedHeader*/) 00113 { } 00114 00117 virtual PBoolean WriteExtraChunks(PWAVFile & /*file*/) 00118 { return true; } 00119 00122 virtual PBoolean ReadExtraChunks(PWAVFile & /*file*/) 00123 { return true; } 00124 00127 virtual void OnStart() 00128 { } 00129 00132 virtual void OnStop() 00133 { } 00134 00137 virtual PBoolean Read(PWAVFile & file, void * buf, PINDEX & len); 00138 00141 virtual PBoolean Write(PWAVFile & file, const void * buf, PINDEX & len); 00142 }; 00143 00144 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory; 00145 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory; 00146 00147 PFACTORY_LOAD(PWAVFileFormatPCM); 00148 00149 00152 class PWAVFileConverter 00153 { 00154 public: 00155 virtual ~PWAVFileConverter() { } 00156 virtual unsigned GetFormat (const PWAVFile & file) const = 0; 00157 virtual off_t GetPosition (const PWAVFile & file) const = 0; 00158 virtual PBoolean SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0; 00159 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0; 00160 virtual off_t GetDataLength (PWAVFile & file) = 0; 00161 virtual PBoolean Read (PWAVFile & file, void * buf, PINDEX len) = 0; 00162 virtual PBoolean Write (PWAVFile & file, const void * buf, PINDEX len) = 0; 00163 }; 00164 00165 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory; 00166 00169 class PWAVFile : public PFile 00170 { 00171 PCLASSINFO(PWAVFile, PFile); 00172 00173 public: 00179 enum WaveType { 00180 fmt_PCM = 1, 00181 fmt_MSADPCM = 2, 00182 fmt_ALaw = 6, 00183 fmt_uLaw = 7, 00184 fmt_VOXADPCM = 0x10, 00185 fmt_IMAADPCM = 0x11, 00186 fmt_GSM = 0x31, 00187 fmt_G728 = 0x41, 00188 fmt_G723 = 0x42, 00189 fmt_MSG7231 = 0x42, 00190 fmt_G726 = 0x64, 00191 fmt_G722 = 0x65, 00192 fmt_G729 = 0x83, 00193 fmt_VivoG7231 = 0x111, 00194 00195 // For backward compatibility 00196 PCM_WavFile = fmt_PCM, 00197 G7231_WavFile = fmt_VivoG7231, 00198 00199 // allow opening files without knowing the format 00200 fmt_NotKnown = 0x10000 00201 }; 00202 00212 PWAVFile( 00213 unsigned format = fmt_PCM 00214 ); 00215 00228 PWAVFile( 00229 OpenMode mode, 00230 int opts = ModeDefault, 00231 unsigned format = fmt_PCM 00232 ); 00233 00243 PWAVFile( 00244 const PFilePath & name, 00245 OpenMode mode = ReadWrite, 00246 int opts = ModeDefault, 00247 unsigned format = fmt_PCM 00248 ); 00249 00250 PWAVFile( 00251 const PString & format, 00252 const PFilePath & name, 00253 OpenMode mode = PFile::ReadWrite, 00254 int opts = PFile::ModeDefault 00255 ); 00256 00259 ~PWAVFile(); 00261 00271 virtual PBoolean Read( 00272 void * buf, 00273 PINDEX len 00274 ); 00275 00283 virtual PBoolean Write( 00284 const void * buf, 00285 PINDEX len 00286 ); 00287 00300 virtual PBoolean Open( 00301 OpenMode mode = ReadWrite, 00302 int opts = ModeDefault 00303 ); 00304 00318 virtual PBoolean Open( 00319 const PFilePath & name, 00320 OpenMode mode = ReadWrite, 00321 int opts = ModeDefault 00322 ); 00323 00329 virtual PBoolean Close(); 00330 00345 virtual PBoolean SetPosition( 00346 off_t pos, 00347 FilePositionOrigin origin = Start 00348 ); 00349 00357 virtual off_t GetPosition() const; 00359 00364 virtual PBoolean SetFormat(unsigned fmt); 00365 virtual PBoolean SetFormat(const PString & format); 00366 00369 virtual unsigned GetFormat() const; 00370 virtual PString GetFormatAsString() const; 00371 00375 virtual unsigned GetChannels() const; 00376 virtual void SetChannels(unsigned v); 00377 00380 virtual unsigned GetSampleRate() const; 00381 virtual void SetSampleRate(unsigned v); 00382 00385 virtual unsigned GetSampleSize() const; 00386 virtual void SetSampleSize(unsigned v); 00387 00390 virtual unsigned GetBytesPerSecond() const; 00391 virtual void SetBytesPerSecond(unsigned v); 00392 00395 off_t GetHeaderLength() const; 00396 00399 virtual off_t GetDataLength(); 00400 00407 PBoolean IsValid() const { return isValidWAV; } 00408 00411 PString GetFormatString() const 00412 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); } 00413 00416 void SetAutoconvert(); 00417 00419 00420 PBoolean RawRead(void * buf, PINDEX len); 00421 PBoolean RawWrite(const void * buf, PINDEX len); 00422 00423 PBoolean FileRead(void * buf, PINDEX len); 00424 PBoolean FileWrite(const void * buf, PINDEX len); 00425 00426 off_t RawGetPosition() const; 00427 PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin); 00428 off_t RawGetDataLength(); 00429 00430 void SetLastReadCount(PINDEX v) { lastReadCount = v; } 00431 void SetLastWriteCount(PINDEX v) { lastWriteCount = v; } 00432 00433 // Restored for backward compatibility reasons 00434 static PWAVFile * format(const PString & format); 00435 static PWAVFile * format(const PString & format, PFile::OpenMode mode, int opts = PFile::ModeDefault); 00436 00437 00438 protected: 00439 void Construct(); 00440 bool SelectFormat(unsigned fmt); 00441 bool SelectFormat(const PString & format); 00442 00443 PBoolean ProcessHeader(); 00444 PBoolean GenerateHeader(); 00445 PBoolean UpdateHeader(); 00446 00447 PBYTEArray wavHeaderData; 00448 PWAV::FMTChunk wavFmtChunk; 00449 PBYTEArray extendedHeader; 00450 00451 bool isValidWAV; 00452 00453 unsigned int origFmt; 00454 PWAVFileFormat * formatHandler; 00455 00456 PBoolean autoConvert; 00457 PWAVFileConverter * autoConverter; 00458 00459 off_t lenHeader; 00460 off_t lenData; 00461 00462 bool header_needs_updating; 00463 00464 friend class PWAVFileConverter; 00465 }; 00466 00467 #endif // PTLIB_PWAVFILE_H 00468 00469 // End Of File ///////////////////////////////////////////////////////////////