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 #ifndef _PWAVFILE
00114 #define _PWAVFILE
00115
00116
00117
00118
00119
00120 #include <ptlib.h>
00121
00122 class PWAVFile;
00123
00124 namespace PWAV {
00125
00126 #ifdef __GNUC__
00127 #define P_PACKED __attribute__ ((packed));
00128 #else
00129 #define P_PACKED
00130 #pragma pack(1)
00131 #endif
00132
00133 struct ChunkHeader
00134 {
00135 char tag[4] P_PACKED;
00136 PInt32l len P_PACKED;
00137 };
00138
00139 struct RIFFChunkHeader
00140 {
00141 ChunkHeader hdr P_PACKED;
00142 char tag[4] P_PACKED;
00143 };
00144
00145 struct FMTChunk
00146 {
00147 ChunkHeader hdr P_PACKED;
00148 PUInt16l format P_PACKED;
00149 PUInt16l numChannels P_PACKED;
00150 PUInt32l sampleRate P_PACKED;
00151 PUInt32l bytesPerSec P_PACKED;
00152 PUInt16l bytesPerSample P_PACKED;
00153 PUInt16l bitsPerSample P_PACKED;
00154 };
00155
00156 };
00157
00158 #ifdef __GNUC__
00159 #undef P_PACKED
00160 #else
00161 #pragma pack()
00162 #endif
00163
00167 class PWAVFileFormat
00168 {
00169 public:
00173 virtual unsigned GetFormat() const = 0;
00174
00178 virtual PString GetFormatString() const = 0;
00179
00183 virtual PString GetDescription() const = 0;
00184
00188 virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
00189
00193 virtual BOOL WriteExtraChunks(PWAVFile & )
00194 { return TRUE; }
00195
00199 virtual BOOL ReadExtraChunks(PWAVFile & )
00200 { return TRUE; }
00201
00205 virtual void OnStart()
00206 { }
00207
00211 virtual void OnStop()
00212 { }
00213
00217 virtual BOOL Read(PWAVFile & file, void * buf, PINDEX & len);
00218
00222 virtual BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);
00223 };
00224
00225 typedef PFactory<PWAVFileFormat> PWAVFileFormatByFormatFactory;
00226 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
00227
00231 class PWAVFileConverter
00232 {
00233 public:
00234 virtual unsigned GetFormat (const PWAVFile & file) const = 0;
00235 virtual off_t GetPosition (const PWAVFile & file) const = 0;
00236 virtual BOOL SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
00237 virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
00238 virtual off_t GetDataLength (PWAVFile & file) = 0;
00239 virtual BOOL Read (PWAVFile & file, void * buf, PINDEX len) = 0;
00240 virtual BOOL Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
00241 };
00242
00243 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
00244
00247 class PWAVFile : public PFile
00248 {
00249 PCLASSINFO(PWAVFile, PFile);
00250
00251 public:
00257 enum {
00258 fmt_PCM = 1,
00259 fmt_ALaw = 6,
00260 fmt_uLaw = 7,
00261 fmt_GSM = 0x31,
00262 fmt_G728 = 0x41,
00263 fmt_G723 = 0x42,
00264 fmt_MSG7231 = 0x42,
00265 fmt_G726 = 0x64,
00266 fmt_G722 = 0x65,
00267 fmt_G729 = 0x84,
00268 fmt_VivoG7231 = 0x111,
00269
00270
00271 PCM_WavFile = fmt_PCM,
00272 G7231_WavFile = fmt_VivoG7231,
00273
00274
00275 fmt_NotKnown = 0x10000
00276 };
00277
00287 PWAVFile(
00288 unsigned format = fmt_PCM
00289 );
00290 static PWAVFile * format(
00291 const PString & format
00292 );
00293
00306 PWAVFile(
00307 OpenMode mode,
00308 int opts = ModeDefault,
00309 unsigned format = fmt_PCM
00310 );
00311 static PWAVFile * format(
00312 const PString & format,
00313 PFile::OpenMode mode,
00314 int opts = PFile::ModeDefault
00315 );
00316
00326 PWAVFile(
00327 const PFilePath & name,
00328 OpenMode mode = ReadWrite,
00329 int opts = ModeDefault,
00330 unsigned format = fmt_PCM
00331 );
00332 PWAVFile(
00333 const PString & format,
00334 const PFilePath & name,
00335 OpenMode mode = PFile::ReadWrite,
00336 int opts = PFile::ModeDefault
00337 );
00338
00341 ~PWAVFile() { Close(); }
00343
00353 virtual BOOL Read(
00354 void * buf,
00355 PINDEX len
00356 );
00357
00365 virtual BOOL Write(
00366 const void * buf,
00367 PINDEX len
00368 );
00369
00381 virtual BOOL Open(
00382 OpenMode mode = ReadWrite,
00383 int opts = ModeDefault
00384 );
00385
00399 virtual BOOL Open(
00400 const PFilePath & name,
00401 OpenMode mode = ReadWrite,
00402 int opts = ModeDefault
00403 );
00404
00410 virtual BOOL Close();
00411
00426 virtual BOOL SetPosition(
00427 off_t pos,
00428 FilePositionOrigin origin = Start
00429 );
00430
00438 virtual off_t GetPosition() const;
00440
00445 virtual BOOL SetFormat(unsigned fmt);
00446 virtual BOOL SetFormat(const PString & format);
00447
00450 virtual unsigned GetFormat() const;
00451 virtual PString GetFormatAsString() const;
00452
00456 virtual unsigned GetChannels() const;
00457 virtual void SetChannels(unsigned v);
00458
00461 virtual unsigned GetSampleRate() const;
00462 virtual void SetSampleRate(unsigned v);
00463
00466 virtual unsigned GetSampleSize() const;
00467 virtual void SetSampleSize(unsigned v);
00468
00471 off_t GetHeaderLength() const;
00472
00475 virtual off_t GetDataLength();
00476
00483 BOOL IsValid() const { return isValidWAV; }
00484
00488 PString GetFormatString() const
00489 { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
00490
00494 void SetAutoconvert();
00495
00497
00498 friend class PWAVFileConverter;
00499
00500 BOOL RawRead(void * buf, PINDEX len);
00501 BOOL RawWrite(const void * buf, PINDEX len);
00502
00503 BOOL FileRead(void * buf, PINDEX len);
00504 BOOL FileWrite(const void * buf, PINDEX len);
00505
00506 off_t RawGetPosition() const;
00507 BOOL RawSetPosition(off_t pos, FilePositionOrigin origin);
00508 off_t RawGetDataLength();
00509
00510 void SetLastReadCount(PINDEX v) { lastReadCount = v; }
00511
00512 PWAV::FMTChunk wavFmtChunk;
00513 PBYTEArray extendedHeader;
00514
00515 protected:
00516 void Construct();
00517 void SelectFormat(unsigned fmt);
00518 void SelectFormat(const PString & format);
00519
00520 PBYTEArray wavHeaderData;
00521
00522 BOOL ProcessHeader();
00523 BOOL GenerateHeader();
00524 BOOL UpdateHeader();
00525
00526 BOOL isValidWAV;
00527
00528 PWAVFileFormat * formatHandler;
00529
00530 BOOL autoConvert;
00531 PWAVFileConverter * autoConverter;
00532
00533 off_t lenHeader;
00534 off_t lenData;
00535
00536 BOOL header_needs_updating;
00537 };
00538
00539 #ifdef _WIN32
00540
00541 # ifndef P_DISABLE_FACTORY_INSTANCES
00542
00543 # ifndef P_FACTORY_INSTANCE_PWAVFileConverter
00544 # define P_FACTORY_INSTANCE_PWAVFileConverter 1
00545 # pragma message("Including PWAVFileConverter factory loader")
00546 PLOAD_FACTORY(PWAVFileConverter, unsigned)
00547 # endif
00548
00549 # ifndef P_FACTORY_INSTANCE_PWAVFileFormat
00550 # define P_FACTORY_INSTANCE_PWAVFileFormat 1
00551 # pragma message("Including PWAVFileFormat factory loader")
00552 PLOAD_FACTORY(PWAVFileFormat, unsigned)
00553 # endif
00554
00555 # endif
00556
00557 #endif
00558
00559
00560 #endif
00561
00562