📄 pwavfile.cxx
字号:
/*
* pwavfile.cxx
*
* WAV file I/O channel class.
*
* Portable Windows Library
*
* Copyright (c) 2001 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is
* Roger Hardiman <roger@freebsd.org>
* and Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
*
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Log: pwavfile.cxx,v $
* Revision 1.1 2006/06/29 04:18:04 joegenbaclor
* *** empty log message ***
*
* Revision 1.47 2006/04/10 23:57:27 csoutheren
* Checked in changes to remove some warnings with gcc effc++ flag
*
* Revision 1.46 2006/04/09 22:22:35 dereksmithies
* Fix a warning about comparison of signed and unsigned numbers.
*
* Revision 1.45 2006/04/06 00:39:37 csoutheren
* Ensure autoconvert format is preserved across file close
*
* Revision 1.44 2006/01/16 07:31:57 csoutheren
* Removed deletion of PWAVFIle format converters.
* These look like memory leaks, but are not - the converters are static objects that
* cannot be deleted
*
* Revision 1.43 2005/11/30 12:47:41 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.42 2005/11/25 01:01:15 csoutheren
* Applied patch #1351168
* PWlib various fixes
*
* Revision 1.41 2005/10/30 23:25:52 csoutheren
* Fixed formatting
* Removed throw() declarations (PWLib does not do exceptions)
* Removed duplicate destructor declarations and definitions
*
* Revision 1.40 2005/10/30 19:41:53 dominance
* fixed most of the warnings occuring during compilation
*
* Revision 1.39 2005/06/09 00:33:20 csoutheren
* Fixed crash problem caused by recent leak fix
* Removed bogus error when reading all of file contents in a single read
*
* Revision 1.38 2005/06/07 09:28:46 csoutheren
* Fixed bug #1204964 - ensure full cleanup when WAV file is closed
* Thanks to Zdenek Broz
*
* Revision 1.37 2005/03/22 07:32:55 csoutheren
* Fixed problem with incorrect message being displayed when reading past end of file
*
* Revision 1.36 2005/01/04 08:09:42 csoutheren
* Fixed Linux configure problems
*
* Revision 1.35 2004/11/08 04:07:40 csoutheren
* Fixed crash opportunity under some conditions
* Fixed incorrect WAV file type display
*
* Revision 1.34 2004/07/19 12:32:25 csoutheren
* Removed vestigial debug comment
*
* Revision 1.33 2004/07/19 12:23:38 csoutheren
* Removed compiler crash under gcc 3.4.0
*
* Revision 1.32 2004/07/15 03:12:42 csoutheren
* Migrated changes from crs_vxnml_devel branch into main trunk
*
* Revision 1.31.4.4 2004/07/13 08:13:05 csoutheren
* Lots of implementation of factory-based PWAVFile
*
* Revision 1.31.4.3 2004/07/12 09:17:20 csoutheren
* Fixed warnings and errors under Linux
*
* Revision 1.31.4.2 2004/07/12 08:30:16 csoutheren
* More fixes for abstract factory implementation of PWAVFile
*
* Revision 1.31.4.1 2004/07/07 07:07:42 csoutheren
* Changed PWAVFile to use abstract factories (extensively)
* Removed redundant blocking/unblocking when using G.723.1
* More support for call transfer
*
* Revision 1.31 2003/07/29 11:27:16 csoutheren
* Changed to use autoconf detected swab function
*
* Revision 1.30 2003/07/28 18:39:09 dsandras
* Linux has a swab function. Patch from Alexander Larsson <alexl@redhat.com>.
*
* Revision 1.29 2003/02/20 23:32:00 robertj
* More RTEMS support patches, thanks Sebastian Meyer.
*
* Revision 1.28 2002/12/20 08:43:42 robertj
* Fixed incorrect header length for MS-GSM, thanks Martijn Roest & Kanchana
*
* Revision 1.27 2002/07/12 01:25:25 craigs
* Repaired reintroduced problem with SID frames in WAV files
*
* Revision 1.26 2002/07/02 06:25:25 craigs
* Added ability to create files in MS G.723.1 format
*
* Revision 1.25 2002/06/20 00:54:41 craigs
* Added explicit class names to some functions to alloew overriding
*
* Revision 1.24 2002/06/12 07:28:16 craigs
* Fixed problem with opening WAV files in read mode
*
* Revision 1.23 2002/05/23 05:04:11 robertj
* Set error code if get invalid sized write for G.723.1 wav file.
*
* Revision 1.22 2002/05/23 03:59:55 robertj
* Changed G.723.1 WAV file so every frame is 24 bytes long.
*
* Revision 1.21 2002/05/21 01:59:54 robertj
* Removed the enum which made yet another set of magic numbers for audio
* formats, now uses the WAV file format numbers.
* Fixed missing Open() function which does not have file name parameter.
* Added ability to set the audio format after construction.
* Added automatic expansion of G.723.1 SID frames into 24 zero bytes as
* those formats do not currently support 4 byte frames.
* Fixed trace output to include "module" section.
*
* Revision 1.20 2002/02/06 00:52:23 robertj
* Fixed GNU warning.
*
* Revision 1.19 2002/01/31 15:29:26 rogerh
* Fix a problem with .wav files recorded in GoldWave. The GoldWave copyright
* string (embedded at the end of the wav file) was returned as audio data and
* heared as noise. Javi <fjmchm@hotmail.com> reported the problem.
*
* Revision 1.18 2002/01/22 03:55:59 craigs
* Added include of ptclib/pwavfile.cxx as this is now in PTCLib
*
* Revision 1.17 2002/01/13 21:01:55 rogerh
* The class contructor is now used to specify the type of new WAV files
* (eg PCM or G7231)
*
* Revision 1.16 2002/01/11 16:33:46 rogerh
* Create a PWAVFile Open() function, which processes the WAV header
*
* Revision 1.15 2001/10/16 13:27:37 rogerh
* Add support for writing G.723.1 WAV files.
* MS Windows can play G.723.1 WAV Files in Media Player and Sound Recorder.
* Sound Recorder can also convert them to normal PCM format WAV files.
* Thanks go to M.Stoychev <M.Stoychev@cnsys.bg> for sample WAV files.
*
* Revision 1.14 2001/10/15 11:48:15 rogerh
* Add GetFormat to return the format of a WAV file
*
* Revision 1.13 2001/10/15 07:27:38 rogerh
* Add support for reading WAV fils containing G.723.1 audio data.
*
* Revision 1.12 2001/09/29 07:41:42 rogerh
* Add fix from Patrick Koorevaar <pkoorevaar@hotmail.com>
*
* Revision 1.11 2001/08/15 12:52:20 rogerh
* Fix typo
*
* Revision 1.10 2001/08/15 12:21:45 rogerh
* Make Solaris use our swab() function instead of the C library version.
* Submitted by Andre Schulze <as8@rncmm2.urz.tu-dresden.de>
*
* Revision 1.9 2001/07/23 02:57:42 robertj
* Fixed swab definition for Linux alpha.
*
* Revision 1.8 2001/07/23 01:20:20 rogerh
* Add updates from Shawn - ensure isvalidWAV is false for zero length files.
* GetDataLength uses actual file size to support file updates as well as appends.
* Add updates from Roger - Update Header() just writes to specific fields which
* preserves any 'extra' data in an existing header between FORMAT and DATA chunks.
*
* Revision 1.7 2001/07/20 07:32:36 rogerh
* Back out previous change. BSD systems already have swab in the C library.
* Also use swab in Write()
*
* Revision 1.6 2001/07/20 07:09:12 rogerh
* We need to byte swap on more then just Linux and BeOS.
*
* Revision 1.5 2001/07/20 04:14:47 robertj
* Fixed swab implementation on Linux alpha
*
* Revision 1.4 2001/07/20 03:30:59 robertj
* Minor cosmetic changes to new PWAVFile class.
*
* Revision 1.3 2001/07/19 09:57:24 rogerh
* Use correct filename
*
* Revision 1.2 2001/07/19 09:53:29 rogerh
* Add the PWAVFile class to read and write .wav files
* The PWAVFile class was written by Roger Hardiman <roger@freebsd.org>
* and Shawn Pai-Hsiang Hsiao <shawn@eecs.harvard.edu>
*
*/
#ifdef __GNUC__
#pragma implementation "pwavfile.h"
#endif
#include <ptlib.h>
#include <ptclib/pwavfile.h>
const char WAVLabelRIFF[4] = { 'R', 'I', 'F', 'F' };
const char WAVLabelWAVE[4] = { 'W', 'A', 'V', 'E' };
const char WAVLabelFMT_[4] = { 'f', 'm', 't', ' ' };
const char WAVLabelFACT[4] = { 'F', 'A', 'C', 'T' };
const char WAVLabelDATA[4] = { 'd', 'a', 't', 'a' };
PINSTANTIATE_FACTORY(PWAVFileFormat, unsigned)
PINSTANTIATE_FACTORY(PWAVFileConverter, unsigned)
inline BOOL ReadAndCheck(PWAVFile & file, void * buf, PINDEX len)
{
return file.FileRead(buf, len) && (file.PFile::GetLastReadCount() == len);
}
inline BOOL WriteAndCheck(PWAVFile & file, void * buf, PINDEX len)
{
return file.FileWrite(buf, len) && (file.GetLastWriteCount() == len);
}
#if PBYTE_ORDER==PBIG_ENDIAN
# if defined(USE_SYSTEM_SWAB)
# define SWAB(a,b,c) ::swab(a,b,c)
# else
static void SWAB(const void * void_from, void * void_to, register size_t len)
{
register const char * from = (const char *)void_from;
register char * to = (char *)void_to;
while (len > 1) {
char b = *from++;
*to++ = *from++;
*to++ = b;
len -= 2;
}
}
# endif
#else
# define SWAB(a,b,c) {}
#endif
///////////////////////////////////////////////////////////////////////////////
// PWAVFile
PWAVFile::PWAVFile(unsigned fmt)
: PFile(), origFmt(fmt)
{
Construct();
SelectFormat(fmt);
}
PWAVFile * PWAVFile::format(const PString & format)
{
PWAVFile * file = new PWAVFile;
file->origFmt = 0xffffffff;
file->Construct();
file->SelectFormat(format);
return file;
}
PWAVFile::PWAVFile(OpenMode mode, int opts, unsigned fmt)
: PFile(mode, opts), origFmt(fmt)
{
Construct();
SelectFormat(fmt);
}
PWAVFile * PWAVFile::format(
const PString & format,
PFile::OpenMode mode,
int opts
)
{
PWAVFile * file = new PWAVFile(mode, opts);
file->origFmt = 0xffffffff;
file->Construct();
file->SelectFormat(format);
return file;
}
PWAVFile::PWAVFile(const PFilePath & name, OpenMode mode, int opts, unsigned fmt)
: origFmt(fmt)
{
Construct();
SelectFormat(fmt);
Open(name, mode, opts);
}
PWAVFile::PWAVFile(
const PString & format,
const PFilePath & name,
OpenMode mode,
int opts
)
{
origFmt = 0xffffffff;
Construct();
SelectFormat(format);
Open(name, mode, opts);
}
PWAVFile::~PWAVFile()
{
Close();
if (formatHandler != NULL)
delete formatHandler;
}
void PWAVFile::Construct()
{
lenData = 0;
lenHeader = 0;
isValidWAV = FALSE;
header_needs_updating = FALSE;
autoConvert = FALSE;
autoConverter = NULL;
formatHandler = NULL;
wavFmtChunk.hdr.len = sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr);
}
void PWAVFile::SelectFormat(unsigned fmt)
{
if (formatHandler != NULL) {
delete formatHandler;
formatHandler = NULL;
}
if (fmt != fmt_NotKnown) {
formatHandler = PWAVFileFormatByIDFactory::CreateInstance(fmt);
wavFmtChunk.format = (WORD)fmt;
}
}
void PWAVFile::SelectFormat(const PString & format)
{
if (formatHandler != NULL) {
delete formatHandler;
formatHandler = NULL;
}
if (!format.IsEmpty())
formatHandler = PWAVFileFormatByFormatFactory::CreateInstance(format);
if (formatHandler != NULL) {
wavFmtChunk.format = (WORD)formatHandler->GetFormat();
if (origFmt == 0xffffffff)
origFmt = wavFmtChunk.format;
}
}
BOOL PWAVFile::Open(OpenMode mode, int opts)
{
if (!(PFile::Open(mode, opts)))
return FALSE;
isValidWAV = FALSE;
// Try and process the WAV file header information.
// Either ProcessHeader() or GenerateHeader() must be called.
if (PFile::GetLength() > 0) {
// try and process the WAV file header information
if (mode == ReadOnly || mode == ReadWrite) {
isValidWAV = ProcessHeader();
}
if (mode == WriteOnly) {
lenData = -1;
GenerateHeader();
}
}
else {
// generate header
if (mode == ReadWrite || mode == WriteOnly) {
lenData = -1;
GenerateHeader();
}
if (mode == ReadOnly) {
isValidWAV = FALSE; // ReadOnly on a zero length file
}
}
// if we did not know the format when we opened, then we had better know it now
if (formatHandler == NULL) {
Close();
return FALSE;
}
return TRUE;
}
BOOL PWAVFile::Open(const PFilePath & name, OpenMode mode, int opts)
{
if (IsOpen())
Close();
SetFilePath(name);
return Open(mode, opts);
}
BOOL PWAVFile::Close()
{
if (autoConverter != NULL) {
autoConverter = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -