回声/延迟算法只会导致噪声/静态?

时间:2013-05-08 11:21:00

标签: java audio signal-processing

此网站上还有其他问题and answers建议,要创建回音或延迟效果,您只需添加一个音频样本和过去存储的音频样本。因此,我有以下Java类:

public class DelayAMod extends AudioMod {

private int delay = 500;
private float decay = 0.1f;
private boolean feedback = false;

private int delaySamples;
private short[] samples;
private int rrPointer;

@Override
public void init() {
    this.setDelay(this.delay);
    this.samples = new short[44100];
    this.rrPointer = 0;
}

public void setDecay(final float decay) {
    this.decay = Math.max(0.0f, Math.min(decay, 0.99f));
}

public void setDelay(final int msDelay) {
    this.delay = msDelay;
    this.delaySamples = 44100 / (1000/this.delay);
    System.out.println("Delay samples:"+this.delaySamples);
}

@Override
public short process(short sample) {
    System.out.println("Got:"+sample);
    if (this.feedback) {
        //Delay should feed back into the loop:
        sample = (this.samples[this.rrPointer] = this.apply(sample));
    } else {
        //No feedback - store base data, then add echo:
        this.samples[this.rrPointer] = sample;
        sample = this.apply(sample);
    }
    ++this.rrPointer;
    if (this.rrPointer >= this.samples.length) {
        this.rrPointer = 0;
    }
    System.out.println("Returning:"+sample);
    return sample;
}

private short apply(short sample) {
    int loc = this.rrPointer - this.delaySamples;
    if (loc < 0) {
        loc += this.samples.length;
    }
    System.out.println("Found:"+this.samples[loc]+" at "+loc);
    System.out.println("Adding:"+(this.samples[loc] * this.decay));
    return (short)Math.max(Short.MIN_VALUE, Math.min(sample + (int)(this.samples[loc] * this.decay), (int)Short.MAX_VALUE));
}
}

它一次从输入流接受一个16位样本,找到较早的样本,并相应地将它们相加。然而,输出只是可怕的嘈杂静电,特别是当衰减升高到实际会导致任何明显结果的水平时。将衰减减少到0.01几乎不允许原始音频通过,但此时肯定没有回声。

基本故障排除事实:

  • 如果跳过此处理,音频流听起来会很好。
  • 如果衰减为0(无需添加任何内容),音频流听起来不错。
  • 确实存储并以正确的顺序和正确的位置访问存储的样本。
  • 存储的样本正在衰减并正确添加到输入样本中。
  • process()return sample的所有号码正是我对此算法所期望的,并且即使在此课程之外也是如此。

问题似乎来自简单地将签名的短路加在一起,并且产生的波形是绝对的灾难。我已经看到这个特定的方法在各个地方实现 - C#,C ++,甚至在微控制器上 - 所以为什么它在这里如此难以实现?

编辑:我觉得这完全是错的。我不知道它是FFmpeg / avconv,还是其他一些因素,但我在这里处理正常的PCM信号。通过绘制波形图,以及音调发生器的失败尝试和结果分析,我确定这是差分脉冲编码调制的某种版本;音高由变化从一个样本到下一个样本确定,并且在纯正弦波上将预期的“音量”乘数减半实际上会降低音高并使音量保持相同。 (与非正弦序列上的音量乘数混淆会产生与此回声算法相同的静态。)由于此算法和其他DSP算法旨在用于线性脉冲编码调制,我要去需要一些方法来获得正确的音频流。

1 个答案:

答案 0 :(得分:0)

除非你有明显的剪辑,否则它肯定会起作用。

例如,this is a text file有两列。最左边的列是16位输入。第二列是第一列和延迟4001个样本的版本之和。采样率为22KHz。

第二列中的每个样本是求和x [k]和x [k-4001]的结果(例如y [5000] = x [5000] + x [999] = -13840 + 9181 = -4659)在第二列中播放样本时,您可以清楚地听到回声信号。

使用您的代码尝试此信号,看看您是否得到相同的结果。