Sunday, May 22, 2011

Basic Tone Class and Instantiation

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: