我正在做一个小程序,用C语言读写32位wav文件。

但是,我有一个问题。

编译后,有时程序运行良好,但有时却无法运行...

  • 输出的wav文件为空
  • 输出的wav文件(1秒)太大,大于5GB ...

  • 我真的堆在这里...
    有人知道解决方案吗?

    下面是我的程序

    ↓wave32.h↓
    typedef struct
    {
      int fs;
      int bits;
      int length;
      double *s;
    } MONO_PCM;
    
    void wave_read_32bit_mono(MONO_PCM *pcm, char *file_name)
    {
      FILE *fp;
      char riff_chunk_ID[4];
      long riff_chunk_size;
      char file_format_type[4];
      char fmt_chunk_ID[4];
      long fmt_chunk_size;
      short wave_format_type;
      short channel;
      long samples_per_sec;
      long bytes_per_sec;
      short block_size;
      short bits_per_sample;
      char data_chunk_ID[4];
      long data_chunk_size;
      int data;
      int n;
    
      fp = fopen(file_name, "rb");
    
      fread(riff_chunk_ID, 1, 4, fp);
      fread(&riff_chunk_size, 4, 1, fp);
      fread(file_format_type, 1, 4, fp);
      fread(fmt_chunk_ID, 1, 4, fp);
      fread(&fmt_chunk_size, 4, 1, fp);
      fread(&wave_format_type, 2, 1, fp);
      fread(&channel, 2, 1, fp);
      fread(&samples_per_sec, 4, 1, fp);
      fread(&bytes_per_sec, 4, 1, fp);
      fread(&block_size, 2, 1, fp);
      fread(&bits_per_sample, 2, 1, fp);
      fread(data_chunk_ID, 1, 4, fp);
      fread(&data_chunk_size, 4, 1, fp);
    
    
      pcm->fs = samples_per_sec;
      pcm->bits = bits_per_sample;
      pcm->length = data_chunk_size / 4;
      pcm->s = calloc(pcm->length, sizeof(double));
    
      for (n = 0; n < pcm->length; n++)
      {
        fread(&data, 4, 1, fp);
        pcm->s[n] =  ( (double)data / 2147483648.0 ) ;
      }
    
      fclose(fp);
    }
    void wave_write_32bit_mono(MONO_PCM *pcm, char *file_name)
    {
      FILE *fp;
      char riff_chunk_ID[4];
      long riff_chunk_size;
      char file_format_type[4];
      char fmt_chunk_ID[4];
      long fmt_chunk_size;
      short wave_format_type;
      short channel;
      long samples_per_sec;
      long bytes_per_sec;
      short block_size;
      short bits_per_sample;
      char data_chunk_ID[4];
      long data_chunk_size;
      double s;
      int data;
      int n;
    
      riff_chunk_ID[0] = 'R';
      riff_chunk_ID[1] = 'I';
      riff_chunk_ID[2] = 'F';
      riff_chunk_ID[3] = 'F';
      riff_chunk_size = 36 + pcm->length * 2;
      file_format_type[0] = 'W';
      file_format_type[1] = 'A';
      file_format_type[2] = 'V';
      file_format_type[3] = 'E';
    
      fmt_chunk_ID[0] = 'f';
      fmt_chunk_ID[1] = 'm';
      fmt_chunk_ID[2] = 't';
      fmt_chunk_ID[3] = ' ';
      fmt_chunk_size = 16;
      wave_format_type = 1;
      channel = 1;
      samples_per_sec = pcm->fs;
      bytes_per_sec = pcm->fs * pcm->bits / 8;
      block_size = pcm->bits / 8;
      bits_per_sample = pcm->bits;
    
      data_chunk_ID[0] = 'd';
      data_chunk_ID[1] = 'a';
      data_chunk_ID[2] = 't';
      data_chunk_ID[3] = 'a';
      data_chunk_size = pcm->length * 4;
    
      fp = fopen(file_name, "wb");
    
      fwrite(riff_chunk_ID, 1, 4, fp);
      fwrite(&riff_chunk_size, 4, 1, fp);
      fwrite(file_format_type, 1, 4, fp);
      fwrite(fmt_chunk_ID, 1, 4, fp);
      fwrite(&fmt_chunk_size, 4, 1, fp);
      fwrite(&wave_format_type, 2, 1, fp);
      fwrite(&channel, 2, 1, fp);
      fwrite(&samples_per_sec, 4, 1, fp);
      fwrite(&bytes_per_sec, 4, 1, fp);
      fwrite(&block_size, 2, 1, fp);
      fwrite(&bits_per_sample, 2, 1, fp);
      fwrite(data_chunk_ID, 1, 4, fp);
      fwrite(&data_chunk_size, 4, 1, fp);
    
      for (n = 0; n < pcm->length; n++)
      {
        s = (pcm->s[n]) * 2147483648.0;
    
    
        if (s > 2147483647.0)
        {
          s = 2147483647.0;
        }
        else if (s < -2147483647.0)
        {
          s = -2147483647.0;
        }
    
        data = (int)(s + 0.5);
        fwrite(&data, 4, 1, fp);
      }
    
      fclose(fp);
    }
    

    ↓wave32.c↓
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <math.h>
    #include "wave32.h"
    
    int main(void)
    {
      MONO_PCM pcm0, pcm1;
      int n;
    
      wave_read_32bit_mono(&pcm0, "sine32.wav"); // 1 sec sine wave
    
      pcm1.fs = pcm0.fs;
      pcm1.bits = pcm0.bits;
      pcm1.length = pcm0.length;
      pcm1.s = calloc(pcm1.length, sizeof(double));
    
      for (n = 0; n < pcm1.length; n++)
      {
    
        pcm1.s[n] = pcm0.s[n];
    
      }
    
      wave_write_32bit_mono(&pcm1, "b.wav");
    
      free(pcm0.s);
      free(pcm1.s);
    
      return 0;
    }
    

    最佳答案

    我猜您的平台长度为8个字节。

    您可以使用以下命令简单地检查它:

    printf("Long= %zu bytes - int= %zu bytes\n", sizeof(long), sizeof(int));
    

    然后,当您使用例如
    fread(&riff_chunk_size, 4, 1, fp);
    

    由于字节顺序,您错误地读取了该值。

    将所有长类型切换为int或更好地添加
    #include <stdint.h>
    

    并将变量类型更改为:
  • long-> int32_t
  • int-> int32_t
  • short-> int16_t
  • 关于c - 用C读写32bit WAV文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37154257/

    10-11 15:31