Pcm的多路混音 c++代码
时间: 2023-12-29 10:01:53 浏览: 23
以下是一个简单的多路PCM混音的C++代码示例:
```c++
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main() {
// 打开多个PCM文件
vector<ifstream> pcm_files;
pcm_files.emplace_back("pcm1.pcm", ios::binary);
pcm_files.emplace_back("pcm2.pcm", ios::binary);
pcm_files.emplace_back("pcm3.pcm", ios::binary);
// 获取每个PCM文件的采样率、声道数和采样位数
int sample_rate = 0, channels = 0, bits_per_sample = 0; for (auto& pcm_file : pcm_files) {
char buf[4];
pcm_file.read(buf, 4); // 读取RIFF头
pcm_file.read(buf, 4); // 读取数据大小
pcm_file.read(buf,4); // 读取WAVE头
pcm_file.read(buf, 4); // 读取fmt头
pcm_file.read(buf, 4); // 读取fmt块大小
pcm_file.read(buf, 2); // 读取编码方式
pcm_file.read(buf, 2); // 读取声道数
channels = max(channels, (int)buf[0]);
pcm_file.read(buf, 4); // 读取采样率
sample_rate = max(sample_rate, *(int*)buf);
pcm_file.read(buf, 4); // 读取每秒数据量
pcm_file.read(buf, 2); // 读取块对齐
pcm_file.read(buf, 2); // 读取采样位数
bits_per_sample = max(bits_per_sample, (int)buf[0]);
pcm_file.read(buf, 4); // 读取data头
pcm_file.read(buf, 4); // 读取数据大小
}
// 计算每个PCM文件的采样数
int sample_count = 0;
for (auto& pcm_file : pcm_files) {
pcm_file.seekg(0, ios::end);
sample_count = max(sample_count, (int)(pcm_file.tellg() - 44) * 8 / bits_per_sample / channels);
pcm_file.seekg(0, ios::beg);
}
// 创建输出PCM文件
ofstream mixed_pcm("mixed.pcm", ios::binary);
mixed_pcm.write("RIFF", 4);
int data_size = sample_count * channels * bits_per_sample / 8;
mixed_pcm.write((char*)&data_size, 4);
mixed_pcm.write("WAVE", 4);
mixed_pcm.write("fmt ", 4);
mixed_pcm.write("\x10\x00\x00\x00", 4); // fmt块大小
mixed_pcm.write("\x01\x00", 2); // 编码方式
mixed_pcm.write((char*)&channels, 2); // 声道数
mixed_pcm.write((char*)&sample_rate, 4); // 采样率
int byte_rate = sample_rate * channels * bits_per_sample / 8;
mixed_pcm.write((char*)&byte_rate, 4); // 每秒数据量
int block_align = channels * bits_per_sample / 8;
mixed_pcm.write((char*)&block_align, 2); // 块对齐
mixed_pcm.write((char*)&bits_per_sample, 2); // 采样位数
mixed_pcm.write("data", 4);
mixed_pcm.write((char*)&data_size, 4);
// 逐个读取每个PCM文件的采样并混合
vector<vector<char>> pcm_data(pcm_files.size());
for (int i = 0; i < sample_count; i++) {
for (int j = 0; j < pcm_files.size(); j++) {
pcm_files[j].read(pcm_data[j].data(), channels * bits_per_sample / 8);
if (pcm_files[j].eof()) {
pcm_data[j].assign(channels * bits_per_sample / 8, 0);
}
}
for (int k = 0; k < channels; k++) {
int sum = 0;
for (int j = 0; j < pcm_files.size(); j++) {
sum += *(short*)(pcm_data[j].data() + k * bits_per_sample / 8);
}
short value = sum / pcm_files.size();
mixed_pcm.write((char*)&value, bits_per_sample / 8);
}
}
// 关闭所有文件
for (auto& pcm_file : pcm_files) {
pcm_file.close();
}
mixed_pcm.close();
return 0;
}
```
该代码假设所有PCM文件的采样率、声道数和采样位数相同,且每个PCM文件的数据大小为44字节加上采样数乘以声道数乘以采样位数除以8字节。如果不满足这些条件,需要进行相应的修改。