diff --git a/README.md b/README.md index 04ad8e7..e1c19ea 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,97 @@ NALU头结构:NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit)。 +
+
+ + +## 分离PCM16LE双声道音频采样数据的左声道和右声道 +> 注:本文中声音样值的采样频率一律是44100Hz,采样格式一律为16LE。“16”代表采样位数是16bit。由于1Byte=8bit,所以一个声道的一个采样值占用2Byte。“LE”代表Little Endian,代表2 Byte采样值的存储方式为高位存在高地址中。 + +``` C++ +// +//本程序中的函数可以将PCM16LE双声道数据中左声道和右声道的数据分离成两个文件。 +// + +#include +#include +#include + +int pcm16le_split(const char *file) +{ + if (file == NULL) { + printf("文件路径为空!\n"); + return 0; + } + + FILE *fp = fopen(file, "rb+"); + if (fp == NULL) { + printf("文件打开失败!\n"); + return 0; + } + + FILE *fp_l = fopen("./output/output_l.pcm", "wb+"); + if (fp_l == NULL) { + printf("左声道文件打开或创建失败!\n"); + return 0; + } + + FILE *fp_r = fopen("./output/output_r.pcm", "wb+"); + if (fp_r == NULL) { + printf("右声道文件打开或创建失败!\n"); + return 0; + } + + unsigned char buf[4] = {0}; + + //PCM16LE双声道数据中左声道和右声道的采样值是间隔存储的。 + //每个采样值占用2Byte空间。 + while (!feof(fp)) { + fread(buf, 1, 4, fp); + + //保存左声道的数据,一个采样值16位,两个字节 + fwrite(buf, 1, 2, fp_l); + + //保存右声道的数据 + fwrite(buf+2, 1, 2, fp_r); + } + + fclose(fp); + fclose(fp_l); + fclose(fp_r); + + return 1; +} + +int main() +{ + char file[] = "./mediadata/NocturneNo2inEflat_44.1k_s16le.pcm"; + if (pcm16le_split(file)) { + printf("操作成功!!!\n"); + } else { + printf("操作失败!!!\n"); + } +} + +``` + +从代码可以看出,PCM16LE双声道数据中左声道和右声道的采样值是间隔存储的。每个采样值占用2Byte空间。代码运行后,会把NocturneNo2inEflat_44.1k_s16le.pcm的PCM16LE格式的数据分离为两个单声道数据: +output_l.pcm:左声道数据。 +output_r.pcm:右声道数据。 + + + +
+
+ + + + + + + + +

diff --git a/mediadata/NocturneNo2inEflat_44.1k_s16le.pcm b/mediadata/NocturneNo2inEflat_44.1k_s16le.pcm new file mode 100644 index 0000000..aba7c59 Binary files /dev/null and b/mediadata/NocturneNo2inEflat_44.1k_s16le.pcm differ diff --git a/pcm16le_split.cpp b/pcm16le_split.cpp new file mode 100644 index 0000000..8aab660 --- /dev/null +++ b/pcm16le_split.cpp @@ -0,0 +1,63 @@ +// +//本程序中的函数可以将PCM16LE双声道数据中左声道和右声道的数据分离成两个文件。 +// + +#include +#include +#include + +int pcm16le_split(const char *file) +{ + if (file == NULL) { + printf("文件路径为空!\n"); + return 0; + } + + FILE *fp = fopen(file, "rb+"); + if (fp == NULL) { + printf("文件打开失败!\n"); + return 0; + } + + FILE *fp_l = fopen("./output/output_l.pcm", "wb+"); + if (fp_l == NULL) { + printf("左声道文件打开或创建失败!\n"); + return 0; + } + + FILE *fp_r = fopen("./output/output_r.pcm", "wb+"); + if (fp_r == NULL) { + printf("右声道文件打开或创建失败!\n"); + return 0; + } + + unsigned char buf[4] = {0}; + + //PCM16LE双声道数据中左声道和右声道的采样值是间隔存储的。 + //每个采样值占用2Byte空间。 + while (!feof(fp)) { + fread(buf, 1, 4, fp); + + //保存左声道的数据,一个采样值16位,两个字节 + fwrite(buf, 1, 2, fp_l); + + //保存右声道的数据 + fwrite(buf+2, 1, 2, fp_r); + } + + fclose(fp); + fclose(fp_l); + fclose(fp_r); + + return 1; +} + +int main() +{ + char file[] = "./mediadata/NocturneNo2inEflat_44.1k_s16le.pcm"; + if (pcm16le_split(file)) { + printf("操作成功!!!\n"); + } else { + printf("操作失败!!!\n"); + } +}