2016-06-12 74 views
0

我有以下類生成包含聲音數據的緩衝區:爲什麼這種以編程方式生成音樂和絃不正確?

package musicbox.example; 

import javax.sound.sampled.LineUnavailableException; 

import musicbox.engine.SoundPlayer; 

public class CChordTest { 

    private static final int SAMPLE_RATE = 1024 * 64; 
    private static final double PI2 = 2 * Math.PI; 

    /* 
    * Note frequencies in Hz. 
    */ 
    private static final double C4 = 261.626; 
    private static final double E4 = 329.628; 
    private static final double G4 = 391.995; 

    /** 
    * Returns buffer containing audio information representing the C chord 
    * played for the specified duration. 
    * 
    * @param duration The duration in milliseconds. 
    * @return Array of bytes representing the audio information. 
    */ 
    private static byte[] generateSoundBuffer(int duration) { 

     double durationInSeconds = duration/1000.0; 
     int samples = (int) durationInSeconds * SAMPLE_RATE; 

     byte[] out = new byte[samples]; 

     for (int i = 0; i < samples; i++) { 
      double value = 0.0; 
      double t = (i * durationInSeconds)/samples; 
      value += Math.sin(t * C4 * PI2); // C note 
      value += Math.sin(t * E4 * PI2); // E note 
      value += Math.sin(t * G4 * PI2); // G note 
      out[i] = (byte) (value * Byte.MAX_VALUE); 
     } 

     return out; 
    } 

    public static void main(String... args) throws LineUnavailableException { 
     SoundPlayer player = new SoundPlayer(SAMPLE_RATE); 
     player.play(generateSoundBuffer(1000)); 
    } 

} 

也許我誤解一些物理或數學這裏,但似乎每個正弦波應該代表每個音符的聲音(C, E和G),並且通過總結三個正弦曲線,我會聽到類似於當我在鍵盤上同時彈奏這三個音符的情況。然而,我所聽到的甚至不是那麼接近。

對於什麼是值得的,如果我註釋掉任何兩個正弦曲線並保持第三個,我確實會聽到對應於該正弦曲線的(正確)音符。

有人可以發現我做錯了什麼嗎?

+2

我很確定你需要平均信號,而不是他們。嘗試除以3. – Amit

+0

賓果!平均信號做了訣竅。如果你把它寫成答案,我會把它標記爲正確的。 – Deomachus

回答

1

要合併音頻信號,您需要平均他們的樣本,而不是他們。

在轉換爲字節之前將值除以3。

相關問題