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 #ifndef _PWAVFILE
00139 #define _PWAVFILE
00140
00141
00142
00143
00144
00145 #include <ptlib.h>
00146
00147 class PWAVFile;
00148
00149 namespace PWAV {
00150
00151 #ifdef __GNUC__
00152 #define P_PACKED __attribute__ ((packed));
00153 #else
00154 #define P_PACKED
00155 #pragma pack(1)
00156 #endif
00157
00158 struct ChunkHeader
00159 {
00160 char tag[4] P_PACKED;
00161 PInt32l len P_PACKED;
00162 };
00163
00164 struct RIFFChunkHeader
00165 {
00166 ChunkHeader hdr P_PACKED;
00167 char tag[4] P_PACKED;
00168 };
00169
00170 struct FMTChunk
00171 {
00172 ChunkHeader hdr P_PACKED;
00173 PUInt16l format P_PACKED;
00174 PUInt16l numChannels P_PACKED;
00175 PUInt32l sampleRate P_PACKED;
00176 PUInt32l bytesPerSec P_PACKED;
00177 PUInt16l bytesPerSample P_PACKED;
00178 PUInt16l bitsPerSample P_PACKED;
00179 };
00180
00181 };
00182
00183 #ifdef __GNUC__
00184 #undef P_PACKED
00185 #else
00186 #pragma pack()
00187 #endif
00188
00192 class PWAVFileFormat
00193 {
00194 public:
00195 virtual ~PWAVFileFormat() { }
00196
00200 virtual unsigned GetFormat() const = 0;
00201
00205 virtual PString GetFormatString() const = 0;
00206
00210 virtual PString GetDescription() const = 0;
00211
00215 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00216
00220 virtual BOOL WriteExtraChunks(PWAVFile & )
00221 { return TRUE; }
00222
00226 virtual BOOL ReadExtraChunks(PWAVFile & )
00227 { return TRUE; }
00228
00232 virtual void OnStart()
00233 { }
00234
00238 virtual void OnStop()
00239 { }
00240
00244 virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00245
00249 virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00250 };
00251
00252 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
00253 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00254
00258 class PWAVFileConverter
00259 {
00260 public:
00261 virtual ~PWAVFileConverter() { }
00262 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00263 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00264 virtual BOOL SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00265 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00266 virtual off_t GetDataLength (PWAVFile & file) = 0;
00267 virtual BOOL Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00268 virtual BOOL Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00269 };
00270
00271 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00272
00275 class PWAVFile : public PFile
00276 {
00277 PCLASSINFO(PWAVFile, PFile);
00278
00279 public:
00285 enum {
00286 fmt_PCM = 1,
00287 fmt_ALaw = 6,
00288 fmt_uLaw = 7,
00289 fmt_GSM = 0x31,
00290 fmt_G728 = 0x41,
00291 fmt_G723 = 0x42,
00292 fmt_MSG7231 = 0x42,
00293 fmt_G726 = 0x64,
00294 fmt_G722 = 0x65,
00295 fmt_G729 = 0x84,
00296 fmt_VivoG7231 = 0x111,
00297
00298
00299 PCM_WavFile = fmt_PCM,
00300 G7231_WavFile = fmt_VivoG7231,
00301
00302
00303 fmt_NotKnown = 0x10000
00304 };
00305
00315 PWAVFile(
00316 unsigned format = fmt_PCM
00317 );
00318 static PWAVFile * format(
00319 const PString & format
00320 );
00321
00334 PWAVFile(
00335 OpenMode mode,
00336 int opts = ModeDefault,
00337 unsigned format = fmt_PCM
00338 );
00339 static PWAVFile * format(
00340 const PString & format,
00341 PFile::OpenMode mode,
00342 int opts = PFile::ModeDefault
00343 );
00344
00354 PWAVFile(
00355 const PFilePath & name,
00356 OpenMode mode = ReadWrite,
00357 int opts = ModeDefault,
00358 unsigned format = fmt_PCM
00359 );
00360 PWAVFile(
00361 const PString & format,
00362 const PFilePath & name,
00363 OpenMode mode = PFile::ReadWrite,
00364 int opts = PFile::ModeDefault
00365 );
00366
00369 ~PWAVFile();
00371
00381 virtual BOOL Read(
00382 void * buf,
00383 PINDEX len
00384 );
00385
00393 virtual BOOL Write(
00394 const void * buf,
00395 PINDEX len
00396 );
00397
00409 virtual BOOL Open(
00410 OpenMode mode = ReadWrite,
00411 int opts = ModeDefault
00412 );
00413
00427 virtual BOOL Open(
00428 const PFilePath & name,
00429 OpenMode mode = ReadWrite,
00430 int opts = ModeDefault
00431 );
00432
00438 virtual BOOL Close();
00439
00454 virtual BOOL SetPosition(
00455 off_t pos,
00456 FilePositionOrigin origin = Start
00457 );
00458
00466 virtual off_t GetPosition() const;
00468
00473 virtual BOOL SetFormat(unsigned fmt);
00474 virtual BOOL SetFormat(const PString & format);
00475
00478 virtual unsigned GetFormat() const;
00479 virtual PString GetFormatAsString() const;
00480
00484 virtual unsigned GetChannels() const;
00485 virtual void SetChannels(unsigned v);
00486
00489 virtual unsigned GetSampleRate() const;
00490 virtual void SetSampleRate(unsigned v);
00491
00494 virtual unsigned GetSampleSize() const;
00495 virtual void SetSampleSize(unsigned v);
00496
00499 off_t GetHeaderLength() const;
00500
00503 virtual off_t GetDataLength();
00504
00511 BOOL IsValid() const { return isValidWAV; }
00512
00516 PString GetFormatString() const
00517 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00518
00522 void SetAutoconvert();
00523
00525
00526 friend class PWAVFileConverter;
00527
00528 BOOL RawRead(void * buf, PINDEX len);
00529 BOOL RawWrite(const void * buf, PINDEX len);
00530
00531 BOOL FileRead(void * buf, PINDEX len);
00532 BOOL FileWrite(const void * buf, PINDEX len);
00533
00534 off_t RawGetPosition() const;
00535 BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00536 off_t RawGetDataLength();
00537
00538 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00539
00540 PWAV::FMTChunk wavFmtChunk;
00541 PBYTEArray extendedHeader;
00542
00543 protected:
00544 void Construct();
00545 void SelectFormat(unsigned fmt);
00546 void SelectFormat(const PString & format);
00547
00548 PBYTEArray wavHeaderData;
00549
00550 BOOL ProcessHeader();
00551 BOOL GenerateHeader();
00552 BOOL UpdateHeader();
00553
00554 BOOL isValidWAV;
00555
00556 PWAVFileFormat * formatHandler;
00557
00558 BOOL autoConvert;
00559 PWAVFileConverter * autoConverter;
00560
00561 off_t lenHeader;
00562 off_t lenData;
00563
00564 BOOL header_needs_updating;
00565 };
00566
00567 #endif
00568
00569