c语言中回调函数的运用

用回调函数的方式实现从一个wav文件中读取数据,写到一个新建的wav中去。

该回答引用GPT:
使用回调函数实现从一个wav文件中读取数据,写到一个新建的wav中去,首先需要定义一个回调函数,该函数接受一个参数,该参数是从wav文件中读取的数据,然后将该参数写入新建的wav文件中。

// 定义回调函数
void callback(char *data) {
    // 打开新建的wav文件
    FILE *fp = fopen("new.wav", "wb");
    // 将参数data写入新建的wav文件中
    fwrite(data, 1, sizeof(data), fp);
    // 关闭文件
    fclose(fp);
}

// 从wav文件中读取数据
char *data = read_wav_file("old.wav");
// 调用回调函数,将读取的数据写入新建的wav文件中
callback(data);

如还有疑问,可留言帮助解决。

  • 这篇文章:前端通过浏览器识别解决IE浏览器中audio标签无法播放.wav文件 也许能够解决你的问题,你可以看下
  • 除此之外, 这篇博客: 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;
    }