📄 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.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)# elsestatic 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///////////////////////////////////////////////////////////////////////////////// PWAVFilePWAVFile::PWAVFile(unsigned fmt) : PFile(){ Construct(); SelectFormat(fmt);}PWAVFile * PWAVFile::format(const PString & format){ PWAVFile * file = new PWAVFile; file->Construct(); file->SelectFormat(format); return file;}PWAVFile::PWAVFile(OpenMode mode, int opts, unsigned fmt) : PFile(mode, opts){ Construct(); SelectFormat(fmt);}PWAVFile * PWAVFile::format( const PString & format, PFile::OpenMode mode, int opts){ PWAVFile * file = new PWAVFile(mode, opts); file->Construct(); file->SelectFormat(format); return file;}PWAVFile::PWAVFile(const PFilePath & name, OpenMode mode, int opts, unsigned fmt){ Construct(); SelectFormat(fmt); Open(name, mode, opts);}PWAVFile::PWAVFile( const PString & format, const PFilePath & name, OpenMode mode, int opts ){ 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();}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) { delete autoConverter; autoConverter = NULL; } if (!PFile::IsOpen()) return TRUE; if (header_needs_updating) UpdateHeader(); if (formatHandler != NULL) formatHandler->OnStop(); delete formatHandler; formatHandler = NULL; return PFile::Close();}void PWAVFile::SetAutoconvert(){ autoConvert = TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -