audio - 如何进行单声道到立体声的转换?

标签 audio pcm resampling

我正在使用 libswresample 将任何 PCM 格式重新采样为 44.1kHz、16 位整数、立体声。

我正在对生成的音频流进行一些音频音量分析,我发现如果我有 44.1kHz、16 位 int 单声道作为源,我大致有以下公式:

leftSample = sourceSample / sqrt(2);
rightSample = sourceSample / sqrt(2);

但我期待的是:

leftSample = sourceSample;
rightSample = sourceSample;

(如果源是立体声,我只需 leftSample = leftSourceSample; rightSample = rightSourceSample;。)

我的期望来自几个来源:

  1. 这可能就是我自己的直接解决方案。
  2. 我四处搜索了一下,其他人似乎也做了同样的事情,例如here .
  3. 在一个非常常见的 ReplayGain 实现中(我实际上知道的唯一一个,基本上到处都在使用,我认为最初来自 mp3gain;可以看到一个副本 here ),它也这样做:

    switch ( num_channels) {
    case  1: right_samples = left_samples;
    case  2: break;
    default: return GAIN_ANALYSIS_ERROR;
    }
    

    这尤其是。相关的,因为 ReplayGain 是通过此实现使用单声道引用声音(粉红噪声,可以下载 here )进行校准的。

    在ReplayGain规范中,也是这样计算的(参见here)。

在我尝试自己实现 ReplayGain 并偶然发现这一点后,我感到困惑。

所以,有一些问题:

  1. libswresample 为什么要这样做?
  2. 这是 libswresample 中预期的情况还是一个错误? (我试图从源头理解(例如 here ),但我还没有完全理解这一切。)我添加了一个错误报告 here .
  3. 什么是“正确”的解决方案?
  4. 其他玩家在做什么?
  5. 如果向普通声卡提供单声道样本,它会做什么?

(我现在也在 avp.stackexchange 上发布了这个问题;也许这是一个更好的地方来询问这个问题,但不确定。)

最佳答案

该实现是将单声道信号“平移”到立体声场的一种正确实现。如果平移,而不是一直向左或一直向右,您希望信号强度与在中间平移时相同,因此向左平移将是:

//left panning
leftSample = sourceSample;
rightSample = 0;
//right panning
leftSample = 0;
rightSample = sourceSample;
//center panning (same power as hard left/right conversion/)
leftSample = sourceSample * sqrt(2)/2;
rightSample = sourceSample * sqrt(2)/2;

但是,如果您从单声道转换为立体声,您的直觉是正确的。没有理由降低电平,因为您不会将居中信号与平移信号进行比较。最好的方法是将信号保持在最大强度:

//mono to stereo conversion
leftSample = sourceSample;
rightSample = sourceSample;

他们也有可能留下一些 s/r 转换后增益变化,但级别似乎是任意的。

关于audio - 如何进行单声道到立体声的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12712815/

相关文章:

matlab - 在Matlab中从声音文件读取数据

ios - 在 Parse.com 上处理音频

python - 每小时对有间隙的时间序列数据重新采样

c# - 从音频文件C#中提取信息

audio - ffmpeg 音频转换 : encoder pcm_u8 working pcm_s8 not

Python Pandas 时间序列操作

python - 用python重采样和合并数据框

c++ - 在 Sound 实际完成之前触发 OnSoundFinished

java - 如何使用 SoundPool 播放随机声音?

android - 如何将 .pcm 文件转换为 .wav 或 .mp3?