#include"WavFileReader.h" WavFileReader::WavFileReader(){} WavFileReader::~WavFileReader() { CloseFile(); } bool WavFileReader::OpenFile(const std::string& p_fileName) { if (p_fileName == m_fileName) { std::cerr << "已经打开了该WAV文件" << std::endl; return true; } m_file = std::ifstream(p_fileName, std::ios::binary); if (!m_file) { std::cerr << "无法打开WAV文件" << std::endl; return false; } if (ProcessWavFile()) { m_fileName = p_fileName; return true; } else { m_file.close(); return false; } } void WavFileReader::CloseFile() { if (m_file) { m_file.close(); } m_fileName = ""; } bool WavFileReader::ProcessWavFile() { /*处理文件头部分*/ WavRIFF riff; WavFormat format; m_file.seekg(0, std::ios::end); m_fileSize = m_file.tellg(); m_file.seekg(0, std::ios::beg); m_file.read(reinterpret_cast(&riff), sizeof(WavRIFF)); if (strncmp(riff.id, "RIFF", 4) != 0 || strncmp(riff.waveFlag, "WAVE", 4) != 0){ std::cerr << "不是有效的WAV文件!" << std::endl; CloseFile(); return false; } m_file.read(reinterpret_cast(&format), sizeof(WavFormat)); if (strncmp(format.id, "fmt ", 4) != 0){ std::cerr << "format读取失败!" << std::endl; CloseFile(); return false; } if (format.formatTag != 1){ std::cerr << "数据格式非pcm,程序不支持!" << std::endl; CloseFile(); return false; } /*处理文件后部数据*/ while (m_file.tellg() < m_fileSize){ WavChunk chunk; m_file.read(reinterpret_cast(&chunk), sizeof(WavChunk)); if (strncmp(chunk.id, "LIST", 4) == 0){ std::cout << "LIST" << std::endl; //ProcessLIST(chunk.dataLength); m_file.seekg(chunk.dataLength, std::ios::cur); continue; } else if (strncmp(chunk.id, "data", 4) == 0){ std::cout << "data" << std::endl; m_dataOffset = m_file.tellg(); m_dataLength = chunk.dataLength; m_file.seekg(chunk.dataLength, std::ios::cur); continue; } else{ m_file.seekg(chunk.dataLength, std::ios::cur); continue; } } m_fileLength = riff.fileLength + 8; m_channels = format.channels; m_sampleRate = format.samplesPerSec; m_bitsPerSample = format.bitsPerSample; m_bytesPerSec = format.avgBytesPerSec; m_lastingTime = (float)m_dataLength / m_bytesPerSec; m_sampleNum = m_dataLength / (m_bitsPerSample / 8); } //TODO:: void WavFileReader::ProcessLIST(int listLength){ while (listLength > 0){ //if (strncmp(id, "INFO", 4) == 0){ //char* info = new char[chunk.dataLength]; //m_file.read(info, chunk.dataLength); //TODO:处理INFO //delete[] info; //} //else if (strncmp(id, "adtl", 4) == 0) { //char* adtl = new char[chunk.dataLength]; //m_file.read(adtl, chunk.dataLength); //TODO:处理adtl //delete[] adtl; //} //else { //char* custom = new char[chunk.dataLength]; //m_file.read(custom, chunk.dataLength); //TODO:处理自定义块 //delete[] custom; //} } } int WavFileReader::ReadData(char* p_buffer, int p_position, int p_readLength){ if (!m_file) { std::cerr << "该WAV文件不存在" << std::endl; return 0; } int filePosition = m_dataOffset + p_position; if(filePosition>m_fileSize){ return 0; } m_file.seekg(m_dataOffset + p_position, std::ios::beg); m_file.read(p_buffer, p_readLength); int realLength = m_file.gcount(); return realLength; } void WavFileReader::SetPosition(int p_position){ if (m_file){ m_file.seekg(p_position, std::ios::beg); } } int WavFileReader::GetPosition(){ if (!m_file) return -1; return m_file.tellg(); } int WavFileReader::GetFileLength(){ if (!m_file) return -1; return m_fileLength; } int WavFileReader::GetDataLength() { if (!m_file) return -1; return m_dataLength; } int WavFileReader::GetChannels(){ if (!m_file) return -1; return m_channels; } int WavFileReader::GetSampleRate(){ if (!m_file) return -1; return m_sampleRate; } int WavFileReader::GetBytesPerSec(){ if (!m_file) return -1; return m_bytesPerSec; } int WavFileReader::GetBitsPerSample(){ if (!m_file) return -1; return m_bitsPerSample; } float WavFileReader::GetLastingTime(){ if (!m_file) return -1; return m_lastingTime; } int WavFileReader::GetSampleNum(){ if (!m_file) return -1; return m_sampleNum; } int16_t WavFileReader::GetSampleValue(int p_index) { if (p_index >= m_sampleNum || !m_file) return -1; unsigned int bytesPerSample = m_bitsPerSample / 8; char* sampleBytes = new char[bytesPerSample]; ReadData(sampleBytes, p_index * bytesPerSample, bytesPerSample); int16_t sampleValue = 0; for (int i = 0; i < bytesPerSample; ++i) { sampleValue |= static_cast(static_cast(sampleBytes[i])) << (8 * i); } // delete[] sampleBytes; return sampleValue; }