此网站上还有其他问题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几乎不允许原始音频通过,但此时肯定没有回声。
基本故障排除事实:
process()
到return sample
的所有号码正是我对此算法所期望的,并且即使在此课程之外也是如此。问题似乎来自简单地将签名的短路加在一起,并且产生的波形是绝对的灾难。我已经看到这个特定的方法在各个地方实现 - C#,C ++,甚至在微控制器上 - 所以为什么它在这里如此难以实现?
编辑:我觉得这完全是错的。我不知道它是FFmpeg / avconv,还是其他一些因素,但我不在这里处理正常的PCM信号。通过绘制波形图,以及音调发生器的失败尝试和结果分析,我确定这是差分脉冲编码调制的某种版本;音高由变化从一个样本到下一个样本确定,并且在纯正弦波上将预期的“音量”乘数减半实际上会降低音高并使音量保持相同。 (与非正弦序列上的音量乘数混淆会产生与此回声算法相同的静态。)由于此算法和其他DSP算法旨在用于线性脉冲编码调制,我要去需要一些方法来获得正确的音频流。
答案 0 :(得分:0)
除非你有明显的剪辑,否则它肯定会起作用。
例如,this is a text file有两列。最左边的列是16位输入。第二列是第一列和延迟4001个样本的版本之和。采样率为22KHz。
第二列中的每个样本是求和x [k]和x [k-4001]的结果(例如y [5000] = x [5000] + x [999] = -13840 + 9181 = -4659)在第二列中播放样本时,您可以清楚地听到回声信号。
使用您的代码尝试此信号,看看您是否得到相同的结果。