Files
XCEngine/MVS/Music fluctuations/source/audio/WavFileReader.cpp

224 lines
4.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}