c++ - 音频混合算法改变音量

标签 c++ algorithm audio

我正在尝试使用以下算法混合一些音频样本:

short* FilterGenerator::mixSources(std::vector<RawData>rawsources, int numframes)
{
short* output = new short[numframes * 2]; // multiply 2 for channels

for (int sample = 0; sample < numframes * 2; ++sample)
{
    for (int sourceCount = 0; sourceCount < rawsources.size(); ++sourceCount)
    {
        if (sample <= rawsources.at(sourceCount).frames * 2)
        {
            short outputSample = rawsources.at(sourceCount).data[sample];
            output[sample] += outputSample;
        }
    }
}

// post mixing volume compression
for (int sample = 0; sample < numframes; ++sample)
{
    output[sample] /= (float)rawsources.size();
}

return output;
}

我得到了我想要的输出,除了当一个源完成时,其他源开始播放更大声的事实。我知道这是为什么,但我不知道如何正确解决它。

此外,这是我输出的音频中 Audacity 的屏幕截图: Audacity Screenshot

如您所见,肯定有问题。您可以看到音频在中心不再为零,并且一旦其中一个源播放完毕,您可以看到音频变得更响亮。

最重要的是,我想解决音量问题,但非常感谢我能做的任何其他调整!

一些额外的信息:我知道这段代码不允许单声道源,但没关系。我只打算使用立体声交错音频样本。

最佳答案

通常混合不除以源数。这意味着将普通音轨与静音音轨混合可以将其振幅减半。如果你愿意,你最终可以规范化轨道,使其在他的范围内。

代码未经测试,可能存在错误:

#include <algorithm> // for std::max 
#include <cmath>     // for std::fabs

short* FilterGenerator::mixSources(std::vector<RawData>rawsources, int numframes)
{
  // We can not use shorts immediately because can overflow
  // I use floats because in the renormalization not have distortions
  float *outputFloating = new float [numframes * 2];

  // The maximum of the absolute value of the signal 
  float maximumOutput = 0;

  for (int sample = 0; sample < numframes * 2; ++sample)
  {
      // makes sure that at the beginning is zero
      outputFloating[sample] = 0;

      for (int sourceCount = 0; sourceCount < rawsources.size(); ++sourceCount)
      {
          // I think that should be a '<'
          if (sample < rawsources.at(sourceCount).frames * 2)
              outputFloating[sample] += rawsources.at(sourceCount).data[sample];  
      }

      // Calculates the maximum
      maximumOutput = std::max (maximumOutput, std::fabs(outputFloating[sample]));
  }  

  // A short buffer
  short* output = new short [numframes * 2]; // multiply 2 for channels

  float multiplier = maximumOutput > 32767 ? 32767 / maximumOutput : 1;

  // Renormalize the track
  for (int sample = 0; sample < numframes * 2; ++sample)
      output[sample] = (short) (outputFloating[sample] * multiplier); 

  delete[] outputFloating;
  return output;
}

关于c++ - 音频混合算法改变音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28746477/

相关文章:

algorithm - 将人们分成最满意的团队

c++ - BASS "Play"流

c++ - 'juce::WildcardFileFilter' 的初始化没有匹配的构造函数

c++ - Qt和声音处理

c++ - 如何返回复杂的返回值?

C++读取文件时忽略某些字符串

实现动态滚动的算法

r - 如何将序列拆分为 k 个同质部分?

c++ - 当我运行 cxxtest 时,出现 undefined reference 错误

java - 将 C++ md5 编码转换为 android/java