C++写wav文件到磁盘,为什么声音这么大?

C++ write wav file to disk, why is it so loud?

我已经编写了一些代码,以 .wav 格式将堆分配的浮点数组写入磁盘。 它工作得很好,除了输出非常响亮和失真。

这是我目前编写wav文件的代码:

typedef struct WAV_HEADER {
  uint8_t riff[4] = {'R', 'I', 'F', 'F'};
  uint32_t overall_size;
  uint8_t wave[4] = {'W', 'A', 'V', 'E'};
  uint8_t fmt_chunk_marker[4] = {'f', 'm', 't', ' '};
  uint32_t length_of_fmt;
  uint16_t format_type;
  uint16_t channels;
  uint32_t sample_rate;
  uint32_t byterate;
  uint16_t block_align;
  uint16_t bits_per_sample;
  uint8_t data_chunk_header[4] = {'d', 'a', 't', 'a'};
  uint32_t data_size;
} WavHeader;


int wav_write(const char* path, float* data, uint32_t size, float sample_freq,
              uint16_t bits_per_sample, uint16_t nr_channels) {



  WavHeader header = {};
  header.length_of_fmt = 16;
  header.format_type = 1;
  header.channels = nr_channels;
  header.sample_rate = sample_freq;
  header.bits_per_sample = bits_per_sample;
  header.byterate = header.sample_rate * header.channels * (header.bits_per_sample / 8);
  header.block_align = (header.bits_per_sample / 8) * header.channels;
  header.data_size = sizeof(&data[0]) * (size >> 3);
  header.overall_size = (header.data_size);

  FILE* out = fopen(path, "wb");
  if (out == NULL) {
    printf("Could not write to %s\n", path);
    return 0;
  }

  fwrite(&header, sizeof(header), 1, out);
  fseek(out,0,SEEK_END);

  fwrite(&data[0], sizeof(&data[0]), size, out);

  fclose(out);

  return 1;
}

我在使用此代码之前所做的是使用 SDL2 加载 2 个 wav 文件, 然后将它们的数据“粘合”在一起以生成 1 个单一的 wav 文件。 我正在使用 SDL_QueueAudio 播放“粘合”数据,听起来很完美,没有问题!

唯一的问题是当我使用我编写的这个函数导出数据时。 输出非常响亮且失真。

我什至在 Bitwig (DAW) 中打开导出的 .wav 文件来查看波形,它看起来很奇怪:

正如我所说, 当我使用 SDL2 播放粘合数据时,它听起来很完美......所以我猜我的 wav_write 函数有问题。

我是这样称呼它的:

  char buff[256];
  sprintf(buff, "%s.wav", this->project_name.c_str());
  wav_write(buff, this->playback_buffer, this->playback_buffer_size_bytes, PLAYBACK_FREQ, 32, 2);

如有任何帮助,我们将不胜感激。 干杯!

您在 header 中使用了错误的格式类型。

如您所见,here 您使用 format_type 1 作为 PCM 数据,但您使用的是浮点数据。

您应该改用 3