📄 wav_file.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright(c) 2004-2005 Intel Corporation. All Rights Reserved.//*/#include <stdio.h>#include <memory.h>#include "wav_file.h"#include "umc_structures.h"WavFile::WavFile(){ m_is_first_time = 1; m_is_info_valid = 0; m_file_handle = NULL;}WavFile::~WavFile(){}int WavFile::Open(vm_char *p_filename, unsigned int mode){ int res; FILE *p_file = NULL; if (mode & AFM_CREATE) { p_file = vm_file_open(p_filename, __VM_STRING("wb")); } else { p_file = vm_file_open(p_filename, __VM_STRING("rb")); } if (p_file == NULL) { return -1; } m_file_handle = p_file; if (!(mode & AFM_CREATE)) { res = ReadHeaderInfo(); if (res < 0) { if (mode & AFM_NO_CONTENT_WRN) { fseek((FILE *) m_file_handle, 0, SEEK_SET); return 1; } fclose((FILE *) m_file_handle); return -1; } } return 0;}const vm_var32 ctRiff = 0x46464952;const vm_var32 ctWave = 0x45564157;const vm_var32 ctFmt = 0x20746D66;const vm_var32 ctData = 0x61746164;struct t_chunk { union { vm_var32 m_ulId; vm_char m_sId[4]; }; vm_var32 m_ulSize;};const vm_var32 ctFmtSize = (2 + 2 + 4 + 4 + 2 + 2);typedef struct { vm_var32 id_riff; vm_var32 len_riff; vm_var32 id_chuck; vm_var32 fmt; vm_var32 len_chuck; vm_var16 type; vm_var16 channels; vm_var32 freq; vm_var32 bytes; vm_var16 align; vm_var16 bits; vm_var32 id_data; vm_var32 len_data;} sWaveHeader;struct wav_header { t_chunk riff_chunk; vm_var32 wave_signature; t_chunk fmt_chunk; vm_var16 nFormatTag; vm_var16 nChannels; vm_var32 nSamplesPerSec; vm_var32 nAvgBytesPerSec; vm_var16 nBlockAlign; vm_var16 wBitPerSample; t_chunk data_chunk;};struct wav_header_ex { t_chunk riff_chunk; unsigned int wave_signature; t_chunk fmt_chunk; vm_var16 nFormatTag; vm_var16 nChannels; vm_var32 nSamplesPerSec; vm_var32 nAvgBytesPerSec; vm_var16 nBlockAlign; vm_var16 wBitPerSample; vm_var16 cbSize; union { vm_var16 wValidBitsPerSample; /* bits of precision */ vm_var16 wSamplesPerBlock; /* valid if wBitsPerSample==0 */ vm_var16 wReserved; /* If neither applies, set to zero. */ }; vm_var32 dwChannelMask; vm_var16 guid[16]; t_chunk data_chunk;};int WavFile::Read(void *p_data, size_t size){ int n; if (m_file_handle == NULL) { return -1; } n = fread(p_data, 1, size, (FILE *) m_file_handle); return n;}int WavFile::Write(void *p_data, size_t size){ size_t n; size_t header_size; vm_var16 *buf = (vm_var16 *)p_data;// wav_header header; wav_header_ex header_ex; if (m_is_first_time) { m_is_first_time = 0;// header_size = sizeof(wav_header_ex); header_size = sizeof(sWaveHeader); fseek((FILE *) m_file_handle, header_size, SEEK_SET); m_riff_size = header_size - 4; m_data_size = 0; }// header_size = sizeof(wav_header_ex); if (m_file_handle == NULL) { return -1; } n = fwrite(p_data, 1, size, (FILE *) m_file_handle); m_riff_size += size; m_data_size += size; return n;}int WavFile::Close(){ int n; int b; wav_header_ex header_ex;// wav_header wave; if (m_file_handle == NULL) { return -1; }//--------------------- { sWaveHeader wave = {0,}; vm_var16 nCh = m_info.channels_number; vm_var32 CntFrameMulLenFrame = m_data_size / nCh / 2; wave.id_riff = BIG_ENDIAN_SWAP32(0x46464952); wave.len_riff =BIG_ENDIAN_SWAP32(sizeof(sWaveHeader) + ((CntFrameMulLenFrame) << 1) * nCh - 8); wave.id_chuck = BIG_ENDIAN_SWAP32(0x45564157); wave.fmt = BIG_ENDIAN_SWAP32(0x20746D66); wave.len_chuck = BIG_ENDIAN_SWAP32(0x00000010); wave.type = BIG_ENDIAN_SWAP16(0x0001); wave.channels = BIG_ENDIAN_SWAP16(nCh); wave.freq = BIG_ENDIAN_SWAP32((vm_var32)(m_info.sample_rate)); wave.bytes = BIG_ENDIAN_SWAP32((m_info.sample_rate << 1) * nCh); wave.align = BIG_ENDIAN_SWAP16((vm_var16)((nCh * 16) / 8)); wave.bits = BIG_ENDIAN_SWAP16((vm_var16)16); wave.id_data = BIG_ENDIAN_SWAP32(0x61746164); wave.len_data = BIG_ENDIAN_SWAP32(((CntFrameMulLenFrame) << 1) * nCh); fseek((FILE *) m_file_handle, 0, SEEK_SET); n = fwrite(&wave, sizeof(sWaveHeader),1, (FILE *) m_file_handle); fclose((FILE *) m_file_handle); return 0; }//--------------------- if (m_is_info_valid && (m_info.format_tag == 1)) { header_ex.riff_chunk.m_ulId = ctRiff; header_ex.riff_chunk.m_ulSize = m_riff_size; header_ex.wave_signature = ctWave; header_ex.fmt_chunk.m_ulId = ctFmt; header_ex.fmt_chunk.m_ulSize = 0x28; if (m_info.channels_number < 3) { header_ex.nFormatTag = m_info.format_tag; header_ex.nChannels = m_info.channels_number; header_ex.nSamplesPerSec = m_info.sample_rate; b = m_info.resolution; b /= 8; header_ex.nAvgBytesPerSec = header_ex.nSamplesPerSec * header_ex.nChannels * b; header_ex.nBlockAlign = header_ex.nChannels * b; header_ex.wBitPerSample = m_info.resolution; header_ex.cbSize = 0; // / Only for simple PCM// header_ex.cbSize = 1; } else { header_ex.nFormatTag = 0xFFFE; header_ex.nChannels = m_info.channels_number; header_ex.nSamplesPerSec = m_info.sample_rate; b = m_info.resolution; b /= 8; header_ex.nAvgBytesPerSec = header_ex.nSamplesPerSec * header_ex.nChannels * b; header_ex.nBlockAlign = header_ex.nChannels * b; header_ex.wBitPerSample = m_info.resolution;// header_ex.cbSize = 22; /// Only for simple PCM header_ex.cbSize = 1; header_ex.wValidBitsPerSample = m_info.resolution; header_ex.dwChannelMask = m_info.channel_mask;// KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71// KSDATAFORMAT_SUBTYPE_PCM: 00000001-0000-0010-8000-00aa00389b71 header_ex.guid[0] = 0x01; header_ex.guid[1] = 0x00; header_ex.guid[2] = 0x00; header_ex.guid[3] = 0x00; header_ex.guid[4] = 0x00; header_ex.guid[5] = 0x00; header_ex.guid[6] = 0x10; header_ex.guid[7] = 0x00; header_ex.guid[8] = 0x80; header_ex.guid[9] = 0x00; header_ex.guid[10] = 0x00; header_ex.guid[11] = 0xaa; header_ex.guid[12] = 0x00; header_ex.guid[13] = 0x38; header_ex.guid[14] = 0x9b; header_ex.guid[15] = 0x71; } header_ex.data_chunk.m_ulId = ctData; header_ex.data_chunk.m_ulSize = m_data_size; fseek((FILE *) m_file_handle, 0, SEEK_SET); n = fwrite(&header_ex, 1, sizeof(header_ex), (FILE *) m_file_handle); } fclose((FILE *) m_file_handle); return 0;}int WavFile::SetInfo(Info * p_info){ m_is_info_valid = 1; memcpy(&m_info, p_info, sizeof(m_info)); return 0;}int WavFile::GetInfo(Info * p_info){ if (m_is_info_valid) { memcpy(p_info, &m_info, sizeof(m_info)); return 0; } return -1;}int WavFile::ReadHeaderInfo(){ wav_header_ex header; t_chunk xChunk; vm_var32 ulTemp = 0; vm_var32 ulOffset = 0; vm_var32 ulDataChunkOffset = 0; int iFmtOk = 0; int iDataOk = 0; if (fread(&xChunk, sizeof(xChunk), 1, (FILE *) m_file_handle) != 1) {// / IO error return -1; } if (xChunk.m_ulId != ctRiff) {// / File does not contain 'Riff' chunk ! return -2; } if (fread(&ulTemp, sizeof(ulTemp), 1, (FILE *) m_file_handle) != 1) {// / IO error return -1; } if (ulTemp != ctWave) {// / File does not contain 'Wave' signature ! return -3; } while (1) { if (iFmtOk && iDataOk) break; ulOffset = ftell((FILE *) m_file_handle); if (fread(&xChunk, sizeof(xChunk), 1, (FILE *) m_file_handle) != 1) {// / IO error return -1; } switch (xChunk.m_ulId) { case ctFmt: if (fread(&header.nFormatTag, ctFmtSize, 1, (FILE *) m_file_handle) != 1) {// / IO error return -1; } if (xChunk.m_ulSize > ctFmtSize) { fseek((FILE *) m_file_handle, xChunk.m_ulSize - ctFmtSize, SEEK_CUR); } iFmtOk = 1; break; case ctData: ulDataChunkOffset = ulOffset; fseek((FILE *) m_file_handle, xChunk.m_ulSize, SEEK_CUR); iDataOk = 1; break; default: fseek((FILE *) m_file_handle, xChunk.m_ulSize, SEEK_CUR); break; } } fseek((FILE *) m_file_handle, ulDataChunkOffset + 8, SEEK_SET); m_info.format_tag = header.nFormatTag; m_info.sample_rate = header.nSamplesPerSec; m_info.resolution = header.wBitPerSample; m_info.channels_number = header.nChannels; m_info.channel_mask = 0; m_is_info_valid = 1;// m_info return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -