224 lines
4.6 KiB
C++
224 lines
4.6 KiB
C++
#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<char*>(&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<char*>(&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<char*>(&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<int16_t>(static_cast<unsigned char>(sampleBytes[i])) << (8 * i);
|
||
}
|
||
//
|
||
delete[] sampleBytes;
|
||
return sampleValue;
|
||
}
|
||
|
||
|
||
|