[英]Reading .wav files - Not reading header?
我試圖從.wav文件中讀取標頭信息,我正在閱讀該文件的以下屬性:
type
size
Format Tag
Format Length
Channels
Sample Rate
Average Bytes Second
Block Align
Bits Per Sample
Data size
現在,所有內容都讀取完全直到讀取采樣率,然后輸出為“0”值或僅為NULL。
這是代碼:(我打開了文本文件,並將指針傳遞給成員函數)
bool Wav::readHeader(FILE *dataIn)
{
char type2[4];
fread(this->type, sizeof(char), 4, dataIn);
fread(&this->size, sizeof(int), 1, dataIn);
fread(this->type, sizeof(char), 4, dataIn);
fread(this->type, sizeof(char), 4, dataIn);
fread(&this->format_length, sizeof(short), 1, dataIn);
fread(&this->format_tag, sizeof(short), 1, dataIn);
fread(&this->channels, sizeof(short), 1, dataIn);
fread(&this->sample_rate, sizeof(unsigned int), 1, dataIn);
fread(&this->avg_bytes_sec, sizeof(unsigned short), 1, dataIn);
fread(&this->block_align, sizeof(short), 1, dataIn);
fread(&this->bits_per_sample, sizeof(short), 1, dataIn);
return true;
}
班級成員定義為:
char type[4];
int size;
unsigned short format_tag;
unsigned short format_length;
unsigned short channels;
unsigned int sample_rate;
unsigned short avg_bytes_sec;
unsigned short block_align;
unsigned short bits_per_sample;
unsigned int data_size;
有沒有人有任何解決方案或建議?
(PS道歉,如果這個問題不對。我盡力寫出來!)
如果你有緊密打包的結構代表(PCM)WAVE的標題,它將如下所示:
struct Riff
{
char chunkId[4]; // "RIFF" (assuming char is 8 bits)
int chunkSize; // (assuming int is 32 bits)
char format[4]; // "WAVE"
};
struct Format
{
char chunkId[4]; // "fmt "
int chunkSize;
short format; // assuming short is 16 bits
short numChannels;
int sampleRate;
int byteRate;
short align;
short bitsPerSample;
};
struct Data
{
char chunkId[4]; // "data"
int chunkSize; // length of data
char* data;
};
struct Wave // Actual structure of a PCM WAVE file
{
Riff riffHeader;
Format formatHeader;
Data dataHeader;
};
基本上,你的問題是你的代碼中的format_length
(我的struct中的Format::chunkSize
)和avg_bytes_sec
(我的struct中的Format::byteRate
)每個都是2個字節,但它們每個都應該是4.你也沒有讀取數據subchunk的標題,但我認為這是故意的?
要閱讀,您可以這樣做:
void readWave(std::ifstream& file, Wave& wave)
{
// First read the RIFF header
file.read(wave.riffHeader.chunkId, 4);
file.read(reinterpret_cast<char*>(&wave.riffHeader.chunkSize), 4);
file.read(wave.riffHeader.format, 4);
// Now read the FORMAT header
file.read(wave.formatHeader.chunkId, 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.chunkSize), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.format), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.numChannels), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.sampleRate), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.byteRate), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.align), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.bitsPerSample), 2);
// Now read the DATA header
file.read(wave.dataHeader.chunkId, 4);
file.read(reinterpret_cast<char*>(&wave.dataHeader.chunkSize), 4);
// The actual data goes in wave.dataHeader.data, so you can allocate it
// and then read direclty into it now
}
邁克爾的鏈接是我在需要讀/寫WAVE文件時總是使用的鏈接 (我必須做幾次)。 我建議你仔細閱讀。
如果在“數據”塊之前在WAVE文件中有額外的塊,則此代碼應該能夠跳過它們:
void readWave(std::ifstream& file, Wave& wave)
{
// First read the RIFF header
file.read(wave.riffHeader.chunkId, 4);
file.read(reinterpret_cast<char*>(&wave.riffHeader.chunkSize), 4);
file.read(wave.riffHeader.format, 4);
// Now read the FORMAT header
file.read(wave.formatHeader.chunkId, 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.chunkSize), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.format), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.numChannels), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.sampleRate), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.byteRate), 4);
file.read(reinterpret_cast<char*>(&wave.formatHeader.align), 2);
file.read(reinterpret_cast<char*>(&wave.formatHeader.bitsPerSample), 2);
// WAVE files are just a special type of RIFF file, so it's possible
// there are other chunks, like "fact" chunks. We'll skip over these
// extra chunks until we find a "data" chunk
char chunkId[4] = {0};
int chunkSize = 0;
while (file.read(chunkId, 4) &&
(chunkId[0] != 'd' ||
chunkId[1] != 'a' ||
chunkId[2] != 't' ||
chunkId[3] != 'a'))
{
file.read(reinterpret_cast<char*>(&chunkSize), 4); // Read the chunk's size
file.seekg(chunkSize, std::ios_base::cur); // Skip the chunk
}
// We've found the DATA chunk and header
wave.dataHeader.chunkId[0] = chunkId[0];
wave.dataHeader.chunkId[1] = chunkId[1];
wave.dataHeader.chunkId[2] = chunkId[2];
wave.dataHeader.chunkId[3] = chunkId[3];
file.read(reinterpret_cast<char*>(&wave.dataHeader.chunkSize), 4);
// The actual data goes in wave.dataHeader.data, so you can allocate it
// and then read direclty into it now
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.