00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _PWAVFILE
00036 #define _PWAVFILE
00037
00038
00039
00040
00041
00042 #ifndef _PTLIB_H
00043 #include <ptlib.h>
00044 #endif
00045
00046 #include <ptlib/pfactory.h>
00047
00048 class PWAVFile;
00049
00050 namespace PWAV {
00051
00052 #ifdef __GNUC__
00053 #define P_PACKED __attribute__ ((packed));
00054 #else
00055 #define P_PACKED
00056 #pragma pack(1)
00057 #endif
00058
00059 struct ChunkHeader
00060 {
00061 char tag[4];
00062 PInt32l len P_PACKED;
00063 };
00064
00065 struct RIFFChunkHeader
00066 {
00067 ChunkHeader hdr;
00068 char tag[4];
00069 };
00070
00071 struct FMTChunk
00072 {
00073 ChunkHeader hdr;
00074 PUInt16l format P_PACKED;
00075 PUInt16l numChannels P_PACKED;
00076 PUInt32l sampleRate P_PACKED;
00077 PUInt32l bytesPerSec P_PACKED;
00078 PUInt16l bytesPerSample P_PACKED;
00079 PUInt16l bitsPerSample P_PACKED;
00080 };
00081
00082 };
00083
00084 #ifdef __GNUC__
00085 #undef P_PACKED
00086 #else
00087 #pragma pack()
00088 #endif
00089
00093 class PWAVFileFormat
00094 {
00095 public:
00096 virtual ~PWAVFileFormat() { }
00097
00101 virtual unsigned GetFormat() const = 0;
00102
00106 virtual PString GetFormatString() const = 0;
00107
00111 virtual PString GetDescription() const = 0;
00112
00116 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00117
00121 virtual void UpdateHeader(PWAV::FMTChunk & , PBYTEArray & )
00122 { }
00123
00127 virtual PBoolean WriteExtraChunks(PWAVFile & )
00128 { return PTrue; }
00129
00133 virtual PBoolean ReadExtraChunks(PWAVFile & )
00134 { return PTrue; }
00135
00139 virtual void OnStart()
00140 { }
00141
00145 virtual void OnStop()
00146 { }
00147
00151 virtual PBoolean Read(PWAVFile & file, void * buf, PINDEX & len);
00152
00156 virtual PBoolean Write(PWAVFile & file, const void * buf, PINDEX & len);
00157 };
00158
00159 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00160 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00161
00165 class PWAVFileConverter
00166 {
00167 public:
00168 virtual ~PWAVFileConverter() { }
00169 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00170 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00171 virtual PBoolean SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00172 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00173 virtual off_t GetDataLength (PWAVFile & file) = 0;
00174 virtual PBoolean Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00175 virtual PBoolean Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00176 };
00177
00178 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00179
00182 class PWAVFile : public PFile
00183 {
00184 PCLASSINFO(PWAVFile, PFile);
00185
00186 public:
00192 enum {
00193 fmt_PCM = 1,
00194 fmt_MSADPCM = 2,
00195 fmt_ALaw = 6,
00196 fmt_uLaw = 7,
00197 fmt_VOXADPCM = 0x10,
00198 fmt_IMAADPCM = 0x11,
00199 fmt_GSM = 0x31,
00200 fmt_G728 = 0x41,
00201 fmt_G723 = 0x42,
00202 fmt_MSG7231 = 0x42,
00203 fmt_G726 = 0x64,
00204 fmt_G722 = 0x65,
00205 fmt_G729 = 0x83,
00206 fmt_VivoG7231 = 0x111,
00207
00208
00209 PCM_WavFile = fmt_PCM,
00210 G7231_WavFile = fmt_VivoG7231,
00211
00212
00213 fmt_NotKnown = 0x10000
00214 };
00215
00225 PWAVFile(
00226 unsigned format = fmt_PCM
00227 );
00228 static PWAVFile * format(
00229 const PString & format
00230 );
00231
00244 PWAVFile(
00245 OpenMode mode,
00246 int opts = ModeDefault,
00247 unsigned format = fmt_PCM
00248 );
00249 static PWAVFile * format(
00250 const PString & format,
00251 PFile::OpenMode mode,
00252 int opts = PFile::ModeDefault
00253 );
00254
00264 PWAVFile(
00265 const PFilePath & name,
00266 OpenMode mode = ReadWrite,
00267 int opts = ModeDefault,
00268 unsigned format = fmt_PCM
00269 );
00270 PWAVFile(
00271 const PString & format,
00272 const PFilePath & name,
00273 OpenMode mode = PFile::ReadWrite,
00274 int opts = PFile::ModeDefault
00275 );
00276
00279 ~PWAVFile();
00281
00291 virtual PBoolean Read(
00292 void * buf,
00293 PINDEX len
00294 );
00295
00303 virtual PBoolean Write(
00304 const void * buf,
00305 PINDEX len
00306 );
00307
00319 virtual PBoolean Open(
00320 OpenMode mode = ReadWrite,
00321 int opts = ModeDefault
00322 );
00323
00337 virtual PBoolean Open(
00338 const PFilePath & name,
00339 OpenMode mode = ReadWrite,
00340 int opts = ModeDefault
00341 );
00342
00348 virtual PBoolean Close();
00349
00364 virtual PBoolean SetPosition(
00365 off_t pos,
00366 FilePositionOrigin origin = Start
00367 );
00368
00376 virtual off_t GetPosition() const;
00378
00383 virtual PBoolean SetFormat(unsigned fmt);
00384 virtual PBoolean SetFormat(const PString & format);
00385
00388 virtual unsigned GetFormat() const;
00389 virtual PString GetFormatAsString() const;
00390
00394 virtual unsigned GetChannels() const;
00395 virtual void SetChannels(unsigned v);
00396
00399 virtual unsigned GetSampleRate() const;
00400 virtual void SetSampleRate(unsigned v);
00401
00404 virtual unsigned GetSampleSize() const;
00405 virtual void SetSampleSize(unsigned v);
00406
00409 virtual unsigned GetBytesPerSecond() const;
00410 virtual void SetBytesPerSecond(unsigned v);
00411
00414 off_t GetHeaderLength() const;
00415
00418 virtual off_t GetDataLength();
00419
00426 PBoolean IsValid() const { return isValidWAV; }
00427
00431 PString GetFormatString() const
00432 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00433
00437 void SetAutoconvert();
00438
00440
00441 friend class PWAVFileConverter;
00442
00443 PBoolean RawRead(void * buf, PINDEX len);
00444 PBoolean RawWrite(const void * buf, PINDEX len);
00445
00446 PBoolean FileRead(void * buf, PINDEX len);
00447 PBoolean FileWrite(const void * buf, PINDEX len);
00448
00449 off_t RawGetPosition() const;
00450 PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin);
00451 off_t RawGetDataLength();
00452
00453 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00454
00455 PWAV::FMTChunk wavFmtChunk;
00456 PBYTEArray extendedHeader;
00457
00458 protected:
00459 void Construct();
00460 void SelectFormat(unsigned fmt);
00461 void SelectFormat(const PString & format);
00462
00463 PBYTEArray wavHeaderData;
00464
00465 PBoolean ProcessHeader();
00466 PBoolean GenerateHeader();
00467 PBoolean UpdateHeader();
00468
00469 PBoolean isValidWAV;
00470
00471 unsigned int origFmt;
00472 PWAVFileFormat * formatHandler;
00473
00474 PBoolean autoConvert;
00475 PWAVFileConverter * autoConverter;
00476
00477 off_t lenHeader;
00478 off_t lenData;
00479
00480 PBoolean header_needs_updating;
00481 };
00482
00483 #endif
00484
00485