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 << "<EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD>WAV<EFBFBD>ļ<EFBFBD>" << std::endl;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_file = std::ifstream(p_fileName, std::ios::binary);
|
|||
|
|
if (!m_file) {
|
|||
|
|
std::cerr << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>WAV<EFBFBD>ļ<EFBFBD>" << 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()
|
|||
|
|
{
|
|||
|
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>*/
|
|||
|
|
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 << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD>WAV<EFBFBD>ļ<EFBFBD>!" << std::endl;
|
|||
|
|
CloseFile();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_file.read(reinterpret_cast<char*>(&format), sizeof(WavFormat));
|
|||
|
|
if (strncmp(format.id, "fmt ", 4) != 0){
|
|||
|
|
std::cerr << "format<EFBFBD><EFBFBD>ȡʧ<EFBFBD><EFBFBD>!" << std::endl;
|
|||
|
|
CloseFile();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (format.formatTag != 1){
|
|||
|
|
std::cerr << "<EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD>ʽ<EFBFBD><EFBFBD>pcm<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>!" << std::endl;
|
|||
|
|
CloseFile();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*<2A><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
|||
|
|
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:<3A><><EFBFBD><EFBFBD>INFO
|
|||
|
|
|
|||
|
|
//delete[] info;
|
|||
|
|
//}
|
|||
|
|
//else if (strncmp(id, "adtl", 4) == 0) {
|
|||
|
|
//char* adtl = new char[chunk.dataLength];
|
|||
|
|
//m_file.read(adtl, chunk.dataLength);
|
|||
|
|
//TODO:<3A><><EFBFBD><EFBFBD>adtl
|
|||
|
|
|
|||
|
|
//delete[] adtl;
|
|||
|
|
//}
|
|||
|
|
//else {
|
|||
|
|
//char* custom = new char[chunk.dataLength];
|
|||
|
|
//m_file.read(custom, chunk.dataLength);
|
|||
|
|
//TODO:<3A><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
//delete[] custom;
|
|||
|
|
//}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
int WavFileReader::ReadData(char* p_buffer, int p_position, int p_readLength){
|
|||
|
|
if (!m_file) {
|
|||
|
|
std::cerr << "<EFBFBD><EFBFBD>WAV<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << 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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|