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
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 & , PBYTEArray & )
00116 { }
00117
00120 virtual PBoolean WriteExtraChunks(PWAVFile & )
00121 { return true; }
00122
00125 virtual PBoolean ReadExtraChunks(PWAVFile & )
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
00199 PCM_WavFile = fmt_PCM,
00200 G7231_WavFile = fmt_VivoG7231,
00201
00202
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
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