I'm in the process of relearning Java sound generation, and hope to write programs that output interesting soundscapes. This blog posting has very rudimentary code, and hope to continue enhancing it. I will post links here to the bigger and better code samples after they are written.
import javax.sound.sampled.*; import java.util.Random; /** * */ public class Tone { private int seconds = 1 ; private int sampleRate = 8000; private double frequency = 1000.0; private double rad = 0.5 * Math.PI; private double volume = 128.0; public Tone(int mySeconds, int mySampleRate, double myFrequency, double myRad, double myVolume ) { seconds = mySeconds; sampleRate = mySampleRate; frequency = myFrequency; rad = myRad; volume = myVolume; } public void setSeconds(int newValue) { seconds =newValue; } public int getSeconds() { return seconds; } public void setSampleRate(int newValue) { sampleRate = newValue; } public int getSampleRate() { return sampleRate; } public void setFrequency(double newValue) { frequency = newValue; } public double getFrequency() { return frequency; } public void setRad(double newValueA, double newValueB ) { rad = newValueA * newValueB; // e.g. 0.5 * Math.PI } public double getRad() { return rad; } public void setVolume(double newValue) { volume = newValue; } public double getVolume() { return volume; } public void playTone() { try { AudioFormat af = new AudioFormat( (float)sampleRate, 8, 1, true, true ); DataLine.Info info = new DataLine.Info ( SourceDataLine.class, af ); SourceDataLine source = (SourceDataLine) AudioSystem.getLine( info ); source.open( af ); source.start(); byte[] buf = new byte[sampleRate * seconds]; for ( int i=0; i<buf.length; i++ ) { buf[i] = (byte)( Math.sin( rad * frequency / sampleRate * i ) * volume ); } source.write( buf, 0, buf.length ); source.drain(); source.stop(); source.close(); } catch ( Exception e ) { System.out.println( e ); } } }
import javax.sound.sampled.*; public class TestTone { public static void main (String[] args) { double myRad = 0.5 * Math.PI; Tone lineOne = new Tone(1, 8000, 1000.0, myRad, 128.0 ); lineOne.playTone(); } }Below is a little more interesting than a single second tone:
import javax.sound.sampled.*; import java.util.Random; public class TestTone { public static void main (String[] args) { Random generator = new Random(); double myRad = 0.2 * Math.PI; double volume = 128.0; for (int i=0;i<10;i++) { if (i % 2 == 0) {volume=volume+16; myRad=myRad + 0.2;} else {volume = volume-8; myRad= myRad + Math.PI;} Tone lineOne = new Tone(generator.nextInt(2), 8000, 200.0, myRad, volume ); if (i % 3 == 0) {volume=volume-16; myRad=myRad - 0.2;} else {volume = volume+16; myRad= myRad * Math.PI;} Tone lineTwo = new Tone(generator.nextInt(2), 8000, 500.0, myRad, volume ); lineOne.playTone(); lineTwo.playTone(); } } }
The coding is awful in the source code below, but the sound output is way cool. I'm posting it so I don't lose it.
import javax.sound.sampled.*; import java.util.Random; /** * Generate a tone mathematically. * * @author this.is.lance.miller@gmail.com */ public class WildTone { /** * Generate a tone * * @param args not used */ Random generator = new Random(); public static void main ( String[] args ) { Random generator = new Random(); int seconds = 1; int sampleRate = 8000; double frequency = 4000.0; double frequencyb = 2000.0; double frequencyc = 500.0; double RAD = 0.1* Math.PI/1; double RADb = 0.1* Math.PI/1; // double RAD = generator.nextDouble()*Math.PI/generator.nextInt(8); int volume = 256; // generator.nextInt(512); int looplimit = 90; int extraInt = 1; int bufInt = 1; double extraDbl = 0.1; int loopValley = generator.nextInt(sampleRate); try { AudioFormat af = new AudioFormat( (float)sampleRate, 8, 1, true, true ); DataLine.Info info = new DataLine.Info ( SourceDataLine.class, af ); SourceDataLine source = (SourceDataLine) AudioSystem.getLine( info ); source.open( af ); source.start(); byte[] buf = new byte[sampleRate * seconds]; byte[] bufb = new byte[(sampleRate * seconds)]; for (int j=1;j<looplimit;j++) { for ( int i=0; i<buf.length; i++ ) { RAD= extraDbl*Math.PI/extraInt; RADb= (0.1*Math.PI/extraInt)*.2; loopValley = generator.nextInt(5); loopValley=loopValley+1000; if (i > loopValley) { if (i < loopValley+500) { if (i > loopValley+600) { if (i < loopValley+620) { RAD= generator.nextDouble()*Math.PI/2; } else {extraDbl=0.1;} } else {extraDbl=0.4;} } else { if (extraDbl > 0.3) {extraDbl = 0.1; frequency=4000.0;} else { extraDbl=extraDbl+0.1; frequency=500.0; } } } if (i % 2 == 0 || i % 3 == 1 ) {volume=0;} else { if (i < sampleRate*seconds/2 ) { volume=256;} else {volume=512; frequency=frequencyb;} } buf[i] = (byte)( Math.sin( RAD * frequency / sampleRate * i ) * volume ); if (i % 2 == 0) { bufb[i] = (byte)( Math.sin( RADb * (frequencyb) / sampleRate * i ) * (volume-256) ); } else { bufb[i] = (byte)( Math.sin( RADb * (frequencyc) / sampleRate * i ) * (volume-256) ); } } bufInt=generator.nextInt(2); if (bufInt > 0 ) { source.write( bufb, 0, bufb.length/bufInt );} else { source.write( buf, 0, buf.length ); if (bufInt == 2) { source.write( bufb, 0, bufb.length/3 );}} } // end for j source.drain(); source.stop(); source.close(); } catch ( Exception e ) { System.out.println( e ); } System.exit( 0 ); } }
No comments:
Post a Comment