命令行PCM转成WAV

1、播放器是无法直接播放PCM音频文件。

原因是播放器不知道PCM文件的采样率、声道数、位深度(采样大小)等参数。

当PCM转成某种特定的音频文件格式后(比如转成WAV、MP3等),就能够被播放器识别播放了。

WAV是IBM和微软共同开发的文件格式,基于RIFF标准的文件格式。简单来说WAV文件可以分为两部分:文件头和PCM音频数据。一般情况文件头占44个字节,里面主要描述音频的采样率、通道数等信息。这样播放器就能直接播放WAV文件了。

2、ffmpeg命令的格式

在使用命令行之前先了解一下ffmpeg命令的格式,主要是通过 -i 把输入文件参数和输入文件分隔开:

ffmpeg 输入文件参数 -i  输入文件  输出文件参数 输出文件

3、通过下面的命令可以将PCM转成WAV
ffmpeg -ar 44100 -ac 2 -f s16le -i 小河淌水.pcm 小河淌水.wav

可以看出命令中没有设置输出文件的参数,也就是采样率、采样格式、通道数都是按照PCM的,上面命令生成的WAV文件头有78字节。对比44字节的文件头,它多增加了一个34字节大小的LIST chunk。这34个字节主要是描述FFmpeg里面libavformat动态库的版本。

4、可以通过输出参数过滤掉这个LIST chunk的信息

ffmpeg -ar 44100 -ac 2 -f s16le -i 小河淌水.pcm -bitexact 小河淌水.wav

查看文件的属性可以看到,确实多了44个字节,也就是WAV的文件头

PCM 格式的音频文件换为 WAV 格式,可以使用以下 C 语言代码: ``` #include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef int16_t sample_t; int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: pcm2wav <input file> <output file>\n"); return 1; } FILE *input_file = fopen(argv[1], "rb"); if (!input_file) { printf("Failed to open input file: %s\n", argv[1]); return 1; } FILE *output_file = fopen(argv[2], "wb"); if (!output_file) { printf("Failed to open output file: %s\n", argv[2]); fclose(input_file); return 1; } // WAV 文件头 struct { // RIFF 头 char riff_id[4]; // 固定为 "RIFF" uint32_t riff_size; // 文件总长度 - 8 char wave_id[4]; // 固定为 "WAVE" // fmt 子块 char fmt_id[4]; // 固定为 "fmt " uint32_t fmt_size; // 固定为 16 uint16_t audio_format; // 编码格式,1 表示 PCM 格式 uint16_t num_channels; // 声道数,1 表示单声道,2 表示立体声 uint32_t sample_rate; // 采样率 uint32_t byte_rate; // 数据传输率,等于每秒采样数 × 每个样本的字节数 uint16_t block_align; // 每个采样块的字节数,等于每个样本的字节数 × 声道数 uint16_t bits_per_sample; // 每个样本的位数 // data 子块 char data_id[4]; // 固定为 "data" uint32_t data_size; // 数据长度 } wav_header = { .riff_id = "RIFF", .wave_id = "WAVE", .fmt_id = "fmt ", .fmt_size = 16, .audio_format = 1, .num_channels = 1, .sample_rate = 16000, // 假设采样率为 16000 Hz .bits_per_sample = sizeof(sample_t) * 8, .data_id = "data" }; // 计算数据长度 fseek(input_file, 0, SEEK_END); uint32_t data_size = ftell(input_file); fseek(input_file, 0, SEEK_SET); // 填写 WAV 文件头 wav_header.riff_size = 36 + data_size; wav_header.byte_rate = wav_header.sample_rate * wav_header.num_channels * wav_header.bits_per_sample / 8; wav_header.block_align = wav_header.num_channels * wav_header.bits_per_sample / 8; wav_header.data_size = data_size; // 写入 WAV 文件头 fwrite(&wav_header, sizeof(wav_header), 1, output_file); // 复制数据 sample_t buffer[1024]; while (!feof(input_file)) { size_t num_read = fread(buffer, sizeof(sample_t), sizeof(buffer) / sizeof(sample_t), input_file); fwrite(buffer, sizeof(sample_t), num_read, output_file); } // 关闭文件 fclose(input_file); fclose(output_file); return 0; } ``` 你可以在命令行中使用以下命令来编译代码: ``` gcc pcm2wav.c -o pcm2wav ``` 然后使用以下命令来将 PCM 文件换为 WAV 文件: ``` ./pcm2wav input.pcm output.wav ``` 其中,`input.pcm` 是输入文件名,`output.wav` 是输出文件名。你需要将代码中的采样率、声道数等参数根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值