PTLib  Version 2.14.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pwavfile.h
Go to the documentation of this file.
1 /*
2  * pwavfile.h
3  *
4  * WAV file I/O channel class.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is
23  * Roger Hardiman <roger@freebsd.org>
24  * and Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
25  *
26  * All Rights Reserved.
27  *
28  * Contributor(s): ______________________________________.
29  *
30  * $Revision: 32255 $
31  * $Author: rjongbloed $
32  * $Date: 2014-06-29 17:49:31 +1000 (Sun, 29 Jun 2014) $
33  */
34 
35 #ifndef PTLIB_PWAVFILE_H
36 #define PTLIB_PWAVFILE_H
37 
38 //#ifdef P_USE_PRAGMA
39 //#pragma interface
40 //#endif
41 
42 #include <ptlib.h>
43 
44 #ifdef P_WAVFILE
45 
46 #include <ptlib/pfactory.h>
47 
48 class PWAVFile;
49 
50 namespace PWAV {
51 
52 #pragma pack(1)
53 
54  struct ChunkHeader
55  {
56  char tag[4];
57  PInt32l len;
58  };
59 
60  struct RIFFChunkHeader
61  {
62  ChunkHeader hdr;
63  char tag[4];
64  };
65 
66  struct FMTChunk
67  {
68  ChunkHeader hdr;
69  PUInt16l format;
70  PUInt16l numChannels;
71  PUInt32l sampleRate;
72  PUInt32l bytesPerSec;
73  PUInt16l bytesPerSample;
74  PUInt16l bitsPerSample;
75  };
76 
77  struct G7231ExtendedInfo
78  {
79  PInt16l data1; // 1
80  PInt16l data2; // 480
81  };
82 
83  struct G7231FACTChunk
84  {
85  PWAV::ChunkHeader hdr;
86  PInt32l data1; // 0 Should be number of samples.
87  };
88 
89 #pragma pack()
90 
91 }; // namespace PWAV
92 
93 
96 class PWAVFileFormat
97 {
98 public:
99  virtual ~PWAVFileFormat() { }
100 
103  virtual unsigned GetFormat() const = 0;
104 
107  virtual PString GetFormatString() const = 0;
108 
111  virtual PString GetDescription() const = 0;
112 
114  virtual bool CanSetChannels(unsigned channels) const = 0;
115 
118  virtual void CreateHeader(PWAV::FMTChunk & header, PBYTEArray & extendedHeader) = 0;
119 
122  virtual void UpdateHeader(PWAV::FMTChunk & /*header*/, PBYTEArray & /*extendedHeader*/)
123  { }
124 
127  virtual PBoolean WriteExtraChunks(PWAVFile & /*file*/)
128  { return true; }
129 
132  virtual PBoolean ReadExtraChunks(PWAVFile & /*file*/)
133  { return true; }
134 
137  virtual void OnStart()
138  { }
139 
142  virtual void OnStop()
143  { }
144 
147  virtual PBoolean Read(PWAVFile & file, void * buf, PINDEX & len);
148 
151  virtual PBoolean Write(PWAVFile & file, const void * buf, PINDEX & len);
152 };
153 
154 typedef PFactory<PWAVFileFormat, PCaselessString> PWAVFileFormatByFormatFactory;
155 typedef PFactory<PWAVFileFormat, unsigned> PWAVFileFormatByIDFactory;
156 
157 #define PCREATE_WAVFILE_FORMAT_FACTORY(cls, id, name) \
158  PFACTORY_CREATE(PWAVFileFormatByIDFactory, cls, id); \
159  typedef cls cls##_ByFormat; \
160  PFACTORY_CREATE(PWAVFileFormatByFormatFactory, cls##_ByFormat, name)
161 
162 PFACTORY_LOAD(PWAVFileFormatPCM);
163 
164 
167 class PWAVFileConverter
168 {
169 public:
170  virtual ~PWAVFileConverter() { }
171  virtual unsigned GetFormat (const PWAVFile & file) const = 0;
172  virtual off_t GetPosition (const PWAVFile & file) const = 0;
173  virtual PBoolean SetPosition (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin) = 0;
174  virtual unsigned GetSampleSize(const PWAVFile & file) const = 0;
175  virtual off_t GetDataLength (PWAVFile & file) = 0;
176  virtual PBoolean Read (PWAVFile & file, void * buf, PINDEX len) = 0;
177  virtual PBoolean Write (PWAVFile & file, const void * buf, PINDEX len) = 0;
178 };
179 
180 typedef PFactory<PWAVFileConverter, unsigned> PWAVFileConverterFactory;
181 
184 class PWAVFile : public PFile
185 {
186  PCLASSINFO(PWAVFile, PFile);
187 
188 public:
194  enum WaveType {
195  fmt_PCM = 1,
196  fmt_MSADPCM = 2,
197  fmt_ALaw = 6,
198  fmt_uLaw = 7,
199  fmt_VOXADPCM = 0x10,
200  fmt_IMAADPCM = 0x11,
201  fmt_GSM = 0x31,
202  fmt_G728 = 0x41,
203  fmt_G723 = 0x42,
204  fmt_MSG7231 = 0x42,
205  fmt_G726 = 0x64,
206  fmt_G722 = 0x65,
207  fmt_G729 = 0x83,
208  fmt_VivoG7231 = 0x111,
209 
210  // For backward compatibility
211  PCM_WavFile = fmt_PCM,
212  G7231_WavFile = fmt_VivoG7231,
213 
214  // allow opening files without knowing the format
215  fmt_NotKnown = 0x10000
216  };
217 
227  PWAVFile(
228  unsigned format = fmt_PCM
229  );
230 
243  PWAVFile(
244  OpenMode mode,
245  OpenOptions opts = ModeDefault,
246  unsigned format = fmt_PCM
247  );
248 
258  PWAVFile(
259  const PFilePath & name,
260  OpenMode mode = ReadWrite,
261  OpenOptions opts = ModeDefault,
262  unsigned format = fmt_PCM
263  );
264 
265  PWAVFile(
266  const PString & format,
267  const PFilePath & name,
268  OpenMode mode = ReadWrite,
269  OpenOptions opts = ModeDefault
270  );
271 
274  ~PWAVFile();
276 
286  virtual PBoolean Read(
287  void * buf,
288  PINDEX len
289  );
290 
298  virtual PBoolean Write(
299  const void * buf,
300  PINDEX len
301  );
302 
315  virtual PBoolean Open(
316  OpenMode mode = ReadWrite,
317  OpenOptions opts = ModeDefault
318  );
319 
333  virtual PBoolean Open(
334  const PFilePath & name,
335  OpenMode mode = ReadWrite,
336  OpenOptions opts = ModeDefault
337  );
338 
344  virtual PBoolean Close();
345 
360  virtual PBoolean SetPosition(
361  off_t pos,
362  FilePositionOrigin origin = Start
363  );
364 
372  virtual off_t GetPosition() const;
374 
379  virtual PBoolean SetFormat(unsigned fmt);
380  virtual PBoolean SetFormat(const PString & format);
381 
384  virtual unsigned GetFormat() const;
385  virtual PString GetFormatAsString() const;
386 
390  virtual unsigned GetChannels() const;
391  virtual void SetChannels(unsigned v);
392 
395  virtual unsigned GetSampleRate() const;
396  virtual void SetSampleRate(unsigned v);
397 
400  virtual unsigned GetSampleSize() const;
401  virtual void SetSampleSize(unsigned v);
402 
405  virtual unsigned GetBytesPerSecond() const;
406  virtual void SetBytesPerSecond(unsigned v);
407 
410  off_t GetHeaderLength() const;
411 
414  virtual off_t GetDataLength();
415 
422  PBoolean IsValid() const { return isValidWAV; }
423 
426  PString GetFormatString() const
427  { if (formatHandler == NULL) return PString("N/A"); else return formatHandler->GetFormatString(); }
428 
431  void SetAutoconvert();
432 
434 
435  PBoolean RawRead(void * buf, PINDEX len);
436  PBoolean RawWrite(const void * buf, PINDEX len);
437 
438  PBoolean FileRead(void * buf, PINDEX len);
439  PBoolean FileWrite(const void * buf, PINDEX len);
440 
441  off_t RawGetPosition() const;
442  PBoolean RawSetPosition(off_t pos, FilePositionOrigin origin);
443  off_t RawGetDataLength();
444 
445  void SetLastReadCount(PINDEX v) { lastReadCount = v; }
446  void SetLastWriteCount(PINDEX v) { lastWriteCount = v; }
447 
448  // Restored for backward compatibility reasons
449  static PWAVFile * format(const PString & format);
450  static PWAVFile * format(const PString & format, OpenMode mode, OpenOptions opts = ModeDefault);
451 
452 
453 protected:
454  void Construct();
455  bool SelectFormat(unsigned fmt);
456  bool SelectFormat(const PString & format);
457 
458  PBoolean ProcessHeader();
459  PBoolean GenerateHeader();
460  PBoolean UpdateHeader();
461 
462  PBYTEArray wavHeaderData;
463  PWAV::FMTChunk wavFmtChunk;
464  PBYTEArray extendedHeader;
465 
466  bool isValidWAV;
467 
468  unsigned int origFmt;
469  PWAVFileFormat * formatHandler;
470 
471  PBoolean autoConvert;
472  PWAVFileConverter * autoConverter;
473 
474  off_t lenHeader;
475  off_t lenData;
476 
477  bool header_needs_updating;
478 
479 friend class PWAVFileConverter;
480 };
481 
482 #endif // P_WAVFILE
483 
484 #endif // PTLIB_PWAVFILE_H
485 
486 // End Of File ///////////////////////////////////////////////////////////////