www.pudn.com > w_ipp-sample-media_p_5.0.017.zip > 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#include #include "wav_file.h" #include "umc_structures.h" WavFile::WavFile() { m_is_first_time = 1; m_is_info_valid = 0; m_file_handle = NULL; m_info.channels_number = 1; } 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 { vm_var32 m_ulId; 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; #ifdef _BIG_ENDIAN_ int i, bsnum; #endif if (m_file_handle == NULL) { return -1; } n = fread(p_data, 1, size, (FILE *) m_file_handle); #ifdef _BIG_ENDIAN_ bsnum = m_info.resolution >> 3; if(bsnum == 2) for (i = 0; i < n/2; i++) ((vm_var16*)p_data)[i] = BIG_ENDIAN_SWAP16(((vm_var16*)p_data)[i]); else if (bsnum == 3) { for (i = 0; i < n/3; i++) { vm_var8 t0; t0 = ((vm_var8*)p_data)[3*i]; ((vm_var8*)p_data)[3*i] = ((vm_var8*)p_data)[3*i+2]; ((vm_var8*)p_data)[3*i+2] = t0; } } else if(bsnum == 4) for (i = 0; i < n/4; i++) ((vm_var32*)p_data)[i] = BIG_ENDIAN_SWAP32(((vm_var32*)p_data)[i]); #endif return n; } int WavFile::Write(void *p_data, size_t size) { #ifdef _BIG_ENDIAN_ int i; #endif 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; } #ifdef _BIG_ENDIAN_ for (i = 0; i < size/2; i++) ((vm_var16*)p_data)[i] = BIG_ENDIAN_SWAP16(((vm_var16*)p_data)[i]); #endif 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, b, bits; sWaveHeader wave; int nCh = m_info.channels_number; int CntFrameMulLenFrame = m_data_size / nCh / 2; // wav_header wave; if (m_file_handle == NULL) { return -1; } if (m_is_first_time) { m_is_first_time = 0; m_riff_size = sizeof(sWaveHeader) - 4; m_data_size = 0; } //--------------------- bits = 16; 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 * bits) / 8)); wave.bits = BIG_ENDIAN_SWAP16((vm_var16)bits); 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, 1, sizeof(sWaveHeader), (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 m_ulId = 0; vm_var32 m_ulSize = 0; 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; } m_ulId = BIG_ENDIAN_SWAP32(xChunk.m_ulId); m_ulSize = BIG_ENDIAN_SWAP32(xChunk.m_ulSize); if (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 != BIG_ENDIAN_SWAP32(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; } m_ulId = BIG_ENDIAN_SWAP32(xChunk.m_ulId); m_ulSize = BIG_ENDIAN_SWAP32(xChunk.m_ulSize); switch (m_ulId) { case ctFmt: if (fread(&header.nFormatTag, ctFmtSize, 1, (FILE *) m_file_handle) != 1) { // / IO error return -1; } if (m_ulSize > ctFmtSize) { fseek((FILE *) m_file_handle, m_ulSize - ctFmtSize, SEEK_CUR); } iFmtOk = 1; break; case ctData: ulDataChunkOffset = ulOffset; fseek((FILE *) m_file_handle, m_ulSize, SEEK_CUR); iDataOk = 1; break; default: fseek((FILE *) m_file_handle, m_ulSize, SEEK_CUR); break; } } fseek((FILE *) m_file_handle, ulDataChunkOffset + 8, SEEK_SET); m_info.format_tag = BIG_ENDIAN_SWAP16(header.nFormatTag); m_info.sample_rate = BIG_ENDIAN_SWAP32(header.nSamplesPerSec); m_info.resolution = BIG_ENDIAN_SWAP16(header.wBitPerSample); m_info.channels_number = BIG_ENDIAN_SWAP16(header.nChannels); m_info.channel_mask = 0; m_is_info_valid = 1; // m_info return 0; }