C语言实现WAV文件读取

一直以来我都是使用python的wave库读写wav文件的

由于项目需要,故而需要一个读取WAV文件的库

WAV文件是由块(Chunk)组成

读取wav文件需要寻找两个块

fmt 块(音频参数)和 data 块(音频数据)

需要的头文件

// Need Head File
#include <stdio.h>
#include <string.h>

块的定义("写"部分还没有实现,因为我有其他实现的方式)

// Chunk
typedef struct _CHUNK_{
    // File Offset
    unsigned Offset;
    // Chunk Size
    unsigned Size;
    // Chunk ID
    char ID[4];
    // Data Buffer (For Write)
    void* Data;
} CHUNK,*rCHUNK;

"WAV类"

包含上述两个需要的块

// WAV Struct
typedef struct _WAV_{
    FILE *fp;
    CHUNK subFMT,subDATA;
} WAV,*rWAV;

读取一个块

// Read Chunk
int __ReadChunk(rCHUNK ck,FILE *fp){
    int ret = 1;
    ck->Offset = ftell(fp);
    ret &= fread(ck->ID,4,1,fp);
    ret &= fread(&ck->Size,4,1,fp);
    return !ret;
}

知道上一个块,去寻找下一个块

这个地方有些难度

// Move To Next Chunk
int __NextChunk(rCHUNK buf,rCHUNK last,FILE *fp){
    int ret = 0;
    if(last){
        // Move to the last chunk
        ret |= fseek(fp,last->Offset,SEEK_SET);
        // Move to the next chunk
        ret |= fseek(fp,last->Size+8,SEEK_CUR);
    }
    // read chunk
    return ret | __ReadChunk(buf,fp);
}

那么可以开始寻找 fmt 和 data 块了

具体步骤

寻找下一个块

如果下一个块的ID是正在寻找的,那么退出循环

否则再下一个块,直到找完为止

int LoadWav(rWAV wav,FILE *fp){
    
    CHUNK tmp;
    tmp.Offset = 0;
    tmp.Size = 4;
    int flag;

    wav->fp = fp;

    // Find FMT Chunk
    flag = 2;
    while(!__NextChunk(&tmp,&tmp,fp)){
        if(!memcmp(tmp.ID,"fmt ",4)){
            flag = 0;
            break;
        }
    }
    if(flag) return flag;

    wav->subFMT = tmp;

    // Find data Chunk
    flag = 2;
    while(!__NextChunk(&tmp,&tmp,fp)){
        if(!memcmp(tmp.ID,"data ",4)){
            flag = 0;
            break;
        }
    }
    if(flag) return flag;

    wav->subDATA = tmp;

    return 0;
}

再写个代码测试一下

打印出 fmt 和 data 块的位置和块数据大小

#include "wav.h"

int main(){
    WAV wav;
    FILE *fp = fopen("3.wav","rb");
    int flag = 0;
    if(flag = LoadWav(&wav,fp)) printf("Load Fail! return code %d\n",flag);
    else{
        printf("fmt at %u , Size is %u\n",wav.subFMT.Offset,wav.subFMT.Size);
        printf("data at %u , Size is %u\n",wav.subDATA.Offset,wav.subDATA.Size);
    }
    fclose(fp);
    return 0;
}

EOF awa

(花了一个下午想出来的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值