Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating colors of noise in Java

I would like to create a colored noise generator using Java that will be able to generate all of the colors defined in this article: http://en.wikipedia.org/wiki/Colors_of_noise

  1. Starting with the simplest one, White Noise, how would I generate the noise so that it can play indefinitely?
  2. From there, how would I modify my generator to generate any of the colors?

I am both confused about how to generate the noise itself, and confused about how once generated I can have it be output through the speakers.

Any links or tips would be very appreciated!

I've also looked at another question: Java generating sound

But I don't fully understand what is going on in the code given in one of the comments. It also doesn't tell me what noise would be generated with that code, and so I wouldn't know how to modify it so that it would generate white noise.

like image 746
Doronz Avatar asked Nov 16 '14 23:11

Doronz


2 Answers

Here is a program to generate white noise in pure Java. It can be easily changed to generate other colors of noise.

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;
        }
    }
}
like image 125
izilotti Avatar answered Oct 16 '22 21:10

izilotti


I'm actually currently working on a project for taking white noise and sampling it to produce random numbers. What you need is the reverse!

Sound is pressure vs time. Basically start with 0 pressure and add a random amount of pressure from -(max amplitude) to (max amplitude). The amplitude of white noise is random and normally distributed so you can use Random.nextGaussian() to generate random z-scores. Multiply the z-scores by the standard deviation (you may have to do some testing to find a standard deviation in the amplitude you like) and then let that be the amplitude for each sample in the audio file.

As far as generating the sound file itself, if you haven't already, you should look into Java Sound API. It features a lot of nice methods for both creating sound files as well as playback.

The next part of your question, the non-white noise, I'm afraid I'm not sure on what the waveforms look like. It probably follows the similar generate random z-scores and multiply them by some amplitude standard deviation (or more likely by some amplitude function that changes with time).

like image 22
Michael Goldstein Avatar answered Oct 16 '22 22:10

Michael Goldstein