【问题标题】:How to access sub-chunks's data of .wav file?如何访问 .wav 文件的子块数据?
【发布时间】:2013-05-06 13:12:24
【问题描述】:

如何访问.wav文件的子块数据? 我一直在尝试将二进制数据(前 44 个字节)复制到一个结构变量(44 个字节的大小)。但是有一个问题:我确信我已经将二进制数据从文件input 复制到了一个名为hdr 的结构中。

但是当我尝试显示包含“RIFF”(字符数组)的 hdr.ChunkID 时,它不会打印“RIFF”。它什么也不打印。

#include <stdio.h>
#include <stdlib.h>

typedef struct FMT
{
    char        Subchunk1ID[4];
    int         Subchunk1Size;
    short int   AudioFormat;
    short int   NumChannels;
    int         SampleRate;
    int         ByteRate;
    short int   BlockAlign;
    short int   BitsPerSample;

} fmt;

typedef struct DATA
{
    char        Subchunk2ID[4];
    int         Subchunk2Size;
    int         Data[441000]; // 10 secs of garbage. he-he)
} data;

typedef struct header
{
    char        ChunkId[4];
    int         ChunkSize;
    char        Format[4];
    fmt         S1;
    data        S2;
} Header;



int main()
{
    FILE *input = fopen("in.wav", "rb");
    FILE *output = fopen("out.wav", "wb");

    unsigned char buf[64];
    Header hdr;

    if(input == NULL)
    {
        printf("Unable to open wave file\n");
        exit(EXIT_FAILURE);
    }

    fread(&buf, sizeof(char), 64, input);
    fwrite(&buf, sizeof(char), 64, output);

    fread(&hdr, sizeof(char), 64, output);
    printf("\n>>> %s", hdr.ChunkId);         /* Here it is. */

    fclose(input);
    fclose(output);

    return 0;
}

不明白哪里出了问题。

【问题讨论】:

  • 如果你需要读44字节,你为什么读64?你将如何处理你读取的额外 20 个字节?
  • 我有一个程序可以显示前 64 个字节并解释它们...例如前 4 个字节 ---> "RIFF" 等等。
  • 对于其余数据,您可能需要检查(例如sizeof(Header))您拥有的结构是否未被填充。如果来自 sizeof 的值与应有的值不同,则需要告诉编译器不应填充结构。

标签: c file struct binary-data


【解决方案1】:

因为您尝试从只写文件句柄中读取。使用第一个 fread 电话阅读 hdr。不需要buf 数组(或第二次读取):

Header hdr;

/* Opening files ... */

fread(&hdr, 1, 64, input);
fwrite(&hdr, 1, 64, output);

printf("\n>>> %4.4s", hdr.ChunkId); 

/* ... */

另请注意,hdr.ChunkID不会作为字符串终止,因此将其打印为字符串可能会在标题后打印看似随机的字符。这就是我在 printf 调用中添加字段长度和精度的原因。

【讨论】:

  • 无论如何添加他正在读/写到buf的地址,例如而不是fread(&amp;buf, sizeof(char), 64, input);,它应该是fread(buf, sizeof(char), 64, input);。此外,也不能保证 sizeof(Header) 等于 64。
  • @someguy 对于数组,array&amp;array 都返回指向数组中第一个元素的指针。
  • @someguy 而sizeof(hdr) 不是 64 字节,它远远超过 44000 字节,所以我将代码更改为仅读取/写入 64 字节。谢谢你提醒我。
  • 糟糕,没有正确阅读代码,但我的意思是由于对齐以及 intshort int 的长度是特定于实现的,不能保证它会工作适当地。 (虽然在这种情况下,它会,因为我们只是读取到结构中的第一个 char[4]。)
  • @someguy 你说得对,不能保证,但我认为结构很可能会被正确填充(也就是说,根本不会)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
  • 2012-10-31
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
相关资源
最近更新 更多