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 #ifndef _PWAVFILE
00142 #define _PWAVFILE
00143
00144
00145
00146
00147
00148 #include <ptlib.h>
00149
00150 class PWAVFile;
00151
00152 namespace PWAV {
00153
00154 #ifdef __GNUC__
00155 #define P_PACKED __attribute__ ((packed));
00156 #else
00157 #define P_PACKED
00158 #pragma pack(1)
00159 #endif
00160
00161 struct ChunkHeader
00162 {
00163 char tag[4];
00164 PInt32l len P_PACKED;
00165 };
00166
00167 struct RIFFChunkHeader
00168 {
00169 ChunkHeader hdr;
00170 char tag[4];
00171 };
00172
00173 struct FMTChunk
00174 {
00175 ChunkHeader hdr;
00176 PUInt16l format P_PACKED;
00177 PUInt16l numChannels P_PACKED;
00178 PUInt32l sampleRate P_PACKED;
00179 PUInt32l bytesPerSec P_PACKED;
00180 PUInt16l bytesPerSample P_PACKED;
00181 PUInt16l bitsPerSample P_PACKED;
00182 };
00183
00184 };
00185
00186 #ifdef __GNUC__
00187 #undef P_PACKED
00188 #else
00189 #pragma pack()
00190 #endif
00191
00195 class PWAVFileFormat
00196 {
00197 public:
00198 virtual ~PWAVFileFormat() { }
00199
00203 virtual unsigned GetFormat() const = 0;
00204
00208 virtual PString GetFormatString() const = 0;
00209
00213 virtual PString GetDescription() const = 0;
00214
00218 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00219
00223 virtual BOOL WriteExtraChunks(PWAVFile & )
00224 { return TRUE; }
00225
00229 virtual BOOL ReadExtraChunks(PWAVFile & )
00230 { return TRUE; }
00231
00235 virtual void OnStart()
00236 { }
00237
00241 virtual void OnStop()
00242 { }
00243
00247 virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00248
00252 virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00253 };
00254
00255 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00256 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00257
00261 class PWAVFileConverter
00262 {
00263 public:
00264 virtual ~PWAVFileConverter() { }
00265 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00266 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00267 virtual BOOL SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00268 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00269 virtual off_t GetDataLength (PWAVFile & file) = 0;
00270 virtual BOOL Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00271 virtual BOOL Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00272 };
00273
00274 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00275
00278 class PWAVFile : public PFile
00279 {
00280 PCLASSINFO(PWAVFile, PFile);
00281
00282 public:
00288 enum {
00289 fmt_PCM = 1,
00290 fmt_ALaw = 6,
00291 fmt_uLaw = 7,
00292 fmt_GSM = 0x31,
00293 fmt_G728 = 0x41,
00294 fmt_G723 = 0x42,
00295 fmt_MSG7231 = 0x42,
00296 fmt_G726 = 0x64,
00297 fmt_G722 = 0x65,
00298 fmt_G729 = 0x84,
00299 fmt_VivoG7231 = 0x111,
00300
00301
00302 PCM_WavFile = fmt_PCM,
00303 G7231_WavFile = fmt_VivoG7231,
00304
00305
00306 fmt_NotKnown = 0x10000
00307 };
00308
00318 PWAVFile(
00319 unsigned format = fmt_PCM
00320 );
00321 static PWAVFile * format(
00322 const PString & format
00323 );
00324
00337 PWAVFile(
00338 OpenMode mode,
00339 int opts = ModeDefault,
00340 unsigned format = fmt_PCM
00341 );
00342 static PWAVFile * format(
00343 const PString & format,
00344 PFile::OpenMode mode,
00345 int opts = PFile::ModeDefault
00346 );
00347
00357 PWAVFile(
00358 const PFilePath & name,
00359 OpenMode mode = ReadWrite,
00360 int opts = ModeDefault,
00361 unsigned format = fmt_PCM
00362 );
00363 PWAVFile(
00364 const PString & format,
00365 const PFilePath & name,
00366 OpenMode mode = PFile::ReadWrite,
00367 int opts = PFile::ModeDefault
00368 );
00369
00372 ~PWAVFile();
00374
00384 virtual BOOL Read(
00385 void * buf,
00386 PINDEX len
00387 );
00388
00396 virtual BOOL Write(
00397 const void * buf,
00398 PINDEX len
00399 );
00400
00412 virtual BOOL Open(
00413 OpenMode mode = ReadWrite,
00414 int opts = ModeDefault
00415 );
00416
00430 virtual BOOL Open(
00431 const PFilePath & name,
00432 OpenMode mode = ReadWrite,
00433 int opts = ModeDefault
00434 );
00435
00441 virtual BOOL Close();
00442
00457 virtual BOOL SetPosition(
00458 off_t pos,
00459 FilePositionOrigin origin = Start
00460 );
00461
00469 virtual off_t GetPosition() const;
00471
00476 virtual BOOL SetFormat(unsigned fmt);
00477 virtual BOOL SetFormat(const PString & format);
00478
00481 virtual unsigned GetFormat() const;
00482 virtual PString GetFormatAsString() const;
00483
00487 virtual unsigned GetChannels() const;
00488 virtual void SetChannels(unsigned v);
00489
00492 virtual unsigned GetSampleRate() const;
00493 virtual void SetSampleRate(unsigned v);
00494
00497 virtual unsigned GetSampleSize() const;
00498 virtual void SetSampleSize(unsigned v);
00499
00502 off_t GetHeaderLength() const;
00503
00506 virtual off_t GetDataLength();
00507
00514 BOOL IsValid() const { return isValidWAV; }
00515
00519 PString GetFormatString() const
00520 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00521
00525 void SetAutoconvert();
00526
00528
00529 friend class PWAVFileConverter;
00530
00531 BOOL RawRead(void * buf, PINDEX len);
00532 BOOL RawWrite(const void * buf, PINDEX len);
00533
00534 BOOL FileRead(void * buf, PINDEX len);
00535 BOOL FileWrite(const void * buf, PINDEX len);
00536
00537 off_t RawGetPosition() const;
00538 BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00539 off_t RawGetDataLength();
00540
00541 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00542
00543 PWAV::FMTChunk wavFmtChunk;
00544 PBYTEArray extendedHeader;
00545
00546 protected:
00547 void Construct();
00548 void SelectFormat(unsigned fmt);
00549 void SelectFormat(const PString & format);
00550
00551 PBYTEArray wavHeaderData;
00552
00553 BOOL ProcessHeader();
00554 BOOL GenerateHeader();
00555 BOOL UpdateHeader();
00556
00557 BOOL isValidWAV;
00558
00559 PWAVFileFormat * formatHandler;
00560
00561 BOOL autoConvert;
00562 PWAVFileConverter * autoConverter;
00563
00564 off_t lenHeader;
00565 off_t lenData;
00566
00567 BOOL header_needs_updating;
00568 };
00569
00570 #endif
00571
00572