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 PTLIB_PWAVFILE_H
00036 #define PTLIB_PWAVFILE_H
00037
00038
00039
00040
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 };
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 & , PBYTEArray & )
00113 { }
00114
00117 virtual PBoolean WriteExtraChunks(PWAVFile & )
00118 { return true; }
00119
00122 virtual PBoolean ReadExtraChunks(PWAVFile & )
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
00196 PCM_WavFile = fmt_PCM,
00197 G7231_WavFile = fmt_VivoG7231,
00198
00199
00200 fmt_NotKnown = 0x10000
00201 };
00202
00212 PWAVFile(
00213 unsigned format = fmt_PCM
00214 );
00215 static PWAVFile * format(
00216 const PString & format
00217 );
00218
00231 PWAVFile(
00232 OpenMode mode,
00233 int opts = ModeDefault,
00234 unsigned format = fmt_PCM
00235 );
00236 static PWAVFile * format(
00237 const PString & format,
00238 PFile::OpenMode mode,
00239 int opts = PFile::ModeDefault
00240 );
00241
00251 PWAVFile(
00252 const PFilePath & name,
00253 OpenMode mode = ReadWrite,
00254 int opts = ModeDefault,
00255 unsigned format = fmt_PCM
00256 );
00257
00258 PWAVFile(
00259 const PString & format,
00260 const PFilePath & name,
00261 OpenMode mode = PFile::ReadWrite,
00262 int opts = PFile::ModeDefault
00263 );
00264
00267 ~PWAVFile();
00269
00279 virtual PBoolean Read(
00280 void * buf,
00281 PINDEX len
00282 );
00283
00291 virtual PBoolean Write(
00292 const void * buf,
00293 PINDEX len
00294 );
00295
00308 virtual PBoolean Open(
00309 OpenMode mode = ReadWrite,
00310 int opts = ModeDefault
00311 );
00312
00326 virtual PBoolean Open(
00327 const PFilePath & name,
00328 OpenMode mode = ReadWrite,
00329 int opts = ModeDefault
00330 );
00331
00337 virtual PBoolean Close();
00338
00353 virtual PBoolean SetPosition(
00354 off_t pos,
00355 FilePositionOrigin origin = Start
00356 );
00357
00365 virtual off_t GetPosition() const;
00367
00372 virtual PBoolean SetFormat(unsigned fmt);
00373 virtual PBoolean SetFormat(const PString & format);
00374
00377 virtual unsigned GetFormat() const;
00378 virtual PString GetFormatAsString() const;
00379
00383 virtual unsigned GetChannels() const;
00384 virtual void SetChannels(unsigned v);
00385
00388 virtual unsigned GetSampleRate() const;
00389 virtual void SetSampleRate(unsigned v);
00390
00393 virtual unsigned GetSampleSize() const;
00394 virtual void SetSampleSize(unsigned v);
00395
00398 virtual unsigned GetBytesPerSecond() const;
00399 virtual void SetBytesPerSecond(unsigned v);
00400
00403 off_t GetHeaderLength() const;
00404
00407 virtual off_t GetDataLength();
00408
00415 PBoolean IsValid() const { return isValidWAV; }
00416
00419 PString GetFormatString() const
00420 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00421
00424 void SetAutoconvert();
00425
00427
00428 friend class PWAVFileConverter;
00429
00430 PBoolean RawRead(void * buf, PINDEX len);
00431 PBoolean RawWrite(const void * buf, PINDEX len);
00432
00433 PBoolean FileRead(void * buf, PINDEX len);
00434 PBoolean FileWrite(const void * buf, PINDEX len);
00435
00436 off_t RawGetPosition() const;
00437 PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin);
00438 off_t RawGetDataLength();
00439
00440 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00441 void SetLastWriteCount(PINDEX v) { lastWriteCount = v; }
00442
00443 PWAV::FMTChunk wavFmtChunk;
00444 PBYTEArray extendedHeader;
00445
00446 protected:
00447 void Construct();
00448 bool SelectFormat(unsigned fmt);
00449 bool SelectFormat(const PString & format);
00450
00451 PBYTEArray wavHeaderData;
00452
00453 PBoolean ProcessHeader();
00454 PBoolean GenerateHeader();
00455 PBoolean UpdateHeader();
00456
00457 PBoolean isValidWAV;
00458
00459 unsigned int origFmt;
00460 PWAVFileFormat * formatHandler;
00461
00462 PBoolean autoConvert;
00463 PWAVFileConverter * autoConverter;
00464
00465 off_t lenHeader;
00466 off_t lenData;
00467
00468 PBoolean header_needs_updating;
00469 };
00470
00471 #endif // PTLIB_PWAVFILE_H
00472
00473