Java 回声/延迟算法只会导致噪音/静电?
该网站上还有其他问题,建议您只需添加一个音频样本和一个存储的过去音频样本,即可产生回声或延迟效果。因此,我有以下Java类:Java 回声/延迟算法只会导致噪音/静电?,java,audio,signal-processing,Java,Audio,Signal Processing,该网站上还有其他问题,建议您只需添加一个音频样本和一个存储的过去音频样本,即可产生回声或延迟效果。因此,我有以下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; priva
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));
}
}
public类DelayAMod扩展AudioMod{
专用int延迟=500;
专用浮子衰减=0.1f;
私有布尔反馈=假;
私人样品;
私人短期[]样本;
私有指针;
@凌驾
公共void init(){
this.setDelay(this.delay);
this.samples=新短[44100];
这个.rrPointer=0;
}
公共无效设置衰减(最终浮点衰减){
this.decage=Math.max(0.0f,Math.min(decage,0.99f));
}
公共无效设置延迟(最终整数延迟){
this.delay=msDelay;
this.delaySamples=44100/(1000/此延迟);
System.out.println(“延迟样本:+this.delaySamples”);
}
@凌驾
公共短流程(短样本){
System.out.println(“Got:+样本”);
如果(这是反馈){
//延迟应反馈到循环中:
sample=(this.samples[this.rrPointer]=this.apply(sample));
}否则{
//无反馈-存储基本数据,然后添加回显:
this.samples[this.rrPointer]=sample;
样本=此。应用(样本);
}
++这个.rr指针;
if(this.rrPointer>=this.samples.length){
这个.rrPointer=0;
}
System.out.println(“返回:+样本”);
返回样品;
}
私人短申请(短样本){
int loc=this.rrPointer-this.delaySamples;
如果(loc<0){
loc+=此.samples.length;
}
System.out.println(“发现:“+this.samples[loc]+”位于“+loc”);
System.out.println(“添加:”+(this.samples[loc]*this.decation));
返回(short)Math.max(short.MIN_值,Math.MIN(sample+(int)(this.samples[loc]*this.decation),(int)short.max_值);
}
}
它从输入流一次接受一个16位的样本,找到一个较早的样本,并相应地将它们相加。然而,输出只是可怕的噪声静态,特别是当衰减提高到实际会导致任何可感知结果的水平时。将衰减降低到0.01几乎不允许原始音频通过,但在这一点上肯定没有回声
基本故障排除事实:
- 如果跳过此处理,音频流听起来很好
- 如果衰减为0(无需添加),音频流听起来很好
- 存储的样本确实以正确的顺序和正确的位置存储和访问
- 存储的样本正在衰减并正确添加到输入样本中
- 从调用
到process()
的所有数字正是我从这个算法中所期望的,即使在这个类之外也是如此return sample
用你的代码试试这个信号,看看是否得到相同的结果。你说“这个问题似乎是因为简单地把有符号的短路加在一起而产生的,结果是一个绝对的灾难。”但你也说“来自进程调用()的所有数字”返回样本正是我从这个算法中所期望的,即使在这个类之外也是如此?也许你可以发布脉冲的输出。@Bjorn好吧,假设我有一个
-3672
的样本。10毫秒前,它是1912
,乘以0.1
就是191
。返回的值将是-3481
。从数字上看,它完全符合我的预期。但是听到声音,通过分析仪观察波形,很明显“正确”的数字并没有产生“正确”的声音。因此,简单的补偿加法显然是行不通的。