正在从wavfile标头读取采样率
Reading samplerate from a wavfile header
我正在编写要在wave文件中读取的代码。
我以这份文件为指导。
它指定报头的字节22是波形文件的通道数,报头的字节24是采样率。
我使用的是Ableton输出的2通道16位44100hz的测试文件。我已经确认了测试波形文件的格式是大胆的,以确保它确实是44100hz采样率。
当我读取wave文件时,我得到的采样率值为-21436。我确信我的代码读取一个小的endian整数是正确的。我确信我的测试波形文件是正确的。所以现在我不知道为什么读取的采样率不正确。。。。
我的int读取代码如下。
int ReadInt(char* bytes , int start) { return (bytes[start+3] << 24) + (bytes[start+2] << 16) + (bytes[start+1] << 8) + bytes[start]; }
读取波形文件的函数如下。。。
WavFile::WavFile(std::string filename)
{
std::ifstream ifs;
ifs.open( filename, std::ios::binary | std::ios::in );
LogStream(LOG_DEBUG) << "WavFile::WavFile - - - - BEGIN READING WAV - - - -";
if(ifs.fail())
throw std::invalid_argument("WavFile::WavFile : Failed to open wavFile "+filename);
char hbytes[HEADER_SIZE];
ifs.read(hbytes , HEADER_SIZE);
// check that this is actually a wave file
bool valid_riff = hbytes[0]=='R' && hbytes[1]=='I' && hbytes[2]=='F' && hbytes[3]=='F';
bool valid_wave = hbytes[8]=='W' && hbytes[9]=='A' && hbytes[10]=='V' && hbytes[11]=='E';
bool valid_ftm = (hbytes[12]=='f' && hbytes[13]=='m' && hbytes[14]=='t' && hbytes[15]==' ');
bool valid_data = (hbytes[36]=='d' && hbytes[37]=='a' && hbytes[38]=='t' && hbytes[39]=='a');
LogStream(LOG_DEBUG) << "WavFile::WavFile - valid_riff="<<valid_riff<<" valid_wave="<<valid_wave<<" valid_ftm="<<valid_ftm<<" valid_data="<<valid_data;
if(!(valid_data && valid_ftm && valid_riff))
throw std::invalid_argument("WavFile::WavFile : Invalid argument - unable to open wavfile "+filename);
int audioFormat = ReadShort(hbytes , 20);
int SubChunk1Size = ReadInt(hbytes , 16);
if(audioFormat != 1 || SubChunk1Size != 16)
throw std::invalid_argument("WavFile::WavFile : Only uncompressed PCM wave format supported."+filename);
int subChunk2size = ReadInt(hbytes , 40);
m_header.num_channels = ReadShort(hbytes , 22);
m_header.sample_rate = ReadInt(hbytes , 24);
m_header.bits_per_sample = ReadShort(hbytes , 34);
LogStream(LOG_DEBUG) << "WavFile::WavFile num_channels="<<m_header.num_channels << " sample_rate="<<m_header.sample_rate<<" bits_per_sample="<<m_header.bits_per_sample;
m_pcm_data.resize( subChunk2size / sizeof(int16_t) );
LogStream(LOG_DEBUG) << "WavFile::WavFile - subChunk2size = "<<subChunk2size;
LogStream(LOG_DEBUG) << "WavFile::WavFile - m_pcm_data.size() = "<<m_pcm_data.size();
ifs.read((char*)m_pcm_data.data() , subChunk2size);
LogStream(LOG_DEBUG) << "WavFile: ifstream failbit="<<ifs.fail()<<" badbit="<<ifs.bad()<<" goodbit="<<ifs.good();
ifs.close();
LogStream(LOG_DEBUG) << "WavFile::WavFile - - - - END READING WAV - - - -n";
LogStream(LOG_DEBUG) << "WavFile::WavFile";
}
44100具有十六进制值44ac(无符号int16),-21436也具有十六进制数值44ac(有符号int16。您可以通过以下方式(输出44100)来避免这种情况:
int main()
{
char bytes[4] = { 0x44, 0xac, 0x00, 0x00 };
printf("%in", (((unsigned char)bytes[3]) << 24) | (((unsigned char)bytes[2]) << 16) | (((unsigned char)bytes[1]) << 8) | ((unsigned char)bytes[0]));
return 0;
}
或者简单地读取为无符号字节-这将避免其他字段出现同样的问题:
int main()
{
unsigned char bytes[4] = { 0x44, 0xac, 0x00, 0x00 };
printf("%in", (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]);
return 0;
}
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何从wav文件中获取采样率?
- 如何在C++中正确读取波形文件采样率
- FFMpeg:从AV_SAMPLE_FMT_S16到AV_SAMPLE_FMT_FLTP的重新采样将比特率除以2
- 对齐数据:速度取决于恒定数据读取的相对采样大小和采样频率
- 通过I2C增加传感器采样率
- RTP 媒体采样率
- 采样率偏差和声音播放位置
- 如何获得Windows音频播放的当前采样率
- 梳理2个wav文件后得到的wav的采样率
- 正在从wavfile标头读取采样率
- Android OpenSL Audio Buffer低于本机采样率/缓冲区大小(仅部分设备)
- Android:如何在C/ c++中获得首选(本地)音频缓冲区大小和音频采样率
- 如何检查/更改声卡的采样率?