2014-11-16 62 views
7

我想創建使用Java,將能夠產生所有在這篇文章中所定義的顏色的有色噪聲發生器:http://en.wikipedia.org/wiki/Colors_of_noise產生噪音的顏色在Java中

  1. 用最簡單的一個開始,白噪聲,我將如何產生噪音,以便它可以無限期地發揮作用?
  2. 從那裏,我將如何修改我的發電機生成任何顏色?

我對如何生成噪聲本身感到困惑,並且對如何產生噪聲感到困惑,我可以通過揚聲器輸出它。

任何鏈接或提示將非常感激!

我還看了另外一個問題:Java generating sound

但我不完全瞭解什麼是在評論一個給定的代碼怎麼回事。它也不會告訴我該代碼會產生什麼噪音,所以我不知道如何修改它以便產生白噪聲。

+0

您鏈接的問題涉及生成「嗶嗶聲」並播放它們。 「嘟嘟」只是你的簡單週期波,其頻率與你所演奏的波的頻率成正比(在這個例子中,正弦波)。 –

回答

1

我實際上目前正在研究一個白噪聲和採樣產生隨機數的項目。你需要的是相反的!

聲音是壓力與時間。基本上從0壓力開始,並從 - (最大振幅)到(最大振幅)增加一個隨機數量的壓力。白噪聲的幅度是隨機的並且是正態分佈的,因此您可以使用Random.nextGaussian()來生成隨機z分數。將z分數乘以標準偏差(您可能需要做一些測試以找到您喜歡的幅度的標準偏差),然後將其作爲音頻文件中每個樣本的幅度。

至於生成聲音文件本身,如果你還沒有,你應該看看Java Sound API。它爲創建聲音文件和播放提供了許多不錯的方法。

您的問題的下一部分,非白色噪音,恐怕我不確定波形是什麼樣子。它可能遵循類似的生成隨機z分數,並將它們乘以某個幅度標準偏差(或者更可能由某個隨時間變化的幅度函數)。

+2

生成其他有色噪聲的常用方法是過濾白噪聲。例如,粉紅噪聲可以通過對白噪聲施加3dB /倍頻程低通濾波器,褐噪聲爲6dB /倍頻程低通,藍噪聲爲3dB /八度高通,紫色爲6dB /倍頻程高通,最後灰噪聲使用倒置A加權過濾器。 – jaket

3

這是一個在純Java中產生白噪聲的程序。它可以很容易地改變,以產生其他顏色的噪音。

import javax.sound.sampled.*; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.nio.ByteBuffer; 
import java.util.Random; 

public class WhiteNoise extends JFrame { 

    private GeneratorThread generatorThread; 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        WhiteNoise frame = new WhiteNoise(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public WhiteNoise() { 
     addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent e) { 
       generatorThread.exit(); 
       System.exit(0); 
      } 
     }); 

     setTitle("White Noise Generator"); 
     setResizable(false); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 200, 50); 
     setLocationRelativeTo(null); 
     getContentPane().setLayout(new BorderLayout(0, 0)); 
     generatorThread = new GeneratorThread(); 
     generatorThread.start(); 
    } 

    class GeneratorThread extends Thread { 

     final static public int SAMPLE_SIZE = 2; 
     final static public int PACKET_SIZE = 5000; 

     SourceDataLine line; 
     public boolean exitExecution = false; 

     public void run() { 

      try { 
       AudioFormat format = new AudioFormat(44100, 16, 1, true, true); 
       DataLine.Info info = new DataLine.Info(SourceDataLine.class, format, PACKET_SIZE * 2); 

       if (!AudioSystem.isLineSupported(info)) { 
        throw new LineUnavailableException(); 
       } 

       line = (SourceDataLine)AudioSystem.getLine(info); 
       line.open(format); 
       line.start(); 
      } catch (LineUnavailableException e) { 
       e.printStackTrace(); 
       System.exit(-1); 
      } 

      ByteBuffer buffer = ByteBuffer.allocate(PACKET_SIZE); 

      Random random = new Random(); 
      while (exitExecution == false) { 
       buffer.clear(); 
       for (int i=0; i < PACKET_SIZE /SAMPLE_SIZE; i++) { 
        buffer.putShort((short) (random.nextGaussian() * Short.MAX_VALUE)); 
       } 
       line.write(buffer.array(), 0, buffer.position()); 
      } 

      line.drain(); 
      line.close(); 
     } 

     public void exit() { 
      exitExecution =true; 
     } 
    } 
} 
+0

您能否提供一些意見來解釋您的代碼的功能,例如,爲什麼數據包大小爲5000,爲什麼要將它乘以2?我相信「教一個人釣魚」的哲學,這感覺就像「給男人一條魚」。 – jamie