Permalink
Browse files

Working with the java sound api

  • Loading branch information...
0 parents commit 9455ef0b002b0baa1509bd6c5d148064f75759e7 @zk committed Jan 14, 2009
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="lib" path="lib/minim.jar"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>dbssim</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,5 @@
+#Tue Jan 13 23:25:56 MST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.source=1.3
@@ -0,0 +1,8 @@
+#Tue Jan 13 23:25:56 MST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+version=1
Binary file not shown.
18 pom.xml
@@ -0,0 +1,18 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>napplelabs</groupId>
+ <artifactId>dbssim</artifactId>
+ <packaging>jar</packaging>
+ <version>0.1-SNAPSHOT</version>
+ <name>dbssim</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
@@ -0,0 +1 @@
+package napplelabs.dbssim;/*File AudioCapture01.java This program demonstrates the capture and subsequent playback of audio data. A GUI appears on the screen containing the following buttons: Capture Stop Playback Input data from a microphone is captured and saved in a ByteArrayOutputStream object when the user clicks the Capture button. Data capture stops when the user clicks the Stop button. Playback begins when the user clicks the Playback button. Tested using SDK 1.4.0 under Win2000 **************************************/import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.io.*;import javax.sound.sampled.*;public class AudioCapture01 extends JFrame { boolean stopCapture = false; ByteArrayOutputStream byteArrayOutputStream; AudioFormat audioFormat; TargetDataLine targetDataLine; AudioInputStream audioInputStream; SourceDataLine sourceDataLine; public static void main(String args[]) { new AudioCapture01(); }// end main public AudioCapture01() {// constructor final JButton captureBtn = new JButton("Capture"); final JButton stopBtn = new JButton("Stop"); final JButton playBtn = new JButton("Playback"); captureBtn.setEnabled(true); stopBtn.setEnabled(false); playBtn.setEnabled(false); // Register anonymous listeners captureBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { captureBtn.setEnabled(false); stopBtn.setEnabled(true); playBtn.setEnabled(false); // Capture input data from the // microphone until the Stop // button is clicked. captureAudio(); }// end actionPerformed }// end ActionListener );// end addActionListener() getContentPane().add(captureBtn); stopBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { captureBtn.setEnabled(true); stopBtn.setEnabled(false); playBtn.setEnabled(true); // Terminate the capturing of // input data from the // microphone. stopCapture = true; }// end actionPerformed }// end ActionListener );// end addActionListener() getContentPane().add(stopBtn); playBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Play back all of the data // that was saved during // capture. playAudio(); }// end actionPerformed }// end ActionListener );// end addActionListener() getContentPane().add(playBtn); getContentPane().setLayout(new FlowLayout()); setTitle("Capture/Playback Demo"); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(250, 70); setVisible(true); }// end constructor // This method captures audio input // from a microphone and saves it in // a ByteArrayOutputStream object. private void captureAudio() { try { // Get everything set up for // capture audioFormat = getAudioFormat(); DataLine.Info dataLineInfo = new DataLine.Info( TargetDataLine.class, audioFormat); targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo); targetDataLine.open(audioFormat); targetDataLine.start(); // Create a thread to capture the // microphone data and start it // running. It will run until // the Stop button is clicked. Thread captureThread = new Thread(new CaptureThread()); captureThread.start(); } catch (Exception e) { System.out.println(e); System.exit(0); }// end catch }// end captureAudio method // This method plays back the audio // data that has been saved in the // ByteArrayOutputStream private void playAudio() { try { // Get everything set up for // playback. // Get the previously-saved data // into a byte array object. byte audioData[] = byteArrayOutputStream.toByteArray(); // Get an input stream on the // byte array containing the data InputStream byteArrayInputStream = new ByteArrayInputStream( audioData); AudioFormat audioFormat = getAudioFormat(); audioInputStream = new AudioInputStream(byteArrayInputStream, audioFormat, audioData.length / audioFormat.getFrameSize()); DataLine.Info dataLineInfo = new DataLine.Info( SourceDataLine.class, audioFormat); sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); sourceDataLine.open(audioFormat); sourceDataLine.start(); // Create a thread to play back // the data and start it // running. It will run until // all the data has been played // back. Thread playThread = new Thread(new PlayThread()); playThread.start(); } catch (Exception e) { System.out.println(e); System.exit(0); }// end catch }// end playAudio // This method creates and returns an // AudioFormat object for a given set // of format parameters. If these // parameters don't work well for // you, try some of the other // allowable parameter values, which // are shown in comments following // the declarations. private AudioFormat getAudioFormat() { float sampleRate = 8000.0F; // 8000,11025,16000,22050,44100 int sampleSizeInBits = 16; // 8,16 int channels = 1; // 1,2 boolean signed = true; // true,false boolean bigEndian = false; // true,false return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); }// end getAudioFormat // ===================================// // Inner class to capture data from // microphone class CaptureThread extends Thread { // An arbitrary-size temporary holding // buffer byte tempBuffer[] = new byte[10000]; public void run() { byteArrayOutputStream = new ByteArrayOutputStream(); stopCapture = false; try {// Loop until stopCapture is set // by another thread that // services the Stop button. while (!stopCapture) { // Read data from the internal // buffer of the data line. int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length); if (cnt > 0) { // Save data in output stream // object. byteArrayOutputStream.write(tempBuffer, 0, cnt); }// end if }// end while byteArrayOutputStream.close(); } catch (Exception e) { System.out.println(e); System.exit(0); }// end catch }// end run }// end inner class CaptureThread // ===================================// // Inner class to play back the data // that was saved. class PlayThread extends Thread { byte tempBuffer[] = new byte[10000]; public void run() { try { int cnt; // Keep looping until the input // read method returns -1 for // empty stream. while ((cnt = audioInputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) { if (cnt > 0) { // Write data to the internal // buffer of the data line // where it will be delivered // to the speaker. sourceDataLine.write(tempBuffer, 0, cnt); }// end if }// end while // Block and wait for internal // buffer of the data line to // empty. sourceDataLine.drain(); sourceDataLine.close(); } catch (Exception e) { System.out.println(e); System.exit(0); }// end catch }// end run }// end inner class PlayThread // ===================================//}// end outer class AudioCapture01.java
@@ -0,0 +1,44 @@
+package napplelabs.dbssim;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+import javax.sound.sampled.TargetDataLine;
+import javax.sound.sampled.DataLine.Info;
+
+public class NeuronPlayer {
+
+ public NeuronPlayer() throws LineUnavailableException {
+ Info info = new Info(SourceDataLine.class, new AudioFormat(22050f, 8, 1, true, false));
+ SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
+
+ System.out.println("Supported: " + AudioSystem.isLineSupported(info));
+
+ int buff_size = 22100;
+
+ PinkNoise noise = new PinkNoise(1, 5);
+
+
+ line.open();
+ line.start();
+
+ byte[] buffer = new byte[buff_size];
+ for(int i=0; i < buff_size; i++) {
+ buffer[i] = (byte) ((noise.nextValue() * 255) - 127);
+ }
+
+ line.write(buffer, 0, buff_size);
+
+
+
+ line.drain();
+
+ line.stop();
+ line.close();
+ }
+
+ public static void main(String[] args) throws LineUnavailableException {
+ new NeuronPlayer();
+ }
+}
@@ -0,0 +1 @@
+package napplelabs.dbssim;/* * PinkNoise.java - a pink noise generator * * Copyright (c) 2008, Sampo Niskanen <sampo.niskanen@iki.fi> * All rights reserved. * Source: http://www.iki.fi/sampo.niskanen/PinkNoise/ * * Distrubuted under the BSD license: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * - Neither the name of the copyright owners nor contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */import java.util.Random;/** * A class that provides a source of pink noise with a power spectrum * density (PSD) proportional to 1/f^alpha. "Regular" pink noise has a * PSD proportional to 1/f, i.e. alpha=1. However, many natural * systems may require a different PSD proportionality. The value of * alpha may be from 0 to 2, inclusive. The special case alpha=0 * results in white noise (directly generated random numbers) and * alpha=2 results in brown noise (integrated white noise). * <p> * The values are computed by applying an IIR filter to generated * Gaussian random numbers. The number of poles used in the filter * may be specified. For each number of poles there is a limiting * frequency below which the PSD becomes constant. Values as low as * 1-3 poles produce relatively good results, however these values * will be concentrated near zero. Using a larger number of poles * will allow more low frequency components to be included, leading to * more variation from zero. However, the sequence is stationary, * that is, it will always return to zero even with a large number of * poles. * <p> * The distribution of values is very close to Gaussian with mean * zero, but the variance depends on the number of poles used. The * algorithm can be made faster by changing the method call * <code> rnd.nextGaussian() </code> to * <code> rnd.nextDouble()-0.5 </code> * in the method {@link #nextValue()}. The resulting distribution is * almost Gaussian, but has a relatively larger amount of large * values. * <p> * The IIR filter used by this class is presented by N. Jeremy Kasdin, * Proceedings of the IEEE, Vol. 83, No. 5, May 1995, p. 822. * * @author Sampo Niskanen <sampo.niskanen@iki.fi> */public class PinkNoise { private final int poles; private final double[] multipliers; private final double[] values; private final Random rnd; /** * Generate pink noise with alpha=1.0 using a five-pole IIR. */ public PinkNoise() { this(1.0, 5, new Random()); } /** * Generate a specific pink noise using a five-pole IIR. * * @param alpha the exponent of the pink noise, 1/f^alpha. * @throws IllegalArgumentException if <code>alpha < 0</code> or * <code>alpha > 2</code>. */ public PinkNoise(double alpha) { this(alpha, 5, new Random()); } /** * Generate pink noise specifying alpha and the number of poles. * The larger the number of poles, the lower are the lowest * frequency components that are amplified. * * @param alpha the exponent of the pink noise, 1/f^alpha. * @param poles the number of poles to use. * @throws IllegalArgumentException if <code>alpha < 0</code> or * <code>alpha > 2</code>. */ public PinkNoise(double alpha, int poles) { this(alpha, poles, new Random()); } /** * Generate pink noise from a specific randomness source * specifying alpha and the number of poles. The larger the * number of poles, the lower are the lowest frequency components * that are amplified. * * @param alpha the exponent of the pink noise, 1/f^alpha. * @param poles the number of poles to use. * @param random the randomness source. * @throws IllegalArgumentException if <code>alpha < 0</code> or * <code>alpha > 2</code>. */ public PinkNoise(double alpha, int poles, Random random) { if (alpha < 0 || alpha > 2) { throw new IllegalArgumentException("Invalid pink noise alpha = " + alpha); } this.rnd = random; this.poles = poles; this.multipliers = new double[poles]; this.values = new double[poles]; double a = 1; for (int i=0; i < poles; i++) { a = (i - alpha/2) * a / (i+1); multipliers[i] = a; } // Fill the history with random values for (int i=0; i < 5*poles; i++) this.nextValue(); } /** * Return the next pink noise sample. * * @return the next pink noise sample. */ public double nextValue() { /* * The following may be changed to rnd.nextDouble()-0.5 * if strict Gaussian distribution of resulting values is not * required. */ double x = rnd.nextGaussian(); for (int i=0; i < poles; i++) { x -= multipliers[i] * values[i]; } System.arraycopy(values, 0, values, 1, values.length-1); values[0] = x; return x; } /** * A main method to demonstrate the functionality. The program is * used as: * <pre> * java PinkNoise samples [alpha [poles]] * * samples = number of samples to output * alpha = PSD distribution exponent, 1/f^alpha (default 1.0) * poles = number of IIR poles to use (default 5) * </pre> */ public static void main(String[] arg) { PinkNoise source; int n; double alpha = 1.0; int poles = 5; if (arg.length < 1 || arg.length > 3) { System.out.println("\nUsage:\n" + " java PinkNoise <samples> [<alpha> [<poles>]]\n\n" + " <samples> = number of samples to output\n" + " <alpha> = PSD distribution exponent, 1/f^alpha " + "(default 1.0)\n" + " <poles> = number of IIR poles to use (default 5)\n"); System.exit(1); } // Parse arguments: n = Integer.parseInt(arg[0]); if (arg.length >= 2) { alpha = Double.parseDouble(arg[1]); } if (arg.length >= 3) { poles = Integer.parseInt(arg[2]); } // Generate values: source = new PinkNoise(alpha, poles); for (int i=0; i < n; i++) { System.out.println(source.nextValue()); } }}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 9455ef0

Please sign in to comment.