C语言实现wav文件的读写

C语言实现wav文件的读写

  1. wav文件格式
    这里插入图片描述
//wav.h
typedef unsigned char               uint8_t;
typedef signed char                 int8_t;
typedef unsigned short int          uint16_t;
typedef signed short int            int16_t;
typedef unsigned int                uint32_t;
typedef signed int                  int32_t;

typedef struct wave_header
{
    uint8_t  riff[4]; // 'R I F F'
    uint32_t size;
    uint8_t  waveFlag[4];//' W A V E'
    uint8_t  fmt[4];//'F M T'
    uint32_t fmtLen; /* 16 for PCM */
    uint16_t tag;/* PCM = 1*/
    uint16_t channels;
    uint32_t sampFreq;
    uint32_t byteRate;
    uint16_t blockAlign;/* = NumChannels * BitsPerSample/8 */
    uint16_t bitSamp;
    uint8_t  dataFlag[4];//'D A T A'
    uint32_t length;/* data size */
} wave_header_t;

typedef struct wave_file
{
    wave_header_t header;
    uint32_t *data;
}wave_file_t;

  1. 文件操作
functionusage
freadfread(buffer,size,count,fp);
fwritefwrite(buffer,size,count,fp);
fopenFILE * fopen(const char * path,const char * mode);
fclosefclose(fp);

//fread(fa,4,5,fp); 从fp所指的文件中,每次读4个字节(一个实数)送入实数组fa中,连续读5次,即读5个实数到fa中。
3. C语言实现

//wav.c
#include <stdio.h>
#include "wav.h"

#define WAVE_FILE_HEADER_SIZE   sizeof(wave_header_t)
static char wav_header[WAVE_FILE_HEADER_SIZE];

uint32_t get_wav_data(wave_file_t *waveFile)
{
    uint8_t *dataTemp = (uint8_t *)waveFile->data;

    // check for RIFF
    memcpy(waveFile->header.riff, dataTemp, 4);
    dataTemp += 4;
    if( memcmp( (uint8_t*)waveFile->header.riff, "RIFF", 4) )
    {
        return 0;
    }

    // Get size
    memcpy(&waveFile->header.size, dataTemp, 4);
    dataTemp += 4;

    printf( "WAV header size [%d]\n", waveFile->header.size);

    // .wav file flag
    memcpy(waveFile->header.waveFlag, dataTemp, 4);
    dataTemp += 4;
    if( memcmp( (uint8_t*)waveFile->header.waveFlag, "WAVE", 4) )
    {
        return 0;
    }

    // fmt
    memcpy(waveFile->header.fmt, dataTemp, 4);
    dataTemp += 4;
    if( memcmp( (uint8_t*)waveFile->header.fmt, "fmt ", 4) )
    {
        return 0;
    }

    // fmt length
    memcpy(&waveFile->header.fmtLen, dataTemp, 4);
    dataTemp += 4;

    // Tag: PCM or not
    memcpy(&waveFile->header.tag, dataTemp, 4);
    dataTemp += 2;

    // Channels
    memcpy(&waveFile->header.channels, dataTemp, 4);
    dataTemp += 2;

    printf( "WAV channels [%d]\n", waveFile->header.channels);

    // Sample Rate in Hz
    memcpy(&waveFile->header.sampFreq, dataTemp, 4);
    dataTemp += 4;
    memcpy(&waveFile->header.byteRate, dataTemp, 4);
    dataTemp += 4;

    printf( "WAV sample_rate [%d]\n", waveFile->header.sampFreq);
    printf( "WAV byteRate [%d]\n", waveFile->header.byteRate);

    // quantize bytes for per samp point
    memcpy(&waveFile->header.blockAlign, dataTemp, 4);
    dataTemp += 2;
    memcpy(&waveFile->header.bitSamp, dataTemp, 4);
    dataTemp += 2;

    printf( "WAV bitSamp [%d]\n", waveFile->header.bitSamp);

    // Data
    memcpy(waveFile->header.dataFlag, dataTemp, 4);
    dataTemp += 4;
    if( memcmp( (uint8_t*)waveFile->header.dataFlag, "data ", 4) )
    {
        return 0;
    }
    memcpy(&waveFile->header.length, dataTemp, 4);
    dataTemp += 4;

    return 0;
}

wave_file_t wave_file_info;
uint8_t *buf;
uint32_t play_wav_file(char *file_path,char *pcm)
{
    uint32_t bytesToRead=0;
    FILE *fp=NULL;
    FILE *fptr=NULL;
    fp=fopen(file_path,"rb");
    if (!fp) {
         printf("%s can't open audio file\n",file_path);
         exit(1);
     }
     fptr=fopen(pcm,"wb");
      if (!fptr) {
         printf(" can't 2 open audio file\n");
         exit(1);
     }
     fread(&wav_header, WAVE_FILE_HEADER_SIZE, 1, fp);
     wave_file_t *newWav=&wave_file_info;
     memset(&wave_file_info, 0, sizeof(wave_file_info));
     newWav->data = (uint32_t *)&wav_header;
     get_wav_data(newWav);
      //add wav header
     fwrite(&wav_header, WAVE_FILE_HEADER_SIZE, 1, fptr);
     bytesToRead = (newWav->header.length - WAVE_FILE_HEADER_SIZE);


	 for (; bytesToRead > 0; bytesToRead--)
     {
         fread(&buf, 1, 1, fp);
         fwrite(&buf,1, 1, fptr);//写成pcm检查 正确读取 char
     }
     //fread(buf, 1, 1en, fp); 可以按需要的长度与类型读取wav
     /*static unsigned int curr_play_index = 0;
     for(int i=0;i<bytesToRead/len;i++)
     {
     		if(curr_play_index<bytesToRead)
     		{
     			fread(buf, 1, 1en, fp);
     		}
     		curr_play_index+=len;
     }*/

     fclose(fp);
     fclose(fptr);
     return bytesToRead;//when play done it's 0
}

int main(void)
{
    char wave[] = "D://1.wav";
    char pcm[] = "D://1_out.wav";
    uint32_t wav_len =play_wav_file(wave,pcm);
    printf("%d\n",wav_len);

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值