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
00149 class PWAVFileConverter
00150 {
00151 public:
00152 virtual ~PWAVFileConverter() { }
00153 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00154 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00155 virtual PBoolean SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00156 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00157 virtual off_t GetDataLength (PWAVFile & file) = 0;
00158 virtual PBoolean Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00159 virtual PBoolean Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00160 };
00161
00162 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00163
00166 class PWAVFile : public PFile
00167 {
00168 PCLASSINFO(PWAVFile, PFile);
00169
00170 public:
00176 enum WaveType {
00177 fmt_PCM = 1,
00178 fmt_MSADPCM = 2,
00179 fmt_ALaw = 6,
00180 fmt_uLaw = 7,
00181 fmt_VOXADPCM = 0x10,
00182 fmt_IMAADPCM = 0x11,
00183 fmt_GSM = 0x31,
00184 fmt_G728 = 0x41,
00185 fmt_G723 = 0x42,
00186 fmt_MSG7231 = 0x42,
00187 fmt_G726 = 0x64,
00188 fmt_G722 = 0x65,
00189 fmt_G729 = 0x83,
00190 fmt_VivoG7231 = 0x111,
00191
00192
00193 PCM_WavFile = fmt_PCM,
00194 G7231_WavFile = fmt_VivoG7231,
00195
00196
00197 fmt_NotKnown = 0x10000
00198 };
00199
00209 PWAVFile(
00210 unsigned format = fmt_PCM
00211 );
00212 static PWAVFile * format(
00213 const PString & format
00214 );
00215
00228 PWAVFile(
00229 OpenMode mode,
00230 int opts = ModeDefault,
00231 unsigned format = fmt_PCM
00232 );
00233 static PWAVFile * format(
00234 const PString & format,
00235 PFile::OpenMode mode,
00236 int opts = PFile::ModeDefault
00237 );
00238
00248 PWAVFile(
00249 const PFilePath & name,
00250 OpenMode mode = ReadWrite,
00251 int opts = ModeDefault,
00252 unsigned format = fmt_PCM
00253 );
00254
00255 PWAVFile(
00256 const PString & format,
00257 const PFilePath & name,
00258 OpenMode mode = PFile::ReadWrite,
00259 int opts = PFile::ModeDefault
00260 );
00261
00264 ~PWAVFile();
00266
00276 virtual PBoolean Read(
00277 void * buf,
00278 PINDEX len
00279 );
00280
00288 virtual PBoolean Write(
00289 const void * buf,
00290 PINDEX len
00291 );
00292
00305 virtual PBoolean Open(
00306 OpenMode mode = ReadWrite,
00307 int opts = ModeDefault
00308 );
00309
00323 virtual PBoolean Open(
00324 const PFilePath & name,
00325 OpenMode mode = ReadWrite,
00326 int opts = ModeDefault
00327 );
00328
00334 virtual PBoolean Close();
00335
00350 virtual PBoolean SetPosition(
00351 off_t pos,
00352 FilePositionOrigin origin = Start
00353 );
00354
00362 virtual off_t GetPosition() const;
00364
00369 virtual PBoolean SetFormat(unsigned fmt);
00370 virtual PBoolean SetFormat(const PString & format);
00371
00374 virtual unsigned GetFormat() const;
00375 virtual PString GetFormatAsString() const;
00376
00380 virtual unsigned GetChannels() const;
00381 virtual void SetChannels(unsigned v);
00382
00385 virtual unsigned GetSampleRate() const;
00386 virtual void SetSampleRate(unsigned v);
00387
00390 virtual unsigned GetSampleSize() const;
00391 virtual void SetSampleSize(unsigned v);
00392
00395 virtual unsigned GetBytesPerSecond() const;
00396 virtual void SetBytesPerSecond(unsigned v);
00397
00400 off_t GetHeaderLength() const;
00401
00404 virtual off_t GetDataLength();
00405
00412 PBoolean IsValid() const { return isValidWAV; }
00413
00416 PString GetFormatString() const
00417 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00418
00421 void SetAutoconvert();
00422
00424
00425 friend class PWAVFileConverter;
00426
00427 PBoolean RawRead(void * buf, PINDEX len);
00428 PBoolean RawWrite(const void * buf, PINDEX len);
00429
00430 PBoolean FileRead(void * buf, PINDEX len);
00431 PBoolean FileWrite(const void * buf, PINDEX len);
00432
00433 off_t RawGetPosition() const;
00434 PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin);
00435 off_t RawGetDataLength();
00436
00437 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00438
00439 PWAV::FMTChunk wavFmtChunk;
00440 PBYTEArray extendedHeader;
00441
00442 protected:
00443 void Construct();
00444 void SelectFormat(unsigned fmt);
00445 void SelectFormat(const PString & format);
00446
00447 PBYTEArray wavHeaderData;
00448
00449 PBoolean ProcessHeader();
00450 PBoolean GenerateHeader();
00451 PBoolean UpdateHeader();
00452
00453 PBoolean isValidWAV;
00454
00455 unsigned int origFmt;
00456 PWAVFileFormat * formatHandler;
00457
00458 PBoolean autoConvert;
00459 PWAVFileConverter * autoConverter;
00460
00461 off_t lenHeader;
00462 off_t lenData;
00463
00464 PBoolean header_needs_updating;
00465 };
00466
00467 #endif // PTLIB_PWAVFILE_H
00468
00469