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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 #ifndef _PWAVFILE
00151 #define _PWAVFILE
00152
00153
00154
00155
00156
00157 #include <ptlib.h>
00158 #include <ptlib/pfactory.h>
00159
00160 class PWAVFile;
00161
00162 namespace PWAV {
00163
00164 #ifdef __GNUC__
00165 #define P_PACKED __attribute__ ((packed));
00166 #else
00167 #define P_PACKED
00168 #pragma pack(1)
00169 #endif
00170
00171 struct ChunkHeader
00172 {
00173 char tag[4];
00174 PInt32l len P_PACKED;
00175 };
00176
00177 struct RIFFChunkHeader
00178 {
00179 ChunkHeader hdr;
00180 char tag[4];
00181 };
00182
00183 struct FMTChunk
00184 {
00185 ChunkHeader hdr;
00186 PUInt16l format P_PACKED;
00187 PUInt16l numChannels P_PACKED;
00188 PUInt32l sampleRate P_PACKED;
00189 PUInt32l bytesPerSec P_PACKED;
00190 PUInt16l bytesPerSample P_PACKED;
00191 PUInt16l bitsPerSample P_PACKED;
00192 };
00193
00194 };
00195
00196 #ifdef __GNUC__
00197 #undef P_PACKED
00198 #else
00199 #pragma pack()
00200 #endif
00201
00205 class PWAVFileFormat
00206 {
00207 public:
00208 virtual ~PWAVFileFormat() { }
00209
00213 virtual unsigned GetFormat() const = 0;
00214
00218 virtual PString GetFormatString() const = 0;
00219
00223 virtual PString GetDescription() const = 0;
00224
00228 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00229
00233 virtual BOOL WriteExtraChunks(PWAVFile & )
00234 { return TRUE; }
00235
00239 virtual BOOL ReadExtraChunks(PWAVFile & )
00240 { return TRUE; }
00241
00245 virtual void OnStart()
00246 { }
00247
00251 virtual void OnStop()
00252 { }
00253
00257 virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00258
00262 virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00263 };
00264
00265 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00266 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00267
00271 class PWAVFileConverter
00272 {
00273 public:
00274 virtual ~PWAVFileConverter() { }
00275 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00276 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00277 virtual BOOL SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00278 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00279 virtual off_t GetDataLength (PWAVFile & file) = 0;
00280 virtual BOOL Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00281 virtual BOOL Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00282 };
00283
00284 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00285
00288 class PWAVFile : public PFile
00289 {
00290 PCLASSINFO(PWAVFile, PFile);
00291
00292 public:
00298 enum {
00299 fmt_PCM = 1,
00300 fmt_ALaw = 6,
00301 fmt_uLaw = 7,
00302 fmt_GSM = 0x31,
00303 fmt_G728 = 0x41,
00304 fmt_G723 = 0x42,
00305 fmt_MSG7231 = 0x42,
00306 fmt_G726 = 0x64,
00307 fmt_G722 = 0x65,
00308 fmt_G729 = 0x84,
00309 fmt_VivoG7231 = 0x111,
00310
00311
00312 PCM_WavFile = fmt_PCM,
00313 G7231_WavFile = fmt_VivoG7231,
00314
00315
00316 fmt_NotKnown = 0x10000
00317 };
00318
00328 PWAVFile(
00329 unsigned format = fmt_PCM
00330 );
00331 static PWAVFile * format(
00332 const PString & format
00333 );
00334
00347 PWAVFile(
00348 OpenMode mode,
00349 int opts = ModeDefault,
00350 unsigned format = fmt_PCM
00351 );
00352 static PWAVFile * format(
00353 const PString & format,
00354 PFile::OpenMode mode,
00355 int opts = PFile::ModeDefault
00356 );
00357
00367 PWAVFile(
00368 const PFilePath & name,
00369 OpenMode mode = ReadWrite,
00370 int opts = ModeDefault,
00371 unsigned format = fmt_PCM
00372 );
00373 PWAVFile(
00374 const PString & format,
00375 const PFilePath & name,
00376 OpenMode mode = PFile::ReadWrite,
00377 int opts = PFile::ModeDefault
00378 );
00379
00382 ~PWAVFile();
00384
00394 virtual BOOL Read(
00395 void * buf,
00396 PINDEX len
00397 );
00398
00406 virtual BOOL Write(
00407 const void * buf,
00408 PINDEX len
00409 );
00410
00422 virtual BOOL Open(
00423 OpenMode mode = ReadWrite,
00424 int opts = ModeDefault
00425 );
00426
00440 virtual BOOL Open(
00441 const PFilePath & name,
00442 OpenMode mode = ReadWrite,
00443 int opts = ModeDefault
00444 );
00445
00451 virtual BOOL Close();
00452
00467 virtual BOOL SetPosition(
00468 off_t pos,
00469 FilePositionOrigin origin = Start
00470 );
00471
00479 virtual off_t GetPosition() const;
00481
00486 virtual BOOL SetFormat(unsigned fmt);
00487 virtual BOOL SetFormat(const PString & format);
00488
00491 virtual unsigned GetFormat() const;
00492 virtual PString GetFormatAsString() const;
00493
00497 virtual unsigned GetChannels() const;
00498 virtual void SetChannels(unsigned v);
00499
00502 virtual unsigned GetSampleRate() const;
00503 virtual void SetSampleRate(unsigned v);
00504
00507 virtual unsigned GetSampleSize() const;
00508 virtual void SetSampleSize(unsigned v);
00509
00512 off_t GetHeaderLength() const;
00513
00516 virtual off_t GetDataLength();
00517
00524 BOOL IsValid() const { return isValidWAV; }
00525
00529 PString GetFormatString() const
00530 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00531
00535 void SetAutoconvert();
00536
00538
00539 friend class PWAVFileConverter;
00540
00541 BOOL RawRead(void * buf, PINDEX len);
00542 BOOL RawWrite(const void * buf, PINDEX len);
00543
00544 BOOL FileRead(void * buf, PINDEX len);
00545 BOOL FileWrite(const void * buf, PINDEX len);
00546
00547 off_t RawGetPosition() const;
00548 BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00549 off_t RawGetDataLength();
00550
00551 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00552
00553 PWAV::FMTChunk wavFmtChunk;
00554 PBYTEArray extendedHeader;
00555
00556 protected:
00557 void Construct();
00558 void SelectFormat(unsigned fmt);
00559 void SelectFormat(const PString & format);
00560
00561 PBYTEArray wavHeaderData;
00562
00563 BOOL ProcessHeader();
00564 BOOL GenerateHeader();
00565 BOOL UpdateHeader();
00566
00567 BOOL isValidWAV;
00568
00569 unsigned int origFmt;
00570 PWAVFileFormat * formatHandler;
00571
00572 BOOL autoConvert;
00573 PWAVFileConverter * autoConverter;
00574
00575 off_t lenHeader;
00576 off_t lenData;
00577
00578 BOOL header_needs_updating;
00579 };
00580
00581 #endif
00582
00583