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

📄 pwavfile.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
#define WAV_LABEL_FACT "fact"
#define WAV_LABEL_DATA "data"

// Because it is possible to process a file that we just created, or a
// corrupted WAV file, we check each read.
#define RETURN_ON_READ_FAILURE(readStat, len) \
  if (readStat != TRUE || GetLastReadCount() != len) return (FALSE);

BOOL PWAVFile::ProcessHeader() {

  // Process the header information
  // This comes in 3 or 4 chunks, either RIFF, FORMAT and DATA
  // or RIFF, FORMAT, FACT and DATA.

  if (IsOpen() == FALSE) {
    PTRACE(1,"Not Open");
    return (FALSE);
  }

  // go to the beginning of the file
  if (PFile::SetPosition(0) == FALSE) {
    PTRACE(1,"Cannot Set Pos");
    return (FALSE);
  }

  // Read the RIFF chunk.
  char    hdr_label_riff[4]; // ascii RIFF
  PInt32l hdr_len_after;     // length of data to follow
  char    hdr_label_wave[4]; // ascii WAVE
  int     size_riff_chunk = 12;

  // Use PFile::Read as we do not want to use our PWAVFile::Read code
  // as that does some byte swapping
  RETURN_ON_READ_FAILURE(PFile::Read(hdr_label_riff,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_len_after,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(hdr_label_wave,4), 4);

  // check if labels are correct
  if (strncmp(hdr_label_riff, WAV_LABEL_RIFF, strlen(WAV_LABEL_RIFF))) {
    PTRACE(1,"Not RIFF");
    return (FALSE);
  }

  if (strncmp(hdr_label_wave, WAV_LABEL_WAVE, strlen(WAV_LABEL_WAVE))) {
    PTRACE(1,"Not WAVE");
    return (FALSE);
  }

  // Read the FORMAT chunk.
  char    hdr_label_fmt[4];     // fmt_ in ascii
  PInt32l hdr_len_format;       // length of format chunk
  PInt16l hdr_format;           // Format 0x01 = PCM, 0x42 = Microsoft G.723.1
                                //        0x111 = VivoActive G.723.1
  PInt16l hdr_num_channels;     // Channels 0x01 = mono, 0x02 = stereo
  PInt32l hdr_samples_per_sec;  // Sample Rate in Hz
  PInt32l hdr_bytes_per_sec;    // Average bytes Per Second
  PInt16l hdr_bytes_per_sample; // Bytes Per Sample, eg 2
  PInt16l hdr_bits_per_sample;  // Bits Per Sample, eg 16

  RETURN_ON_READ_FAILURE(PFile::Read(hdr_label_fmt,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_len_format,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_format,2), 2);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_num_channels,2), 2);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_samples_per_sec,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_bytes_per_sec,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_bytes_per_sample,2), 2);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_bits_per_sample,2), 2);

  int size_format_chunk = (int)hdr_len_format + 8;

  // The spec allows for extra bytes at the end of the FORMAT chunk
  // Use the len_format field from FORMAT to determine where to move to
  // in the file to find the start of the next chunk.
  if (PFile::SetPosition(size_riff_chunk+size_format_chunk) == FALSE) {
    PTRACE(1,"Cannot reset position");
    return (FALSE);
  }

  // check if labels are correct
  if (strncmp(hdr_label_fmt, WAV_LABEL_FMT_, strlen(WAV_LABEL_FMT_)) ) {
    PTRACE(1,"Not FMT");
    return (FALSE);
  }


  // Peek at the title of the next chunk and then restore the file pointer.
  int position = PFile::GetPosition();
  char    chunk_title[4];
  RETURN_ON_READ_FAILURE(PFile::Read(chunk_title,4), 4);
  PFile::SetPosition(position);


  // Read the FACT chunk (optional)
  int size_fact_chunk = 0;

  if (strncmp(chunk_title, WAV_LABEL_FACT, 4)==0) {
    char    hdr_label_fact[4];  // ascii fact
    PInt32l hdr_len_fact;       // length of fact

    RETURN_ON_READ_FAILURE(PFile::Read(hdr_label_fact,4), 4);
    RETURN_ON_READ_FAILURE(PFile::Read(&hdr_len_fact,4), 4);
    size_fact_chunk = (int)hdr_len_fact + 8;

    // The spec allows for extra bytes in the FACT chunk which contain
    // information relating to the format of the audio. This is mainly
    // used when the WAV file contains compressed audio instead of PCM audio.
    // Use the len_fact field from FACT to determine where to move to
    // in the file to find the start of the next chunk.
    if (PFile::SetPosition(size_riff_chunk+size_format_chunk
			   +size_fact_chunk) == FALSE) {
      PTRACE(1,"Cannot reset position");
      return (FALSE);
    }
  }


  // Read the DATA chunk.
  char    hdr_label_data[4];  // ascii data
  PInt32l hdr_data_len;       // length of data
  int     size_data_chunk = 8;

  RETURN_ON_READ_FAILURE(PFile::Read(hdr_label_data,4), 4);
  RETURN_ON_READ_FAILURE(PFile::Read(&hdr_data_len,4), 4);

  if (strncmp(hdr_label_data, WAV_LABEL_DATA, strlen(WAV_LABEL_DATA))) {
    PTRACE(1,"Not DATA");
    return (FALSE);
  }

  // set the class variables for the Get methods.
  format        = hdr_format;
  numChannels   = hdr_num_channels;
  sampleRate    = hdr_samples_per_sec;
  bitsPerSample = hdr_bits_per_sample;
  lenHeader     = size_riff_chunk + size_format_chunk
		  + size_fact_chunk + size_data_chunk;
  lenData       = hdr_data_len;

  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 (IsOpen() == FALSE) {
    PTRACE(1, "Not Open");
    return (FALSE);
  }

  // go to the beginning of the file
  if (PFile::SetPosition(0) == FALSE) {
    PTRACE(1,"Cannot Set Pos");
    return (FALSE);
  }


  // local variables
  int len_format = 0;
  int averageBytesPerSec = 0;
  int bytesPerSample = 0;


  // Set the file parameters.
  if (waveType == PCM_WavFile) {
    lenHeader   = 44;
    len_format  = 16;   // size of the FORMAT chunk;
    format      = 0x01; // PCM type
    numChannels = 1;
    sampleRate  = 8000;
    bytesPerSample = 2;
    bitsPerSample  = 16;
    averageBytesPerSec = sampleRate * bytesPerSample;
  }
  if (waveType == G7231_WavFile) {
    lenHeader   = 60;
    len_format  = 20;    // size of the FORMAT chunk;
    format      = 0x111; // VivoActive G.723.1 (0x42 is the MS G.723.1 code)
    numChannels = 1;
    sampleRate  = 8000;
    bytesPerSample = 24; // There are 24 bytes in a G.723.1 frame
    bitsPerSample  = 0;
    averageBytesPerSec = 800; // Windows Sound Recorder requires this value
  }

  // 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 audioData;
  if (lenData < 0) {
    audioData = LONG_MAX - lenHeader;
    header_needs_updating = TRUE;
  } else {
    audioData = lenData;
  }
  
  // Write the RIFF chunk.
  PInt32l hdr_len_after = audioData + (lenHeader - 8);

  // Use PFile::Write as we do not want to use our PWAVFile::Write code
  // as that does some byte swapping
  if (!PFile::Write(WAV_LABEL_RIFF,4) ||
      !PFile::Write(&hdr_len_after,4) ||
      !PFile::Write(WAV_LABEL_WAVE,4))
    return FALSE;


  // Write the FORMAT chunk
  PInt32l hdr_len_format       = len_format; //excludes label_fmt and len_format
  PInt16l hdr_format           = (WORD)format;
  PInt16l hdr_num_channels     = (WORD)numChannels;
  PInt32l hdr_sample_per_sec   = sampleRate;
  PInt16l hdr_bits_per_sample  = (WORD)bitsPerSample;
  PInt16l hdr_bytes_per_sample = (WORD)bytesPerSample;
  PInt32l hdr_average_bytes_per_sec = averageBytesPerSec;
  
  if (!PFile::Write(WAV_LABEL_FMT_,4) ||
      !PFile::Write(&hdr_len_format,4) ||
      !PFile::Write(&hdr_format,2) ||
      !PFile::Write(&hdr_num_channels,2) ||
      !PFile::Write(&hdr_sample_per_sec,4) ||
      !PFile::Write(&hdr_average_bytes_per_sec,4) ||
      !PFile::Write(&hdr_bytes_per_sample,2) ||
      !PFile::Write(&hdr_bits_per_sample,2))
    return FALSE;

  // The format chunk then has extra data for G.723.1 files
  if (waveType == G7231_WavFile) {
    PInt16l hdr_format_data1 = 1;
    PInt16l hdr_format_data2 = 480;
    if (!PFile::Write(&hdr_format_data1,2) ||
        !PFile::Write(&hdr_format_data2,2))
      return FALSE;
  }


  // Write the FACT chunk. (only for G.723.1 files)
  if (waveType == G7231_WavFile) {
    PInt32l hdr_fact_len  = 4; // length is 4, exclude label_fact and fact_len
    PInt32l hdr_fact_data = 0; // fact chunk data. Should be number of samples.
    if (!PFile::Write(WAV_LABEL_FACT,4) ||
        !PFile::Write(&hdr_fact_len,4) ||
        !PFile::Write(&hdr_fact_data,4))
        return FALSE;
  }

  // Write the DATA chunk.
  PInt32l hdr_data_len = audioData;

  if (!PFile::Write(WAV_LABEL_DATA,4) ||
      !PFile::Write(&hdr_data_len,4))
      return FALSE;

  isValidWAV = TRUE;

  return (TRUE);
}

// Update the WAV header according to the file length
BOOL PWAVFile::UpdateHeader()
{
  // Check file is still open
  if (IsOpen() == FALSE) {
    PTRACE(1,"Not Open");
    return (FALSE);
  }

  // Check there is already a valid header
  if (isValidWAV == FALSE) {
    PTRACE(1,"WAV File not valid");
    return (FALSE);
  }

  // Find out the length of the audio data
  lenData = PFile::GetLength() - lenHeader;

  // Write out the 'len_after' field
  PFile::SetPosition(4);
  PInt32l hdr_len_after = (lenHeader - 8) + lenData; // size does not include
						     // first 8 bytes
  if (!PFile::Write(&hdr_len_after,4)) return (FALSE);

  // Write out the 'data_len' field
  PFile::SetPosition(lenHeader - 4);
  PInt32l hdr_data_len = lenData;
  if (!PFile::Write(&hdr_data_len,4)) return (FALSE);

  header_needs_updating = FALSE;

  return (TRUE);
}

⌨️ 快捷键说明

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