⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwavfile.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 3 页
字号:
// Performs necessary byte-order swapping on for big-endian platforms.BOOL PWAVFile::Read(void * buf, PINDEX len){  if (autoConverter != NULL)    return autoConverter->Read(*this, buf, len);  return RawRead(buf, len);}BOOL PWAVFile::RawRead(void * buf, PINDEX len){  // Some wav files have extra data after the sound samples in a LIST chunk.  // e.g. WAV files made in GoldWave have a copyright and a URL in this chunk.  // We do not want to return this data by mistake.  PINDEX readlen = len;  off_t pos = PFile::GetPosition();  if (pos >= (lenHeader+lenData))    return FALSE;    if ((pos + len) > (lenHeader+lenData))    readlen = (lenHeader+lenData) - pos;  if (formatHandler != NULL)    return formatHandler->Read(*this, buf, readlen);  return FileRead(buf, readlen);}BOOL PWAVFile::FileRead(void * buf, PINDEX len){  return PFile::Read(buf, len);}// Performs necessary byte-order swapping on for big-endian platforms.BOOL PWAVFile::Write(const void * buf, PINDEX len){  // Needs to update header on close.  header_needs_updating = TRUE;  if (autoConverter != NULL)    return autoConverter->Write(*this, buf, len);  return RawWrite(buf, len);}BOOL PWAVFile::RawWrite(const void * buf, PINDEX len){  // Needs to update header on close.  header_needs_updating = TRUE;  if (formatHandler != NULL)    return formatHandler->Write(*this, buf, len);  return FileWrite(buf, len);}BOOL PWAVFile::FileWrite(const void * buf, PINDEX len){  return PFile::Write(buf, len);}// Both SetPosition() and GetPosition() are offset by lenHeader.BOOL PWAVFile::SetPosition(off_t pos, FilePositionOrigin origin){  if (autoConverter != NULL)    return autoConverter->SetPosition(*this, pos, origin);  return RawSetPosition(pos, origin);}BOOL PWAVFile::RawSetPosition(off_t pos, FilePositionOrigin origin){  if (isValidWAV) {    pos += lenHeader;  }  return PFile::SetPosition(pos, origin);}off_t PWAVFile::GetPosition() const{  if (autoConverter != NULL)    return autoConverter->GetPosition(*this);  return RawGetPosition();}off_t PWAVFile::RawGetPosition() 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 wavFmtChunk.format;  else    return 0;}PString PWAVFile::GetFormatAsString() const{  if (isValidWAV && formatHandler != NULL)    return formatHandler->GetFormat();  else    return PString::Empty();}unsigned PWAVFile::GetChannels() const{  if (isValidWAV)    return wavFmtChunk.numChannels;  else    return 0;}void PWAVFile::SetChannels(unsigned v) {  wavFmtChunk.numChannels = (WORD)v;  header_needs_updating = TRUE;}unsigned PWAVFile::GetSampleRate() const{  if (isValidWAV)    return wavFmtChunk.sampleRate;  else    return 0;}void PWAVFile::SetSampleRate(unsigned v) {  wavFmtChunk.sampleRate = (WORD)v;  header_needs_updating = TRUE;}unsigned PWAVFile::GetSampleSize() const{  if (isValidWAV)    return wavFmtChunk.bitsPerSample;  else    return 0;}void PWAVFile::SetSampleSize(unsigned v) {  wavFmtChunk.bitsPerSample = (WORD)v;  header_needs_updating = TRUE;}off_t PWAVFile::GetHeaderLength() const{  if (isValidWAV)    return lenHeader;  else    return 0;}off_t PWAVFile::GetDataLength(){  if (autoConverter != NULL)    return autoConverter->GetDataLength(*this);  return RawGetDataLength();}off_t PWAVFile::RawGetDataLength(){  if (isValidWAV) {    // Updates data length before returns.    lenData = PFile::GetLength() - lenHeader;    return lenData;  }  else    return 0;}BOOL PWAVFile::SetFormat(unsigned fmt){  if (IsOpen() || isValidWAV)    return FALSE;  SelectFormat(fmt);  return TRUE;}BOOL PWAVFile::SetFormat(const PString & format){  if (IsOpen() || isValidWAV)    return FALSE;  SelectFormat(format);  return TRUE;}static inline BOOL NeedsConverter(const PWAV::FMTChunk & fmtChunk){  return (fmtChunk.format != PWAVFile::fmt_PCM) || (fmtChunk.bitsPerSample != 16);}BOOL PWAVFile::ProcessHeader() {  if (autoConverter != NULL) {    delete autoConverter;    autoConverter = NULL;  }  // Process the header information  // This comes in 3 or 4 chunks, either RIFF, FORMAT and DATA  // or RIFF, FORMAT, FACT and DATA.  if (!IsOpen()) {    PTRACE(1,"WAV\tProcessHeader: Not Open");    return (FALSE);  }  // go to the beginning of the file  if (!PFile::SetPosition(0)) {    PTRACE(1,"WAV\tProcessHeader: Cannot Set Pos");    return (FALSE);  }  // Read the RIFF chunk.  struct PWAV::RIFFChunkHeader riffChunk;  if (!ReadAndCheck(*this, &riffChunk, sizeof(riffChunk)))    return FALSE;  // check if tags are correct  if (strncmp(riffChunk.hdr.tag, WAVLabelRIFF, sizeof(WAVLabelRIFF)) != 0) {    PTRACE(1,"WAV\tProcessHeader: Not RIFF");    return (FALSE);  }  if (strncmp(riffChunk.tag, WAVLabelWAVE, sizeof(WAVLabelWAVE)) != 0) {    PTRACE(1,"WAV\tProcessHeader: Not WAVE");    return (FALSE);  }  // Read the known part of the FORMAT chunk.  if (!ReadAndCheck(*this, &wavFmtChunk, sizeof(wavFmtChunk)))    return FALSE;  // check if labels are correct  if (strncmp(wavFmtChunk.hdr.tag, WAVLabelFMT_, sizeof(WAVLabelFMT_)) != 0) {    PTRACE(1,"WAV\tProcessHeader: Not FMT");    return (FALSE);  }  // if we opened the file without knowing the format, then try and set the format now  if (formatHandler == NULL) {    SelectFormat(wavFmtChunk.format);    if (formatHandler == NULL) {      Close();      return FALSE;    }  }  // read the extended format chunk (if any)  extendedHeader.SetSize(0);  if ((unsigned)wavFmtChunk.hdr.len > (sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr))) {    extendedHeader.SetSize(wavFmtChunk.hdr.len - (sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr)));    if (!ReadAndCheck(*this, extendedHeader.GetPointer(), extendedHeader.GetSize()))      return FALSE;  }  // give format handler a chance to read extra chunks  if (!formatHandler->ReadExtraChunks(*this))    return FALSE;  PWAV::ChunkHeader chunkHeader;  // ignore chunks until we see a DATA chunk  for (;;) {    if (!ReadAndCheck(*this, &chunkHeader, sizeof(chunkHeader)))      return FALSE;    if (strncmp(chunkHeader.tag, WAVLabelDATA, sizeof(WAVLabelDATA)) == 0)       break;    if (!PFile::SetPosition(PFile::GetPosition() + + chunkHeader.len)) {      PTRACE(1,"WAV\tProcessHeader: Cannot set new position");      return FALSE;    }  }  // calculate the size of header and data for accessing the WAV data.  lenHeader  = PFile::GetPosition();   lenData    = chunkHeader.len;  // get ptr to data handler if in autoconvert mode  if (autoConvert && NeedsConverter(wavFmtChunk)) {    autoConverter = PWAVFileConverterFactory::CreateInstance(wavFmtChunk.format);    if (autoConverter == NULL) {      PTRACE(1, "PWAVFile\tNo format converter for type " << (int)wavFmtChunk.format);    }  }  formatHandler->OnStart();  return TRUE;}// Generates the wave file header.// Two types of header are supported.// a) PCM data, set to 8000Hz, mono, 16-bit samples// b) G.723.1 data// When this function is called with lenData < 0, it will write the header// as if the lenData is LONG_MAX minus header length.// Note: If it returns FALSE, the file may be left in inconsistent state.BOOL PWAVFile::GenerateHeader(){  if (autoConverter != NULL) {    delete autoConverter;    autoConverter = NULL;  }  if (!IsOpen()) {    PTRACE(1, "WAV\tGenerateHeader: Not Open");    return (FALSE);  }  // length of audio data is set to a large value if lenData does not  // contain a valid (non negative) number. We must then write out real values  // when we close the wav file.  int audioDataLen;  if (lenData < 0) {    audioDataLen = LONG_MAX - wavFmtChunk.hdr.len;    header_needs_updating = TRUE;  } else {    audioDataLen = lenData;  }  // go to the beginning of the file  if (!PFile::SetPosition(0)) {    PTRACE(1,"WAV\tGenerateHeader: Cannot Set Pos");    return (FALSE);  }  // write the WAV file header  PWAV::RIFFChunkHeader riffChunk;  memcpy(riffChunk.hdr.tag, WAVLabelRIFF, sizeof(WAVLabelRIFF));  memcpy(riffChunk.tag,     WAVLabelWAVE, sizeof(WAVLabelWAVE));  riffChunk.hdr.len = lenHeader + audioDataLen - sizeof(riffChunk.hdr);  if (!WriteAndCheck(*this, &riffChunk, sizeof(riffChunk)))    return FALSE;  // populate and write the WAV header with the default data  memcpy(wavFmtChunk.hdr.tag,  WAVLabelFMT_, sizeof(WAVLabelFMT_));  wavFmtChunk.hdr.len = sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr);  // set default length assuming no extra bytes  // allow the format handler to modify the header and extra bytes  formatHandler->CreateHeader(wavFmtChunk, extendedHeader);  // write the basic WAV header  if (      !WriteAndCheck(*this, &wavFmtChunk, sizeof(wavFmtChunk)) ||      ((extendedHeader.GetSize() > 0) && !WriteAndCheck(*this, extendedHeader.GetPointer(), extendedHeader.GetSize()))     )    return FALSE;  // allow the format handler to write additional chunks  if (!formatHandler->WriteExtraChunks(*this))    return FALSE;  // Write the DATA chunk.  PWAV::ChunkHeader dataChunk;  memcpy(dataChunk.tag, WAVLabelDATA, sizeof(WAVLabelDATA));  dataChunk.len = audioDataLen;  if (!WriteAndCheck(*this, &dataChunk, sizeof(dataChunk)))    return FALSE;  isValidWAV = TRUE;  // get the length of the header  lenHeader = PFile::GetPosition();  // get pointer to auto converter   if (autoConvert && NeedsConverter(wavFmtChunk)) {    autoConverter = PWAVFileConverterFactory::CreateInstance(wavFmtChunk.format);    if (autoConverter == NULL) {      PTRACE(1, "PWAVFile\tNo format converter for type " << (int)wavFmtChunk.format);      return FALSE;    }  }  return (TRUE);}// Update the WAV header according to the file length

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -