c语言如何将数据写入wav文件

c语言如何将数据写入wav文件

C语言如何将数据写入WAV文件的关键步骤包括:创建并打开文件、写入WAV文件头、写入音频数据、关闭文件。 其中,写入WAV文件头是最重要的一步,因为WAV文件有特定的格式要求,必须按照规范来写入头信息,才能让音频播放器正确识别文件内容。

在详细描述写入WAV文件头之前,首先要理解WAV文件的基本结构。WAV文件由三个主要部分组成:RIFF文件头、格式块、数据块。RIFF文件头定义了文件类型和文件大小,格式块描述了音频数据的格式(如采样率、通道数、位深等),数据块则包含实际的音频数据。

以下将详细讲解如何在C语言中实现上述步骤:

一、创建并打开文件

在C语言中,可以使用标准库函数fopen来创建并打开文件。需要以二进制写入模式打开文件,以便正确写入所有数据类型。

#include <stdio.h>

#include <stdlib.h>

FILE *create_wav_file(const char *filename) {

FILE *file = fopen(filename, "wb");

if (!file) {

perror("Failed to create file");

exit(EXIT_FAILURE);

}

return file;

}

二、写入WAV文件头

WAV文件头是文件结构的关键部分,它定义了音频文件的格式信息。以下是WAV文件头的基本结构:

  1. RIFF文件头
    • Chunk ID: "RIFF"
    • Chunk Size: 4 bytes (文件大小 – 8)
    • Format: "WAVE"
  2. 格式块(fmt chunk)
    • Subchunk1 ID: "fmt "
    • Subchunk1 Size: 16 bytes (PCM格式)
    • Audio Format: 1 (PCM)
    • Number of Channels: 1 (单声道)或2 (立体声)
    • Sample Rate: 采样率(如44100 Hz)
    • Byte Rate: 采样率 × 通道数 × 每个样本的字节数
    • Block Align: 通道数 × 每个样本的字节数
    • Bits per Sample: 每个样本的位数(如16位)
  3. 数据块(data chunk)
    • Subchunk2 ID: "data"
    • Subchunk2 Size: 音频数据的字节数

void write_wav_header(FILE *file, int sample_rate, int bits_per_sample, int channels, int data_size) {

int byte_rate = sample_rate * channels * bits_per_sample / 8;

short block_align = channels * bits_per_sample / 8;

fwrite("RIFF", 1, 4, file); // ChunkID

int chunk_size = 36 + data_size; // ChunkSize

fwrite(&chunk_size, 4, 1, file);

fwrite("WAVE", 1, 4, file); // Format

fwrite("fmt ", 1, 4, file); // Subchunk1ID

int subchunk1_size = 16; // Subchunk1Size

fwrite(&subchunk1_size, 4, 1, file);

short audio_format = 1; // AudioFormat (PCM)

fwrite(&audio_format, 2, 1, file);

fwrite(&channels, 2, 1, file); // NumChannels

fwrite(&sample_rate, 4, 1, file); // SampleRate

fwrite(&byte_rate, 4, 1, file); // ByteRate

fwrite(&block_align, 2, 1, file); // BlockAlign

fwrite(&bits_per_sample, 2, 1, file); // BitsPerSample

fwrite("data", 1, 4, file); // Subchunk2ID

fwrite(&data_size, 4, 1, file); // Subchunk2Size

}

三、写入音频数据

音频数据可以是从其他来源(如录音设备或其他音频文件)读取的PCM数据。以下是一个示例,演示如何写入简单的正弦波数据:

void write_audio_data(FILE *file, int sample_rate, int bits_per_sample, int channels, int duration) {

int samples = sample_rate * duration;

short amplitude = 32760; // 最大振幅

double frequency = 440.0; // A4音符频率

for (int i = 0; i < samples; i++) {

double sample = amplitude * sin((2 * M_PI * frequency) / sample_rate * i);

short sample_value = (short)sample;

fwrite(&sample_value, sizeof(short), 1, file);

}

}

四、关闭文件

文件写入完成后,使用fclose关闭文件以确保数据正确写入磁盘。

void close_wav_file(FILE *file) {

fclose(file);

}

五、完整示例

将上述步骤整合在一起,形成一个完整的示例程序:

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

FILE *create_wav_file(const char *filename);

void write_wav_header(FILE *file, int sample_rate, int bits_per_sample, int channels, int data_size);

void write_audio_data(FILE *file, int sample_rate, int bits_per_sample, int channels, int duration);

void close_wav_file(FILE *file);

int main() {

const char *filename = "output.wav";

int sample_rate = 44100;

int bits_per_sample = 16;

int channels = 1;

int duration = 5; // 5秒钟

FILE *file = create_wav_file(filename);

int data_size = sample_rate * duration * bits_per_sample / 8 * channels;

write_wav_header(file, sample_rate, bits_per_sample, channels, data_size);

write_audio_data(file, sample_rate, bits_per_sample, channels, duration);

close_wav_file(file);

printf("WAV file '%s' created successfully.n", filename);

return 0;

}

FILE *create_wav_file(const char *filename) {

FILE *file = fopen(filename, "wb");

if (!file) {

perror("Failed to create file");

exit(EXIT_FAILURE);

}

return file;

}

void write_wav_header(FILE *file, int sample_rate, int bits_per_sample, int channels, int data_size) {

int byte_rate = sample_rate * channels * bits_per_sample / 8;

short block_align = channels * bits_per_sample / 8;

fwrite("RIFF", 1, 4, file); // ChunkID

int chunk_size = 36 + data_size; // ChunkSize

fwrite(&chunk_size, 4, 1, file);

fwrite("WAVE", 1, 4, file); // Format

fwrite("fmt ", 1, 4, file); // Subchunk1ID

int subchunk1_size = 16; // Subchunk1Size

fwrite(&subchunk1_size, 4, 1, file);

short audio_format = 1; // AudioFormat (PCM)

fwrite(&audio_format, 2, 1, file);

fwrite(&channels, 2, 1, file); // NumChannels

fwrite(&sample_rate, 4, 1, file); // SampleRate

fwrite(&byte_rate, 4, 1, file); // ByteRate

fwrite(&block_align, 2, 1, file); // BlockAlign

fwrite(&bits_per_sample, 2, 1, file); // BitsPerSample

fwrite("data", 1, 4, file); // Subchunk2ID

fwrite(&data_size, 4, 1, file); // Subchunk2Size

}

void write_audio_data(FILE *file, int sample_rate, int bits_per_sample, int channels, int duration) {

int samples = sample_rate * duration;

short amplitude = 32760; // 最大振幅

double frequency = 440.0; // A4音符频率

for (int i = 0; i < samples; i++) {

double sample = amplitude * sin((2 * M_PI * frequency) / sample_rate * i);

short sample_value = (short)sample;

fwrite(&sample_value, sizeof(short), 1, file);

}

}

void close_wav_file(FILE *file) {

fclose(file);

}

这段代码实现了创建一个包含5秒钟A4音符的WAV文件。通过理解和应用这些步骤,你可以根据需要生成和写入不同类型的音频数据。

相关问答FAQs:

1. 如何在C语言中将数据写入WAV文件?
在C语言中,可以使用文件操作函数将数据写入WAV文件。首先,需要使用fopen函数打开一个WAV文件,然后使用fwrite函数将数据写入文件中。具体的步骤如下:

  • 使用fopen函数打开一个WAV文件,并指定打开方式为二进制写入模式。
  • 使用fwrite函数将数据写入WAV文件中,可以通过指定写入的数据大小和数量来实现。
  • 使用fclose函数关闭文件。

2. 如何在C语言中读取数据并将其写入WAV文件?
在C语言中,可以使用文件操作函数读取数据,并将其写入WAV文件。首先,需要使用fopen函数打开一个源文件,然后使用fread函数读取数据,再使用fopen函数打开一个目标WAV文件,最后使用fwrite函数将数据写入目标文件中。具体的步骤如下:

  • 使用fopen函数打开源文件,并指定打开方式为二进制读取模式。
  • 使用fread函数从源文件中读取数据,可以通过指定读取的数据大小和数量来实现。
  • 使用fopen函数打开目标WAV文件,并指定打开方式为二进制写入模式。
  • 使用fwrite函数将读取到的数据写入目标WAV文件中。
  • 使用fclose函数关闭源文件和目标文件。

3. 如何在C语言中生成一个空白的WAV文件?
在C语言中,可以使用文件操作函数生成一个空白的WAV文件。首先,需要使用fopen函数打开一个WAV文件,然后使用fwrite函数写入WAV文件的头部信息,最后使用fclose函数关闭文件。具体的步骤如下:

  • 使用fopen函数打开一个WAV文件,并指定打开方式为二进制写入模式。
  • 使用fwrite函数写入WAV文件的头部信息,包括文件格式、采样率、声道数等。
  • 使用fclose函数关闭文件。

原创文章,作者:Edit1,如若转载,请注明出处:https://docs.pingcode.com/baike/1078751

(0)
Edit1Edit1
上一篇 2024年8月28日 下午6:10
下一篇 2024年8月28日 下午6:10
免费注册
电话联系

4008001024

微信咨询
微信咨询
返回顶部