如何根据时长切割WAV文件

WAV格式的文件,无非就是一个头,后面全部都是二进制数。

//wave文件头
typedef struct WaveHeader
{
    char  riff[4];              //资源交换文件标志
    int size;                    //从下个地址开始到文件结尾的字节数
    char  wave_flag[4];   //wave文件标识
    char  fmt[4];             //波形格式标识
    int fmt_len;              //过滤字节(一般为00000010H)
    short tag;            //格式种类,值为1时,表示PCM线性编码
    short channels;           //通道数,单声道为1,双声道为2
    int samp_freq;            //采样频率
    int byte_rate;//数据传输率 (每秒字节=采样频率×每个样本字节数)
    short block_align;//块对齐字节数 = channles*bit_samp/8
    short bit_samp;           //bits per sample (又称量化位数)
}wave_header_s;

typedef struct WaveStruct
{
    FILE *fp;                  //file pointer
    wave_header_s stHeader;    //header
    char data_flag[4];         //数据标识符
    int length;                //采样数据总数
    int *pData;                //data
}wave_s;

以上是WAV文件头的内容,切割WAV文件生成子文件时,主要需要修改的部分是采样数据总数和head中的size

/* 读取wav文件头信息 */
    fread(stWave.stHeader.riff, sizeof(char), 4, stWave.fp);
    fread(&stWave.stHeader.size, sizeof(int), 1, stWave.fp);
    fread(stWave.stHeader.wave_flag, sizeof(char), 4, stWave.fp);
    fread(stWave.stHeader.fmt, sizeof(char), 4, stWave.fp);
    fread(&stWave.stHeader.fmt_len, sizeof(int), 1, stWave.fp);
    fread(&stWave.stHeader.tag, sizeof(short), 1, stWave.fp);
    fread(&stWave.stHeader.channels, sizeof(short), 1, stWave.fp);
    fread(&stWave.stHeader.samp_freq, sizeof(int), 1, stWave.fp);
    fread(&stWave.stHeader.byte_rate, sizeof(int), 1, stWave.fp);
    fread(&stWave.stHeader.block_align, sizeof(short), 1, stWave.fp);
    fread(&stWave.stHeader.bit_samp, sizeof(short), 1, stWave.fp);

    do
    {
        fread(&temp, sizeof(char), 1, stWave.fp);
    }
    while('d' != temp);
    stWave.data_flag[0] = temp;

    fread(&stWave.data_flag[1], sizeof(char), 3, stWave.fp);
    fread(&stWave.length, sizeof(int), 1, stWave.fp);

/* 根据时间算出新文件大小 */
newFileDataSize = byte_rate * 新文件时长time;
根据新文件大小,计算新文件个数

/* 根据源文件生成新文件的首部 */
    memcpy (&stNewWave, &stWave, sizeof(stNewWave));
    stNewWave.length = newFileDataSize;
    stNewWave.stHeader.size = stWave.stHeader.size - (stWave.length - stNewWave.length);

下面就根据data中的内容,一点一点封装到新文件的data中

for(int i=1; i<=newFileNumber; i++)
    {
        /* 拼装新文件名 */
        sprintf(buffer,"output/%s%d.wav",filename, i);

        /* 写方式打开文件 */
        newfp=fopen(buffer,"wb");

        /* 写入新文件文件头 */
        tmp = ((char *)&stNewWave + 8);
        for(int j=0;j < (sizeof(stNewWave) - 4 - 4); j++)
        {
                fputc(*tmp,newfp);
                tmp ++;
        }

        /* 写入新文件采样内容 */
        for(int t=0; t< newFileDataSize; t++)
        {
            fputc(fgetc(stWave.fp), newfp);
        }

        fflush(newfp);
        fclose(newfp);
        printf("%s\n",buffer);
    }

全部代码已上传到CSDN,gcc编译后就可以运行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值