在Flutter中混合8位音频文件

chhkpiq4  于 2023-04-13  发布在  Flutter
关注(0)|答案(1)|浏览(193)

我试图混合多个WAV文件成一个使用混合算法,我发现在chatGPT答案和其他网站。
我尝试了简单的步骤混合音频使用下面的代码:

double mixingRatio = 0.5;

    Uint8List? list = fileData1;
    for(int i = 0; i < fileData1.length; i++) {
      int mixedValue = ((1 - mixingRatio) * fileData1[i] + mixingRatio * fileData2[i]).round().clamp(0, 255);
      list[i] = mixedValue;
    }

    return list;
  }

有太多的剪辑,即使我夹紧(0-255)。它仍然剪辑如图所示。输入文件都是规范化的,并从Audacity确认。

寻找这个简单问题的数学解决方案。我不想使用FFmpeg,因为它不适用于实时数据。

谢谢
编辑:
这就是我如何导入原始音频。

zpgglvta

zpgglvta1#

在8位无符号PCM中,有效范围为0-255,128为“零”值。(高于128的值位于波形的上半部分,低于128的值位于波形的下半部分。)
在对这些值进行数学运算(例如缩放、加法)之前,需要将它们归一化。这实际上就像减去128一样简单,因此最终得到的int在-128到127之间。现在可以缩放和添加这些值。
当然,在将得到的钳位(-128和127之间)值存储回无符号PCM字节数组之前,需要将偏置值加回。
例如:

final mixedValue = ((1 - mixingRatio) * (fileData1[i] - 128) +
              mixingRatio * (fileData2[i] - 128))
          .round()
          .clamp(-128, 127) +
      128;

顺便说一下,你似乎用结果覆盖了fileData1。这可能不是你想要的。仔细检查一下,因为这可能是你的问题。两个公式给予了 * 不同 * 的值。试试这个:

void main() {
  print(oldWay(0.5, 113, 143)); // prints 113
  print(newWay(0.5, 113, 143)); // prints 128 (the correct value)
}

int oldWay(double r, int a, int b) {
  return ((1 - r) * a + r * a).round().clamp(0, 255);
}

int newWay(double r, int a, int b) {
  return ((1 - r) * (a - 128) + r * (b - 128)).round().clamp(-128, 127) + 128;
}

相关问题