You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现PCM转WAV:头部参数与数据追加问题求助

PCM to WAV Conversion: Fixing Header Calculations & Data Writing Issues

Hey there! Let’s work through your PCM-to-WAV conversion problems—this is a super common task with a few easy-to-miss details, so let’s break it down step by step.

1. Correct WAV Header Parameter Calculations

First, let’s validate your existing calculations (you’re mostly on the right track!) and clear up the chunk_size/data_size confusion:

Confirmed Correct Parameters

With your specs (44100 Hz, 1 channel, 16-bit depth):

  • fmt_length = 16: ✅ Correct—this is fixed for uncompressed PCM format.
  • byte_rate = (sample_rate * bits_per_sample * channels)/8: ✅ Correct. For your values, that’s (44100 * 16 * 1)/8 = 88200 bytes per second.
  • block_align = (channels * bits_per_sample)/8: ✅ Correct. That’s (1 * 16)/8 = 2 bytes per sample frame (critical for ensuring proper data alignment).
  • no_of_samples = (data_size * 8) / (channels * bits_per_sample): ✅ Correct. This gives the total number of audio samples in your PCM data.
  • Duration calculation: float time = (float) data_size / (float) byte_rate: ✅ Correct (you can simplify this by using byte_rate directly instead of expanding the formula).

Clearing Up chunk_size & data_size Confusion

Your calculation for chunk_size = 36 + data_size is correct—here’s why:

  • The WAV file’s RIFF chunk size excludes the first 8 bytes of the file (the "RIFF" identifier itself, plus the chunk_size field).
  • The rest of the file (WAVE header + fmt subchunk + data subchunk) totals 36 + data_size bytes:
    • WAVE identifier: 4 bytes
    • fmt subchunk: 24 bytes (4-byte ID + 4-byte size + 16-byte format data)
    • data subchunk header: 8 bytes (4-byte ID + 4-byte data_size)
    • data_size: your raw PCM data length

So chunk_size is indeed 36 + data_size, and the total WAV file size will be 8 + chunk_size = 44 + data_size (the 8 bytes are the RIFF ID and chunk_size field).

2. Fixing the PCM Data Writing Code

Your current loop has a critical mistake: you’re looping chunk_size times, but you only need to write data_size bytes of PCM data. chunk_size includes header data, so writing that many bytes will either read past the end of your PCM file or write garbage data into the WAV.

Correct Approach (Batch I/O for Efficiency)

Always use batch reading/writing instead of single-byte operations—it’s faster and less error-prone. Make sure to open both files in binary mode (add b to the fopen mode, e.g., "rb"/"wb") to avoid line-ending conversion issues on Windows:

// Reset PCM file pointer to the start (in case you used ftell to get data_size earlier)
fseek(ptr2, 0, SEEK_SET);

char buffer[4096]; // Use a reasonable buffer size
size_t bytes_read;

// Read PCM data in chunks and write directly to the WAV file
while ((bytes_read = fread(buffer, 1, sizeof(buffer), ptr2)) > 0) {
    fwrite(buffer, 1, bytes_read, ptr);
}

If You Must Use Single-Byte I/O

If you need to stick with single-byte operations, fix the loop limit to data_size and add a check for EOF:

fseek(ptr2, 0, SEEK_SET);
for (int n = 0; n < data_size; n++) {
    int a = fgetc(ptr2);
    if (a == EOF) break; // Stop if we hit the end of the PCM file early
    fwrite(&a, sizeof(char), 1, ptr);
}

3. Byte Order (Endianness) Considerations

WAV files require little-endian byte order for all header numeric fields (32-bit integers like sample_rate, 16-bit integers like channels). For 16-bit PCM data, little-endian is also standard.

  • If you’re on a little-endian system (e.g., x86/x86_64 computers), you can write integers directly (but using endian-safe functions is still good practice).
  • If you’re on a big-endian system (e.g., some ARM devices), convert values to little-endian before writing:
    • Use htole32() for 32-bit values (like sample_rate, byte_rate, chunk_size)
    • Use htole16() for 16-bit values (like channels, bits_per_sample, block_align)

Example for writing the sample rate:

uint32_t le_sample_rate = htole32(44100);
fwrite(&le_sample_rate, sizeof(uint32_t), 1, ptr);

Quick Checklist Before Testing

  1. Verify you’re opening files in binary mode ("rb"/"wb").
  2. Double-check that data_size is accurately calculated (either via ftell on the PCM file or the formula).
  3. Ensure all header fields are written in little-endian byte order.
  4. Write only data_size bytes of PCM data to the WAV file.

内容的提问来源于stack exchange,提问作者shashank arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:09:46