首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结构化C/C++ -读取WAV标头32位浮点-字节偏移错误

结构化C/C++ -读取WAV标头32位浮点-字节偏移错误
EN

Stack Overflow用户
提问于 2017-01-19 19:43:49
回答 1查看 2.3K关注 0票数 0

我使用一个结构来读取具有58字节wav头的音频格式3 (=IEEE浮点数32位)的wav文件。问题:字节38以“事实”块开头。这似乎没问题。DwFactSize的偏移量应该是42。问题开始了!偏移量为44!首先,我想,问题是在填充比特。所以我尝试了uint,未签名的字符和attribute((packed)).这不会改变什么。

这是wav头的定义:

0-3 'RIFF'/'RIFX‘Little/大端 4-7 wRiffLength文件长度减去8字节的riff头 8-11‘波’ 12 - 15 'fmt‘ 16 - 19 wFmtSize格式块长度减去8字节头 20 - 21 wFormatTag识别PCM、ULAW等 22 - 23 wChannels 每秒24 -27个dwSamplesPerSecond采样 28 - 31 dwAvgBytesPerSec对于压缩格式来说是非常重要的。 32 - 33 wBlockAlign基本块大小 34 - 35 wBitsPerSample对于压缩格式来说是很重要的

(直到35字节与通常的44字节头一样)

36 - 37 wExtSize =0格式扩展的长度 38 - 41“事实” 42-45 dwFactSize =4事实块的长度减去8字节头 46 - 49 dwSamplesWritten实际写出的样本数 50 - 53“数据” 54-57 dwDataLength数据块长度减去8字节头

产出:

..。

直到这里..。正确..。

Fact4 38

DwFactSize 44

dwSamplesWritten 48

Data4 52

dwDataLength 56

快速破解以显示偏移问题:

代码语言:javascript
复制
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <cstddef>

typedef struct  WAV_HEADER
{
unsigned char       RIFF[4];        /* RIFF Header      */ //Magic header
unsigned long       ChunkSize;      /* RIFF Chunk Size  */
unsigned char       WAVE[4];        /* WAVE Header      */
unsigned char       fmt[4];         /* FMT header       */
unsigned long       Subchunk1Size;  /* Size of the fmt chunk: 16=PCM, 18=IEEE Float, 40=Extensible                     */
unsigned short      AudioFormat;    /* Audio format 1=PCM, 3=IEEE Float, 6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM, 65534=Extensible */
unsigned short      NumOfChan;      /* Number of channels 1=Mono 2=Stereo                   */
unsigned long       SamplesPerSec;  /* Sampling Frequency in Hz                             */
unsigned long       bytesPerSec;    /* bytes per second */
unsigned short      blockAlign;     /* 2=16-bit mono, 4=16-bit stereo , 6=24-bit stereo,8=32-bit stereo*/
unsigned short      bitsPerSample;  /* Number of bits per sample, inkl. hier=36 bytes  */
unsigned short      wExtSize;       /*  2 byte, wExtSize = 0  the length of the format extension   */
unsigned char       Fact[4];        /* "fact"  string   */
/*Problem here! -> +2bytes*/
unsigned long       DwFactSize;     /* Sampled data length,  inkl. hier bei 44 bytes */
unsigned long       dwSamplesWritten;
unsigned char       Data[4];        /* leerer string falls extensible -> Beginn nicht nach 44 sondern 68!  */
unsigned long       dwDataLength;   /* raw DataLength */
}__attribute__((packed)) wav_hdr;


int getFileSize(FILE *inFile);

int main(int argc,char *argv[])
{
char *file;
file = argv[1];
wav_hdr wavHeader;
FILE *wavFile;
int headerSize = sizeof(wav_hdr),filelength = 0;
wavFile = fopen(file,"r");
if(wavFile == NULL)
{
    printf("\nCan not open wave file. Usage: program [file] \n");
    exit(EXIT_FAILURE);
}

fread(&wavHeader,headerSize,1,wavFile);
filelength = getFileSize(wavFile);
fclose(wavFile);


std::cout << "\nRIFF " << offsetof(WAV_HEADER, RIFF) <<  std::endl;
std::cout << "\nChunkSize " << offsetof(WAV_HEADER, ChunkSize) <<  std::endl;
std::cout << "\nWAVE[4] " << offsetof(WAV_HEADER, WAVE) <<  std::endl;
std::cout << "\nfmt[4] " << offsetof(WAV_HEADER, fmt) <<  std::endl;
std::cout << "\nSubchunk1Size " << offsetof(WAV_HEADER, Subchunk1Size) <<  std::endl;
std::cout << "\nAudioFormat " << offsetof(WAV_HEADER, AudioFormat) <<  std::endl;
std::cout << "\nNumOfChan " << offsetof(WAV_HEADER, NumOfChan) <<  std::endl;
std::cout << "\nSamplesPerSec " << offsetof(WAV_HEADER, SamplesPerSec) <<  std::endl;
std::cout << "\nbytesPerSec " << offsetof(WAV_HEADER, bytesPerSec) <<  std::endl;
std::cout << "\nblockAlign " << offsetof(WAV_HEADER, blockAlign) <<  std::endl;
std::cout << "\nbitsPerSample " << offsetof(WAV_HEADER, bitsPerSample) <<  std::endl;
std::cout << "\nwExtSize (2) " << offsetof(WAV_HEADER, wExtSize) <<  std::endl;
std::cout << "\nFact[4] " << offsetof(WAV_HEADER, Fact) <<  std::endl;

std::cout << "\nDwFactSize " << offsetof(WAV_HEADER, DwFactSize) <<  std::endl;
std::cout << "\ndwSamplesWritten " << offsetof(WAV_HEADER, dwSamplesWritten) <<  std::endl;
std::cout << "\nData[4] " << offsetof(WAV_HEADER, Data) <<  std::endl;
std::cout << "\ndwDataLength " << offsetof(WAV_HEADER, dwDataLength) <<  std::endl;


return 0;
}

int getFileSize(FILE *inFile)
{
int fileSize = 0;
fseek(inFile,0,SEEK_END);
fileSize=ftell(inFile);
fseek(inFile,0,SEEK_SET);
return fileSize;
}

要生成这样的32位浮点数,88200 Wav文件: sox input16_44100.wav -b 32 -e -e output32F_88200.wav rate -s -a -v -L 88200。

EN

回答 1

Stack Overflow用户

发布于 2017-01-19 20:15:49

显然,Fact[]DwFactSize之间有两个字节的填充。

我怀疑这是因为你在那里使用typedef。只需将其编写为常规的C++定义:struct __attribute__((packed)) WAV_HEADER { ...

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41750320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档