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

📄 pwavfile.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 3 页
字号:
BOOL PWAVFile::UpdateHeader(){  // Check file is still open  if (!IsOpen()) {    PTRACE(1,"WAV\tUpdateHeader: Not Open");    return (FALSE);  }  // Check there is already a valid header  if (!isValidWAV) {    PTRACE(1,"WAV\tUpdateHeader: File not valid");    return (FALSE);  }  // Find out the length of the audio data  lenData = PFile::GetLength() - lenHeader;  // rewrite the length in the RIFF chunk  PInt32l riffChunkLen = (lenHeader - 8) + lenData; // size does not include first 8 bytes  PFile::SetPosition(4);  if (!WriteAndCheck(*this, &riffChunkLen, sizeof(riffChunkLen)))    return FALSE;  // rewrite the data length field in the data chunk  PInt32l dataChunkLen;  dataChunkLen = lenData;  PFile::SetPosition(lenHeader - 4);  if (!WriteAndCheck(*this, &dataChunkLen, sizeof(dataChunkLen)))    return FALSE;  header_needs_updating = FALSE;  return TRUE;}//////////////////////////////////////////////////////////////////BOOL PWAVFileFormat::Read(PWAVFile & file, void * buf, PINDEX & len){   if (!file.RawRead(buf, len))    return FALSE;  len = file.GetLastReadCount();  return TRUE;}BOOL PWAVFileFormat::Write(PWAVFile & file, const void * buf, PINDEX & len){   if (!file.RawWrite(buf, len))    return FALSE;  len = file.GetLastWriteCount();  return TRUE;}//////////////////////////////////////////////////////////////////class PWAVFileFormatPCM : public PWAVFileFormat{  public:    void CreateHeader(PWAV::FMTChunk & wavFmtChunk, PBYTEArray & extendedHeader);    PString GetDescription() const;    unsigned GetFormat() const;    PString GetFormatString() const;    BOOL Read(PWAVFile & file, void * buf, PINDEX & len);    BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);};PWAVFileFormatByIDFactory::Worker<PWAVFileFormatPCM> pcmIDWAVFormat(PWAVFile::fmt_PCM);PWAVFileFormatByFormatFactory::Worker<PWAVFileFormatPCM> pcmFormatWAVFormat("PCM-16");unsigned PWAVFileFormatPCM::GetFormat() const{  return PWAVFile::fmt_PCM;}PString PWAVFileFormatPCM::GetDescription() const{  return "PCM";}PString PWAVFileFormatPCM::GetFormatString() const{  return "PCM-16";}void PWAVFileFormatPCM::CreateHeader(PWAV::FMTChunk & wavFmtChunk,                                      PBYTEArray & /*extendedHeader*/){  wavFmtChunk.hdr.len         = sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr);  // no extended information  wavFmtChunk.format          = PWAVFile::fmt_PCM;  wavFmtChunk.numChannels     = 1;  wavFmtChunk.sampleRate      = 8000;  wavFmtChunk.bytesPerSample  = 2;  wavFmtChunk.bitsPerSample   = 16;  wavFmtChunk.bytesPerSec     = wavFmtChunk.sampleRate * wavFmtChunk.bytesPerSample;}BOOL PWAVFileFormatPCM::Read(PWAVFile & file, void * buf, PINDEX & len){  if (!file.FileRead(buf, len))    return FALSE;  len = file.GetLastReadCount();  // WAV files are little-endian. So swap the bytes if this is  // a big endian machine and we have 16 bit samples  // Note: swab only works on even length buffers.  if (file.wavFmtChunk.bitsPerSample == 16) {    SWAB(buf, buf, len);  }  return TRUE;}BOOL PWAVFileFormatPCM::Write(PWAVFile & file, const void * buf, PINDEX & len){  // WAV files are little-endian. So swap the bytes if this is  // a big endian machine and we have 16 bit samples  // Note: swab only works on even length buffers.  if (file.wavFmtChunk.bitsPerSample == 16) {    SWAB(buf, (void *)buf, len);  }  if (!file.FileWrite(buf, len))    return FALSE;  len = file.GetLastWriteCount();  return TRUE;}//////////////////////////////////////////////////////////////////#ifdef __GNUC__#define P_PACKED    __attribute__ ((packed));#else#define P_PACKED#pragma pack(1)#endifstruct G7231ExtendedInfo {  PInt16l data1      P_PACKED;      // 1  PInt16l data2      P_PACKED;      // 480};struct G7231FACTChunk {  PWAV::ChunkHeader hdr;  PInt32l data1      P_PACKED;      // 0   Should be number of samples.};#ifdef __GNUC__#undef P_PACKED#else#pragma pack()#endifclass PWAVFileFormatG7231 : public PWAVFileFormat{  public:    PWAVFileFormatG7231(unsigned short _g7231)      : g7231(_g7231) { }    void CreateHeader(PWAV::FMTChunk & wavFmtChunk, PBYTEArray & extendedHeader);    BOOL WriteExtraChunks(PWAVFile & file);    PString GetFormatString() const    { return "G.723.1"; }   // must match string in mediafmt.h    void OnStart();    BOOL Read(PWAVFile & file, void * buf, PINDEX & len);    BOOL Write(PWAVFile & file, const void * buf, PINDEX & len);  protected:    unsigned short g7231;    BYTE cacheBuffer[24];    PINDEX cacheLen;    PINDEX cachePos;};void PWAVFileFormatG7231::CreateHeader(PWAV::FMTChunk & wavFmtChunk, PBYTEArray & extendedHeader){  wavFmtChunk.hdr.len         = sizeof(wavFmtChunk) - sizeof(wavFmtChunk.hdr) + sizeof(sizeof(G7231ExtendedInfo));  wavFmtChunk.format          = g7231;  wavFmtChunk.numChannels     = 1;  wavFmtChunk.sampleRate      = 8000;  wavFmtChunk.bytesPerSample  = 24;  wavFmtChunk.bitsPerSample   = 0;  wavFmtChunk.bytesPerSec     = 800;  extendedHeader.SetSize(sizeof(G7231ExtendedInfo));  G7231ExtendedInfo * g7231Info = (G7231ExtendedInfo *)extendedHeader.GetPointer(sizeof(G7231ExtendedInfo));  g7231Info->data1 = 1;  g7231Info->data2 = 480;}BOOL PWAVFileFormatG7231::WriteExtraChunks(PWAVFile & file){  // write the fact chunk  G7231FACTChunk factChunk;  memcpy(factChunk.hdr.tag, "FACT", 4);  factChunk.hdr.len = sizeof(factChunk) - sizeof(factChunk.hdr);  factChunk.data1 = 0;  return file.FileWrite(&factChunk, sizeof(factChunk));}static PINDEX G7231FrameSizes[4] = { 24, 20, 4, 1 };void PWAVFileFormatG7231::OnStart(){  cacheLen = cachePos = 0;}BOOL PWAVFileFormatG7231::Read(PWAVFile & file, void * origData, PINDEX & origLen){  // Note that Microsoft && VivoActive G.2723.1 codec cannot do SID frames, so  // we must parse the data and remove SID frames  // also note that frames are always written as 24 byte frames, so each frame must be unpadded  PINDEX bytesRead = 0;  while (bytesRead < origLen) {    // keep reading until we find a 20 or 24 byte frame    while (cachePos == cacheLen) {      if (!file.FileRead(cacheBuffer, 24))        return FALSE;      // calculate actual length of frame      PINDEX frameLen = G7231FrameSizes[cacheBuffer[0] & 3];      if (frameLen == 20 || frameLen == 24) {        cacheLen = frameLen;        cachePos = 0;      }    }    // copy data to requested buffer    PINDEX copyLen = PMIN(origLen-bytesRead, cacheLen-cachePos);    memcpy(origData, cacheBuffer+cachePos, copyLen);    origData = copyLen + (char *)origData;    cachePos += copyLen;    bytesRead += copyLen;  }  origLen = bytesRead;  return TRUE;}BOOL PWAVFileFormatG7231::Write(PWAVFile & file, const void * origData, PINDEX & len){  // Note that Microsoft && VivoActive G.2723.1 codec cannot do SID frames, so  // we must parse the data and remove SID frames  // also note that frames are always written as 24 byte frames, so each frame must be padded  PINDEX written = 0;  BYTE frameBuffer[24];  while (len > 0) {    // calculate actual length of frame    PINDEX frameLen = G7231FrameSizes[(*(char *)origData) & 3];    if (len < frameLen)      return FALSE;    // we can write 24 byte frame straight out,     // 20 byte frames need to be reblocked    // we ignore any other frames    const void * buf = NULL;    switch (frameLen) {      case 24:        buf = origData;        break;      case 20:        memcpy(frameBuffer, origData, 20);        buf = frameBuffer;        break;      default:        break;    }    if (buf != NULL && !file.FileWrite(buf, 24))      return FALSE;    else      written += 24;    origData = (char *)origData + frameLen;    len -= frameLen;  }  len = written;  return TRUE;}class PWAVFileFormatG7231_vivo : public PWAVFileFormatG7231{  public:    PWAVFileFormatG7231_vivo()      : PWAVFileFormatG7231(PWAVFile::fmt_VivoG7231) { }    unsigned GetFormat() const    { return PWAVFile::fmt_VivoG7231; }    PString GetDescription() const    { return GetFormatString() & "Vivo"; }};PWAVFileFormatByIDFactory::Worker<PWAVFileFormatG7231_vivo> g7231VivoWAVFormat(PWAVFile::fmt_VivoG7231);PWAVFileFormatByFormatFactory::Worker<PWAVFileFormatG7231_vivo> g7231FormatWAVFormat("G.723.1");class PWAVFileFormatG7231_ms : public PWAVFileFormatG7231{  public:    PWAVFileFormatG7231_ms()      : PWAVFileFormatG7231(PWAVFile::fmt_MSG7231) { }    unsigned GetFormat() const    { return PWAVFile::fmt_MSG7231; }    PString GetDescription() const    { return GetFormatString() & "MS"; }};PWAVFileFormatByIDFactory::Worker<PWAVFileFormatG7231_ms> g7231MSWAVFormat(PWAVFile::fmt_MSG7231);//////////////////////////////////////////////////////////////////class PWAVFileConverterPCM : public PWAVFileConverter{  public:    unsigned GetFormat    (const PWAVFile & file) const;    off_t GetPosition     (const PWAVFile & file) const;    BOOL SetPosition      (PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin);    unsigned GetSampleSize(const PWAVFile & file) const;    off_t GetDataLength   (PWAVFile & file);    BOOL Read             (PWAVFile & file, void * buf, PINDEX len);    BOOL Write            (PWAVFile & file, const void * buf, PINDEX len);};unsigned PWAVFileConverterPCM::GetFormat(const PWAVFile &) const{  return PWAVFile::fmt_PCM;}off_t PWAVFileConverterPCM::GetPosition(const PWAVFile & file) const{  off_t pos = file.RawGetPosition();  return pos * 2;}BOOL PWAVFileConverterPCM::SetPosition(PWAVFile & file, off_t pos, PFile::FilePositionOrigin origin){  pos /= 2;  return file.SetPosition(pos, origin);}unsigned PWAVFileConverterPCM::GetSampleSize(const PWAVFile &) const{  return 16;}off_t PWAVFileConverterPCM::GetDataLength(PWAVFile & file){  return file.RawGetDataLength() * 2;}BOOL PWAVFileConverterPCM::Read(PWAVFile & file, void * buf, PINDEX len){  if (file.wavFmtChunk.bitsPerSample == 16)    return file.PWAVFile::RawRead(buf, len);  if (file.wavFmtChunk.bitsPerSample != 8) {    PTRACE(1, "PWAVFile\tAttempt to read autoconvert PCM data with unsupported number of bits per sample " << (int)file.wavFmtChunk.bitsPerSample);    return FALSE;  }  // read the PCM data with 8 bits per sample  PINDEX samples = (len / 2);  PBYTEArray pcm8;  if (!file.PWAVFile::RawRead(pcm8.GetPointer(samples), samples))    return FALSE;  // convert to PCM-16  PINDEX i;  short * pcmPtr = (short *)buf;  for (i = 0; i < samples; i++)    *pcmPtr++ = (unsigned short)((pcm8[i] << 8) - 0x8000);  // fake the lastReadCount  file.SetLastReadCount(len);  return TRUE;}BOOL PWAVFileConverterPCM::Write(PWAVFile & file, const void * buf, PINDEX len){  if (file.wavFmtChunk.bitsPerSample == 16)    return file.PWAVFile::RawWrite(buf, len);  PTRACE(1, "PWAVFile\tAttempt to write autoconvert PCM data with unsupported number of bits per sample " << (int)file.wavFmtChunk.bitsPerSample);  return FALSE;}PWAVFileConverterFactory::Worker<PWAVFileConverterPCM> pcmConverter(PWAVFile::fmt_PCM, true);//////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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