首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合音频:添加音频缓冲区

混合音频:添加音频缓冲区
EN

Stack Overflow用户
提问于 2021-09-03 17:19:24
回答 2查看 79关注 0票数 0

我有2个或更多的音频帧,结构如下:

代码语言:javascript
复制
   int sample_rate;    // The sample-rate of this buffer (48000 or 44100 normaly)
   int no_channels;    // The number of audio channels
   int no_samples;     // The number of audio samples per channel (n elements in data array)
   float* p_data;      // The audio data

将两个音频缓冲区添加到一起非常简单: frameInput1;frameInput2;

代码语言:javascript
复制
    frameOutput.sample_rate = 48000;
    frameOutput.no_channel = 1;
    frameOutput.no_sample = 1000;
    frameOutput.p_data = (float*)malloc(frameOutput.no_sample * frameOutput.no_channel * sizeof(float))

    for(int i=0; i<frameOutput.no_sample; i++){
         frameOutput.p_data[i] = frameInput1.p_data[i] + frameInput2.p_data[i];
     }

我用相同的样本创建了一个音频缓冲区,并为数据数组中的每个样本添加了输入帧

但是如果我有不同no_sample或不同sample_rate的音频缓冲区呢?

例如:

代码语言:javascript
复制
     input1.sample_rate = 48000hz; input1.no_sample = 1000 ;
     input2.sample_rate = 44100hz; input2.no_sample = 600 ;

如何将这两个输入相加?

EN

回答 2

Stack Overflow用户

发布于 2021-09-04 22:58:16

只需根据sample_rate缩放缓冲区中的地址即可:

代码语言:javascript
复制
float in1_rate_scale = float(input1.sample_rate) / frameOutput.sample_rate;
float in2_rate_scale = float(input2.sample_rate) / frameOutput.sample_rate;

for (int i = 0; i < frameOutput.no_sample; i++) {
    frameOutput.p_data[i] = frameInput1.p_data[i*in1_rate_scale] + frameInput2.p_data[i * in2_rate_scale];
}

无论如何,记住,仅仅添加"volume“值是错误的,当两个缓冲区的响度都达到最大时,很容易溢出。但这是另一个问题,也是你面前的另一个问题。

票数 0
EN

Stack Overflow用户

发布于 2021-09-04 23:44:01

我假设您的程序正在处理两个音频流,并且每个音频流都为您提供一系列音频缓冲区。

如果是这样,那么每个缓冲区中的音频帧数不是音频的基本特征,而只是音频样本如何打包在一起的副作用(例如,流A的生产者决定将1000个样本放在一个缓冲区中,而流B的生产者决定只将600个样本放在一起)。

理想情况下,你可以告诉你的流生产者给你一个固定(和相等)帧数的音频缓冲区,这样你就可以逐字地把样本加在一起,但是如果你不能让他们这样做,那么你就需要实现某种缓冲机制,在某种FIFO队列中保存来自两个缓冲区中较大的“额外”帧,然后在你的下一个混合操作中使用它们作为第一个样本。这可能会变得有点复杂,所以除非你最关心的是性能,否则我建议只为每个输入流保留一个音频帧的先进先出队列(例如std::dequeue<float>或类似的),并且总是将所有新收到的音频帧从该输入流推到该先进先出队列的尾部,然后在需要混合音频时从每个先进先出队列的头部弹出帧。通过这种方式,您可以将音频混合与输入音频缓冲区的大小解耦,这样无论输入流为您生成什么,您的混合代码都将正常工作。(请注意,输出/混合音频缓冲区的最大大小将等于当时最短FIFO队列中的音频帧数量)

处理不同的采样率是一个更难解决的问题,特别是如果您希望您的输出音频具有良好的声音质量。要正确处理它,您需要使用采样速率转换算法(如libsamplerate)将其中一个流的采样速率转换为另一个流的采样速率(或者,如果您愿意,将两个流的采样速率转换为输出流的采样速率)。一旦你这样做了,然后你可以将两个匹配速率的流逐个样本地添加在一起,就像以前一样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69048608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档