2013-05-08 77 views
4

本網站上還有其他一些問題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算法可用於線性脈衝編碼調製,因此我需要一些方法首先獲得適當的音頻流。

+0

你說:「這個問題似乎是由於簡單地將有符號的短褲加在一起而產生的,所產生的波形是絕對的災難。」但你也會說「從process()調用返回樣本的所有數字正是我期望從這個算法中得到的,甚至在這個類之外也是如此。」這是什麼,你有沒有得到正確的結果?也許你可以從衝動中發佈輸出。 – 2013-05-08 15:54:29

+0

@Bjorn呃,說我有一個'-3672'的樣本。而在10毫秒前,它是'1912',它被'0.1'乘以'191'。返回的值將是'-3481'。 *數字*,它完全符合我的期望。但聽到聲音,並通過分析儀從字面上看波形,顯然「正確」的數字不會產生「正確」的聲音。 Ergo,簡單的補償顯然不起作用。 – DigitalMan 2013-05-10 03:36:19

回答

0

它肯定應該工作除非你有重大的剪輯。例如,this is a text file具有兩列。最左邊的列是16位輸入。第二列是第一個和延遲4001個樣本的版本的總和。採樣率是22KHz。第二列中的每個樣本是x [k]和x [k-4001](例如,y [5000] = x [5000] + x [999] = - 13840 + 9181 = -4659 )播放第二列中的樣本時,您可以清楚地聽到回聲信號。

用你的代碼嘗試這個信號,看看你是否得到相同的結果。