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