📄 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.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>
#if PBYTE_ORDER==PBIG_ENDIAN && (defined(P_LINUX) || defined(__BEOS__) \
|| defined(P_SOLARIS) )
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
///////////////////////////////////////////////////////////////////////////////
// PWAVFile
PWAVFile::PWAVFile()
{
isValidWAV = FALSE;
header_needs_updating = FALSE;
}
PWAVFile::PWAVFile(OpenMode mode, int opts)
: PFile(mode, opts)
{
isValidWAV = FALSE;
header_needs_updating = FALSE;
}
PWAVFile::PWAVFile(const PFilePath & name, OpenMode mode, int opts, WaveType type)
: PFile(name, mode, opts)
{
isValidWAV = FALSE;
header_needs_updating = FALSE;
if (!IsOpen()) return;
waveType = type;
// 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
}
}
}
// Performs necessary byte-order swapping on for big-endian platforms.
BOOL PWAVFile::Read(void * buf, PINDEX len)
{
BOOL rval = PFile::Read(buf, len);
if (rval == FALSE) {
return (rval);
}
// WAV files are little-endian. So swap the bytes if this is
// a big endian machine and we have 16 bit samples
#if PBYTE_ORDER==PBIG_ENDIAN
// Note: swab only works on even length buffers.
if (bitsPerSample == 16)
swab(buf, buf, PFile::GetLastReadCount());
#endif
return (rval);
}
// Performs necessary byte-order swapping on for big-endian platforms.
BOOL PWAVFile::Write(const void * buf, PINDEX len)
{
BOOL rval;
// WAV files are little-endian. So swap the bytes if this is
// a big endian machine and we have 16 bit samples
#if PBYTE_ORDER==PBIG_ENDIAN
if (bitsPerSample == 16) {
// Note: swab only works on even length buffers.
swab(buf, (void *)buf, len);
}
#endif
rval = PFile::Write(buf, len);
// Needs to update header on close.
if (rval == TRUE) {
header_needs_updating = TRUE;
}
return (rval);
}
BOOL PWAVFile::Close()
{
if (header_needs_updating)
UpdateHeader();
return (PFile::Close());
}
// Both SetPosition() and GetPosition() are offset by lenHeader.
BOOL PWAVFile::SetPosition(off_t pos, FilePositionOrigin origin)
{
if (isValidWAV) {
pos += lenHeader;
}
return (PFile::SetPosition(pos, origin));
}
off_t PWAVFile::GetPosition() const
{
off_t pos = PFile::GetPosition();
if (isValidWAV) {
if (pos >= lenHeader) {
pos -= lenHeader;
}
else {
pos = 0;
}
}
return (pos);
}
unsigned PWAVFile::GetFormat() const
{
if (isValidWAV)
return format;
else
return 0;
}
unsigned PWAVFile::GetChannels() const
{
if (isValidWAV)
return numChannels;
else
return 0;
}
unsigned PWAVFile::GetSampleRate() const
{
if (isValidWAV)
return sampleRate;
else
return 0;
}
unsigned PWAVFile::GetSampleSize() const
{
if (isValidWAV)
return bitsPerSample;
else
return 0;
}
off_t PWAVFile::GetHeaderLength() const
{
if (isValidWAV)
return lenHeader;
else
return 0;
}
off_t PWAVFile::GetDataLength()
{
if (isValidWAV) {
// Updates data length before returns.
lenData = PFile::GetLength();
lenData -= lenHeader;
return lenData;
}
else
return 0;
}
#define WAV_LABEL_RIFF "RIFF"
#define WAV_LABEL_WAVE "WAVE"
#define WAV_LABEL_FMT_ "fmt "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -