# pwavfile.h

Go to the documentation of this file.

    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: 27139 $
    00031  * $Author: rjongbloed $
    00032  * $Date: 2012-03-06 21:51:15 -0600 (Tue, 06 Mar 2012) $
    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
    00107   virtual bool CanSetChannels(unsigned channels) const = 0;
    00108
    00111   virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
    00112
    00115   virtual void UpdateHeader(PWAV::FMTChunk & /*header*/, PBYTEArray & /*extendedHeader*/)
    00116   { }
    00117
    00120   virtual PBoolean WriteExtraChunks(PWAVFile & /*file*/)
    00121   { return true; }
    00122
    00125   virtual PBoolean ReadExtraChunks(PWAVFile & /*file*/)
    00126   { return true; }
    00127
    00130   virtual void OnStart()
    00131   { }
    00132
    00135   virtual void OnStop()
    00136   { }
    00137
    00140   virtual PBoolean Read(PWAVFile & file, void * buf, PINDEX & len);
    00141
    00144   virtual PBoolean Write(PWAVFile & file, const void * buf, PINDEX & len);
    00145 };
    00146
    00147 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
    00148 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
    00149
    00150 PFACTORY_LOAD(PWAVFileFormatPCM);
    00151
    00152
    00155 class PWAVFileConverter
    00156 {
    00157 public:
    00158   virtual ~PWAVFileConverter() { }
    00159   virtual unsigned GetFormat    (const PWAVFile & file) const = 0;
    00160   virtual off_t GetPosition     (const PWAVFile & file) const = 0;
    00161   virtual PBoolean SetPosition      (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
    00162   virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
    00163   virtual off_t GetDataLength   (PWAVFile & file) = 0;
    00164   virtual PBoolean Read             (PWAVFile & file, void * buf, PINDEX len)  = 0;
    00165   virtual PBoolean Write            (PWAVFile & file, const void * buf, PINDEX len) = 0;
    00166 };
    00167
    00168 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
    00169
    00172 class PWAVFile : public PFile
    00173 {
    00174   PCLASSINFO(PWAVFile, PFile);
    00175
    00176 public:
    00182   enum WaveType {
    00183     fmt_PCM         = 1,
    00184     fmt_MSADPCM     = 2,
    00185     fmt_ALaw        = 6,
    00186     fmt_uLaw        = 7,
    00187     fmt_VOXADPCM    = 0x10,
    00188     fmt_IMAADPCM    = 0x11,
    00189     fmt_GSM         = 0x31,
    00190     fmt_G728        = 0x41,
    00191     fmt_G723        = 0x42,
    00192     fmt_MSG7231     = 0x42,
    00193     fmt_G726        = 0x64,
    00194     fmt_G722        = 0x65,
    00195     fmt_G729        = 0x83,
    00196     fmt_VivoG7231   = 0x111,
    00197
    00198     // For backward compatibility
    00199     PCM_WavFile     = fmt_PCM,
    00200     G7231_WavFile   = fmt_VivoG7231,
    00201
    00202     // allow opening files without knowing the format
    00203     fmt_NotKnown    = 0x10000
    00204   };
    00205
    00215   PWAVFile(
    00216     unsigned format = fmt_PCM
    00217   );
    00218
    00231   PWAVFile(
    00232     OpenMode mode,
    00233     int opts = ModeDefault,
    00234     unsigned format = fmt_PCM
    00235   );
    00236
    00246   PWAVFile(
    00247     const PFilePath & name,
    00248     OpenMode mode = ReadWrite,
    00249     int opts = ModeDefault,
    00250     unsigned format = fmt_PCM
    00251   );
    00252
    00253   PWAVFile(
    00254     const PString & format,
    00255     const PFilePath & name,
    00256     OpenMode mode = PFile::ReadWrite,
    00257     int opts = PFile::ModeDefault
    00258   );
    00259
    00262   ~PWAVFile();
    00264
    00274   virtual PBoolean Read(
    00275     void * buf,
    00276     PINDEX len
    00277   );
    00278
    00286   virtual PBoolean Write(
    00287     const void * buf,
    00288     PINDEX len
    00289   );
    00290
    00303   virtual PBoolean Open(
    00304     OpenMode mode = ReadWrite,
    00305     int opts = ModeDefault
    00306   );
    00307
    00321   virtual PBoolean Open(
    00322     const PFilePath & name,
    00323     OpenMode mode = ReadWrite,
    00324     int opts = ModeDefault
    00325   );
    00326
    00332   virtual PBoolean Close();
    00333
    00348   virtual PBoolean SetPosition(
    00349     off_t pos,
    00350     FilePositionOrigin origin = Start
    00351   );
    00352
    00360   virtual off_t GetPosition() const;
    00362
    00367   virtual PBoolean SetFormat(unsigned fmt);
    00368   virtual PBoolean SetFormat(const PString & format);
    00369
    00372   virtual unsigned GetFormat() const;
    00373   virtual PString GetFormatAsString() const;
    00374
    00378   virtual unsigned GetChannels() const;
    00379   virtual void SetChannels(unsigned v);
    00380
    00383   virtual unsigned GetSampleRate() const;
    00384   virtual void SetSampleRate(unsigned v);
    00385
    00388   virtual unsigned GetSampleSize() const;
    00389   virtual void SetSampleSize(unsigned v);
    00390
    00393   virtual unsigned GetBytesPerSecond() const;
    00394   virtual void SetBytesPerSecond(unsigned v);
    00395
    00398   off_t GetHeaderLength() const;
    00399
    00402   virtual off_t GetDataLength();
    00403
    00410   PBoolean IsValid() const { return isValidWAV; }
    00411
    00414   PString GetFormatString() const
    00415   { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
    00416
    00419   void SetAutoconvert();
    00420
    00422
    00423   PBoolean RawRead(void * buf, PINDEX len);
    00424   PBoolean RawWrite(const void * buf, PINDEX len);
    00425
    00426   PBoolean FileRead(void * buf, PINDEX len);
    00427   PBoolean FileWrite(const void * buf, PINDEX len);
    00428
    00429   off_t RawGetPosition() const;
    00430   PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin);
    00431   off_t RawGetDataLength();
    00432
    00433   void SetLastReadCount(PINDEX v) { lastReadCount = v; }
    00434   void SetLastWriteCount(PINDEX v) { lastWriteCount = v; }
    00435
    00436   // Restored for backward compatibility reasons
    00437   static PWAVFile * format(const PString & format);
    00438   static PWAVFile * format(const PString & format, PFile::OpenMode mode, int opts = PFile::ModeDefault);
    00439
    00440
    00441 protected:
    00442   void Construct();
    00443   bool SelectFormat(unsigned fmt);
    00444   bool SelectFormat(const PString & format);
    00445
    00446   PBoolean ProcessHeader();
    00447   PBoolean GenerateHeader();
    00448   PBoolean UpdateHeader();
    00449
    00450   PBYTEArray wavHeaderData;
    00451   PWAV::FMTChunk wavFmtChunk;
    00452   PBYTEArray extendedHeader;
    00453
    00454   bool     isValidWAV;
    00455
    00456   unsigned int origFmt;
    00457   PWAVFileFormat * formatHandler;
    00458
    00459   PBoolean     autoConvert;
    00460   PWAVFileConverter * autoConverter;
    00461
    00462   off_t lenHeader;
    00463   off_t lenData;
    00464
    00465   bool     header_needs_updating;
    00466
    00467 friend class PWAVFileConverter;
    00468 };
    00469
    00470 #endif // PTLIB_PWAVFILE_H
    00471
    00472 // End Of File ///////////////////////////////////////////////////////////////