yoga1290

WAWA+Tone JMF Testing!

Jul 21st, 2011
760
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 33.38 KB | None | 0 0
  1. /*
  2.  * To change this template, choose Tools | Templates
  3.  * and open the template in the editor.
  4.  */
  5. package jacka;
  6.  
  7. /**
  8.  *
  9.  * @author yoga1290
  10.  */
  11. import javax.swing.*;
  12. import java.awt.*;
  13. import java.awt.event.*;
  14. import javax.sound.sampled.*;
  15. import java.io.*;
  16. import java.nio.channels.*;
  17. import java.nio.*;
  18. import java.util.*;
  19.  
  20. //listed 4rm http://www.developer.com/java/other/article.php/2226701/Java-Sound-Creating-Playing-and-Saving-Synthetic-Sounds.htm
  21. class AudioSynth01 extends JFrame{
  22.  
  23.   //The following are general instance variables
  24.   // used to create a SourceDataLine object.
  25.   AudioFormat audioFormat;
  26.   AudioInputStream audioInputStream;
  27.   SourceDataLine sourceDataLine;
  28.  
  29.   //The following are audio format parameters.
  30.   // They may be modified by the signal generator
  31.   // at runtime.  Values allowed by Java
  32.   // SDK 1.4.1 are shown in comments.
  33.   float sampleRate = 16000.0F;
  34.   //Allowable 8000,11025,16000,22050,44100
  35.   int sampleSizeInBits = 16;
  36.   //Allowable 8,16
  37.   int channels = 1;
  38.   //Allowable 1,2
  39.   boolean signed = true;
  40.   //Allowable true,false
  41.   boolean bigEndian = true;
  42.   //Allowable true,false
  43.  
  44.   //A buffer to hold two seconds monaural and one
  45.   // second stereo data at 16000 samp/sec for
  46.   // 16-bit samples
  47.   byte audioData[] = new byte[16000*4];
  48.  
  49.   //Following components appear in the North
  50.   // position of the GUI.
  51.   final JButton generateBtn =
  52.                          new JButton("Generate");
  53.   final JButton playOrFileBtn =
  54.                         new JButton("Play/File");
  55.   final JLabel elapsedTimeMeter =
  56.                               new JLabel("0000");
  57.  
  58.   //Following radio buttons select a synthetic
  59.   // data type.  Add more buttons if you add
  60.   // more synthetic data types.  They appear in
  61.   // the center position of the GUI.
  62.   final JRadioButton tones =
  63.                   new JRadioButton("Tones",true);
  64.   final JRadioButton stereoPanning =
  65.               new JRadioButton("Stereo Panning");
  66.   final JRadioButton stereoPingpong =
  67.              new JRadioButton("Stereo Pingpong");
  68.   final JRadioButton fmSweep =
  69.                     new JRadioButton("FM Sweep");
  70.   final JRadioButton decayPulse =
  71.                  new JRadioButton("Decay Pulse");
  72.   final JRadioButton echoPulse =
  73.                  new JRadioButton("Echo Pulse");
  74.   final JRadioButton waWaPulse =
  75.                  new JRadioButton("WaWa Pulse");
  76.  
  77.   //Following components appear in the South
  78.   // position of the GUI.
  79.   final JRadioButton listen =
  80.                  new JRadioButton("Listen",true);
  81.   final JRadioButton file =
  82.                         new JRadioButton("File");
  83.   final JTextField fileName =
  84.                        new JTextField("junk",10);
  85.  
  86.   //-------------------------------------------//
  87.   public static void main(
  88.                         String args[]){
  89.     new AudioSynth01();
  90.   }//end main
  91.   //-------------------------------------------//
  92.  
  93.   public AudioSynth01(){//constructor
  94.     //A panel for the North position.  Note the
  95.     // etched border.
  96.     final JPanel controlButtonPanel =
  97.                                     new JPanel();
  98.     controlButtonPanel.setBorder(
  99.              BorderFactory.createEtchedBorder());
  100.  
  101.     //A panel and button group for the radio
  102.     // buttons in the Center position.
  103.     final JPanel synButtonPanel = new JPanel();
  104.     final ButtonGroup synButtonGroup =
  105.                                new ButtonGroup();
  106.     //This panel is used for cosmetic purposes
  107.     // only, to cause the radio buttons to be
  108.     // centered horizontally in the Center
  109.     // position.
  110.     final JPanel centerPanel = new JPanel();
  111.  
  112.     //A panel for the South position.  Note the
  113.     // etched border.
  114.     final JPanel outputButtonPanel =
  115.                                     new JPanel();
  116.     outputButtonPanel.setBorder(
  117.              BorderFactory.createEtchedBorder());
  118.     final ButtonGroup outputButtonGroup =
  119.                                new ButtonGroup();
  120.  
  121.     //Disable the Play button initially to force
  122.     // the user to generate some data before
  123.     // trying to listen to it or write it to a
  124.     // file.
  125.     playOrFileBtn.setEnabled(false);
  126.  
  127.     //Register anonymous listeners on the
  128.     // Generate button and the Play/File button.
  129.     generateBtn.addActionListener(
  130.       new ActionListener(){
  131.         public void actionPerformed(
  132.                                   ActionEvent e){
  133.           //Don't allow Play during generation
  134.           playOrFileBtn.setEnabled(false);
  135.           //Generate synthetic data
  136.           new SynGen().getSyntheticData(
  137.                                       audioData);
  138.           //Now it is OK for the user to listen
  139.           // to or file the synthetic audio data.
  140.           playOrFileBtn.setEnabled(true);
  141.         }//end actionPerformed
  142.       }//end ActionListener
  143.     );//end addActionListener()
  144.  
  145.     playOrFileBtn.addActionListener(
  146.       new ActionListener(){
  147.         public void actionPerformed(
  148.                                   ActionEvent e){
  149.           //Play or file the data synthetic data
  150.           playOrFileData();
  151.         }//end actionPerformed
  152.       }//end ActionListener
  153.     );//end addActionListener()
  154.  
  155.     //Add two buttons and a text field to a
  156.     // physical group in the North of the GUI.
  157.     controlButtonPanel.add(generateBtn);
  158.     controlButtonPanel.add(playOrFileBtn);
  159.     controlButtonPanel.add(elapsedTimeMeter);
  160.  
  161.     //Add radio buttons to a mutually exclusive
  162.     // group in the Center of the GUI.  Make
  163.     // additions here if you add new synthetic
  164.     // generator methods.
  165.     synButtonGroup.add(tones);
  166.     synButtonGroup.add(stereoPanning);
  167.     synButtonGroup.add(stereoPingpong);
  168.     synButtonGroup.add(fmSweep);
  169.     synButtonGroup.add(decayPulse);
  170.     synButtonGroup.add(echoPulse);
  171.     synButtonGroup.add(waWaPulse);
  172.  
  173.     //Add radio buttons to a physical group and
  174.     // center it in the Center of the GUI. Make
  175.     // additions here if you add new synthetic
  176.     // generator methods.
  177.     synButtonPanel.setLayout(
  178.                             new GridLayout(0,1));
  179.     synButtonPanel.add(tones);
  180.     synButtonPanel.add(stereoPanning);
  181.     synButtonPanel.add(stereoPingpong);
  182.     synButtonPanel.add(fmSweep);
  183.     synButtonPanel.add(decayPulse);
  184.     synButtonPanel.add(echoPulse);
  185.     synButtonPanel.add(waWaPulse);
  186.  
  187.     //Note that the centerPanel has center
  188.     // alignment by default.
  189.     centerPanel.add(synButtonPanel);
  190.  
  191.     //Add radio buttons to a mutually exclusive
  192.     // group in the South of the GUI.
  193.     outputButtonGroup.add(listen);
  194.     outputButtonGroup.add(file);
  195.  
  196.     //Add radio buttons to a physical group in
  197.     // the South of the GUI.
  198.     outputButtonPanel.add(listen);
  199.     outputButtonPanel.add(file);
  200.     outputButtonPanel.add(fileName);
  201.  
  202.     //Add the panels containing components to the
  203.     // content pane of the GUI in the appropriate
  204.     // positions.
  205.     getContentPane().add(
  206.           controlButtonPanel,BorderLayout.NORTH);
  207.     getContentPane().add(centerPanel,
  208.                             BorderLayout.CENTER);
  209.     getContentPane().add(outputButtonPanel,
  210.                              BorderLayout.SOUTH);
  211.  
  212.     //Finish the GUI.  If you add more radio
  213.     // buttons in the center, you may need to
  214.     // modify the call to setSize to increase
  215.     // the vertical component of the GUI size.
  216.     setTitle("Copyright 2003, R.G.Baldwin");
  217.     setDefaultCloseOperation(EXIT_ON_CLOSE);
  218.     setSize(250,275);
  219.     setVisible(true);
  220.   }//end constructor
  221.   //-------------------------------------------//
  222.  
  223.   //This method plays or files the synthetic
  224.   // audio data that has been generated and saved
  225.   // in an array in memory.
  226.   private void playOrFileData() {
  227.     try{
  228.       //Get an input stream on the byte array
  229.       // containing the data
  230.       InputStream byteArrayInputStream =
  231.                         new ByteArrayInputStream(
  232.                                       audioData);
  233.  
  234.       //Get the required audio format
  235.       audioFormat = new AudioFormat(
  236.                                 sampleRate,
  237.                                 sampleSizeInBits,
  238.                                 channels,
  239.                                 signed,
  240.                                 bigEndian);
  241.  
  242.       //Get an audio input stream from the
  243.       // ByteArrayInputStream
  244.       audioInputStream = new AudioInputStream(
  245.                     byteArrayInputStream,
  246.                     audioFormat,
  247.                     audioData.length/audioFormat.
  248.                                  getFrameSize());
  249.  
  250.       //Get info on the required data line
  251.       DataLine.Info dataLineInfo =
  252.                           new DataLine.Info(
  253.                             SourceDataLine.class,
  254.                                     audioFormat);
  255.  
  256.       //Get a SourceDataLine object
  257.       sourceDataLine = (SourceDataLine)
  258.                              AudioSystem.getLine(
  259.                                    dataLineInfo);
  260.       //Decide whether to play the synthetic
  261.       // data immediately, or to write it into
  262.       // an audio file, based on the user
  263.       // selection of the radio buttons in the
  264.       // South of the GUI..
  265.       if(listen.isSelected()){
  266.       //Create a thread to play back the data and
  267.       // start it running.  It will run until all
  268.       // the data has been played back
  269.         new ListenThread().start();
  270.       }else{
  271.         //Disable buttons until existing data
  272.         // is written to the file.
  273.         generateBtn.setEnabled(false);
  274.         playOrFileBtn.setEnabled(false);
  275.  
  276.         //Write the data to an output file with
  277.         // the name provided by the text field
  278.         // in the South of the GUI.
  279.         try{
  280.           AudioSystem.write(
  281.                     audioInputStream,
  282.                     AudioFileFormat.Type.AU,
  283.                     new File(fileName.getText() +
  284.                                          ".au"));
  285.         }catch (Exception e) {
  286.           e.printStackTrace();
  287.           System.exit(0);
  288.         }//end catch
  289.         //Enable buttons for another operation
  290.         generateBtn.setEnabled(true);
  291.         playOrFileBtn.setEnabled(true);
  292.       }//end else
  293.     }catch (Exception e) {
  294.       e.printStackTrace();
  295.       System.exit(0);
  296.     }//end catch
  297.   }//end playOrFileData
  298. //=============================================//
  299.  
  300. //Inner class to play back the data that was
  301. // saved.
  302. class ListenThread extends Thread{
  303.   //This is a working buffer used to transfer
  304.   // the data between the AudioInputStream and
  305.   // the SourceDataLine.  The size is rather
  306.   // arbitrary.
  307.   byte playBuffer[] = new byte[16384];
  308.  
  309.   public void run(){
  310.     try{
  311.       //Disable buttons while data is being
  312.       // played.
  313.       generateBtn.setEnabled(false);
  314.       playOrFileBtn.setEnabled(false);
  315.  
  316.       //Open and start the SourceDataLine
  317.       sourceDataLine.open(audioFormat);
  318.       sourceDataLine.start();
  319.  
  320.       int cnt;
  321.       //Get beginning of elapsed time for
  322.       // playback
  323.       long startTime = new Date().getTime();
  324.  
  325.       //Transfer the audio data to the speakers
  326.       while((cnt = audioInputStream.read(
  327.                               playBuffer, 0,
  328.                               playBuffer.length))
  329.                                           != -1){
  330.         //Keep looping until the input read
  331.         // method returns -1 for empty stream.
  332.         if(cnt > 0){
  333.           //Write data to the internal buffer of
  334.           // the data line where it will be
  335.           // delivered to the speakers in real
  336.           // time
  337.           sourceDataLine.write(
  338.                              playBuffer, 0, cnt);
  339.         }//end if
  340.       }//end while
  341.  
  342.       //Block and wait for internal buffer of the
  343.       // SourceDataLine to become empty.
  344.       sourceDataLine.drain();
  345.  
  346.  
  347.       //Get and display the elapsed time for
  348.       // the previous playback.
  349.       int elapsedTime =
  350.          (int)(new Date().getTime() - startTime);
  351.       elapsedTimeMeter.setText("" + elapsedTime);
  352.  
  353.       //Finish with the SourceDataLine
  354.       sourceDataLine.stop();
  355.       sourceDataLine.close();
  356.  
  357.       //Re-enable buttons for another operation
  358.       generateBtn.setEnabled(true);
  359.       playOrFileBtn.setEnabled(true);
  360.     }catch (Exception e) {
  361.       e.printStackTrace();
  362.       System.exit(0);
  363.     }//end catch
  364.  
  365.   }//end run
  366. }//end inner class ListenThread
  367. //=============================================//
  368.  
  369. //Inner signal generator class.
  370.  
  371. //An object of this class can be used to
  372. // generate a variety of different synthetic
  373. // audio signals.  Each time the getSyntheticData
  374. // method is called on an object of this class,
  375. // the method will fill the incoming array with
  376. // the samples for a synthetic signal.
  377. class SynGen{
  378.   //Note:  Because this class uses a ByteBuffer
  379.   // asShortBuffer to handle the data, it can
  380.   // only be used to generate signed 16-bit
  381.   // data.
  382.   ByteBuffer byteBuffer;
  383.   ShortBuffer shortBuffer;
  384.   int byteLength;
  385.  
  386.   void getSyntheticData(byte[] synDataBuffer){
  387.     //Prepare the ByteBuffer and the shortBuffer
  388.     // for use
  389.     byteBuffer = ByteBuffer.wrap(synDataBuffer);
  390.     shortBuffer = byteBuffer.asShortBuffer();
  391.  
  392.     byteLength = synDataBuffer.length;
  393.  
  394.     //Decide which synthetic data generator
  395.     // method to invoke based on which radio
  396.     // button the user selected in the Center of
  397.     // the GUI.  If you add more methods for
  398.     // other synthetic data types, you need to
  399.     // add corresponding radio buttons to the
  400.     // GUI and add statements here to test the
  401.     // new radio buttons.  Make additions here
  402.     // if you add new synthetic generator
  403.     // methods.
  404.  
  405.     if(tones.isSelected()) tones();
  406.     if(stereoPanning.isSelected())
  407.                                  stereoPanning();
  408.     if(stereoPingpong.isSelected())
  409.                                 stereoPingpong();
  410.     if(fmSweep.isSelected()) fmSweep();
  411.     if(decayPulse.isSelected()) decayPulse();
  412.     if(echoPulse.isSelected()) echoPulse();
  413.     if(waWaPulse.isSelected()) waWaPulse();
  414.  
  415.   }//end getSyntheticData method
  416.   //-------------------------------------------//
  417.  
  418.   //This method generates a monaural tone
  419.   // consisting of the sum of three sinusoids.
  420.   void tones(){
  421.     channels = 1;//Java allows 1 or 2
  422.     //Each channel requires two 8-bit bytes per
  423.     // 16-bit sample.
  424.     int bytesPerSamp = 2;
  425.     sampleRate = 16000.0F;
  426.     // Allowable 8000,11025,16000,22050,44100
  427.     int sampLength = byteLength/bytesPerSamp;
  428.     for(int cnt = 0; cnt < sampLength; cnt++){
  429.       double time = cnt/sampleRate;
  430.       double freq = 950.0;//arbitrary frequency
  431.       double sinValue =
  432.         (Math.sin(2*Math.PI*freq*time) +
  433.         Math.sin(2*Math.PI*(freq/1.8)*time) +
  434.         Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  435.       shortBuffer.put((short)(16000*sinValue));
  436.     }//end for loop
  437.   }//end method tones
  438.   //-------------------------------------------//
  439.  
  440.   //This method generates a stereo speaker sweep,
  441.   // starting with a relatively high frequency
  442.   // tone on the left speaker and moving across
  443.   // to a lower frequency tone on the right
  444.   // speaker.
  445.   void stereoPanning(){
  446.     channels = 2;//Java allows 1 or 2
  447.     int bytesPerSamp = 4;//Based on channels
  448.     sampleRate = 16000.0F;
  449.     // Allowable 8000,11025,16000,22050,44100
  450.     int sampLength = byteLength/bytesPerSamp;
  451.     for(int cnt = 0; cnt < sampLength; cnt++){
  452.       //Calculate time-varying gain for each
  453.       // speaker
  454.       double rightGain = 16000.0*cnt/sampLength;
  455.       double leftGain = 16000.0 - rightGain;
  456.  
  457.       double time = cnt/sampleRate;
  458.       double freq = 600;//An arbitrary frequency
  459.       //Generate data for left speaker
  460.       double sinValue =
  461.                  Math.sin(2*Math.PI*(freq)*time);
  462.       shortBuffer.put(
  463.                      (short)(leftGain*sinValue));
  464.       //Generate data for right speaker
  465.       sinValue =
  466.              Math.sin(2*Math.PI*(freq*0.8)*time);
  467.       shortBuffer.put(
  468.                     (short)(rightGain*sinValue));
  469.     }//end for loop
  470.   }//end method stereoPanning
  471.   //-------------------------------------------//
  472.  
  473.   //This method uses stereo to switch a sound
  474.   // back and forth between the left and right
  475.   // speakers at a rate of about eight switches
  476.   // per second.  On my system, this is a much
  477.   // better demonstration of the sound separation
  478.   // between the two speakers than is the
  479.   // demonstration produced by the stereoPanning
  480.   // method.  Note also that because the sounds
  481.   // are at different frequencies, the sound
  482.   // produced is similar to that of U.S.
  483.   // emergency vehicles.
  484.  
  485.   void stereoPingpong(){
  486.     channels = 2;//Java allows 1 or 2
  487.     int bytesPerSamp = 4;//Based on channels
  488.     sampleRate = 16000.0F;
  489.     // Allowable 8000,11025,16000,22050,44100
  490.     int sampLength = byteLength/bytesPerSamp;
  491.     double leftGain = 0.0;
  492.     double rightGain = 16000.0;
  493.     for(int cnt = 0; cnt < sampLength; cnt++){
  494.       //Calculate time-varying gain for each
  495.       // speaker
  496.       if(cnt % (sampLength/8) == 0){
  497.         //swap gain values
  498.         double temp = leftGain;
  499.         leftGain = rightGain;
  500.         rightGain = temp;
  501.       }//end if
  502.  
  503.       double time = cnt/sampleRate;
  504.       double freq = 600;//An arbitrary frequency
  505.       //Generate data for left speaker
  506.       double sinValue =
  507.                  Math.sin(2*Math.PI*(freq)*time);
  508.       shortBuffer.put(
  509.                      (short)(leftGain*sinValue));
  510.       //Generate data for right speaker
  511.       sinValue =
  512.              Math.sin(2*Math.PI*(freq*0.8)*time);
  513.       shortBuffer.put(
  514.                     (short)(rightGain*sinValue));
  515.     }//end for loop
  516.   }//end stereoPingpong method
  517.   //-------------------------------------------//
  518.  
  519.   //This method generates a monaural linear
  520.   // frequency sweep from 100 Hz to 1000Hz.
  521.   void fmSweep(){
  522.     channels = 1;//Java allows 1 or 2
  523.     int bytesPerSamp = 2;//Based on channels
  524.     sampleRate = 16000.0F;
  525.     // Allowable 8000,11025,16000,22050,44100
  526.     int sampLength = byteLength/bytesPerSamp;
  527.     double lowFreq = 100.0;
  528.     double highFreq = 1000.0;
  529.  
  530.     for(int cnt = 0; cnt < sampLength; cnt++){
  531.       double time = cnt/sampleRate;
  532.  
  533.       double freq = lowFreq +
  534.                cnt*(highFreq-lowFreq)/sampLength;
  535.       double sinValue =
  536.                    Math.sin(2*Math.PI*freq*time);
  537.       shortBuffer.put((short)(16000*sinValue));
  538.     }//end for loop
  539.   }//end method fmSweep
  540.   //-------------------------------------------//
  541.  
  542.   //This method generates a monaural triple-
  543.   // frequency pulse that decays in a linear
  544.   // fashion with time.
  545.   void decayPulse(){
  546.     channels = 1;//Java allows 1 or 2
  547.     int bytesPerSamp = 2;//Based on channels
  548.     sampleRate = 16000.0F;
  549.     // Allowable 8000,11025,16000,22050,44100
  550.     int sampLength = byteLength/bytesPerSamp;
  551.     for(int cnt = 0; cnt < sampLength; cnt++){
  552.       //The value of scale controls the rate of
  553.       // decay - large scale, fast decay.
  554.       double scale = 2*cnt;
  555.       if(scale > sampLength) scale = sampLength;
  556.       double gain =
  557.              16000*(sampLength-scale)/sampLength;
  558.       double time = cnt/sampleRate;
  559.       double freq = 499.0;//an arbitrary freq
  560.       double sinValue =
  561.         (Math.sin(2*Math.PI*freq*time) +
  562.         Math.sin(2*Math.PI*(freq/1.8)*time) +
  563.         Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  564.       shortBuffer.put((short)(gain*sinValue));
  565.     }//end for loop
  566.   }//end method decayPulse
  567.   //-------------------------------------------//
  568.  
  569.   //This method generates a monaural triple-
  570.   // frequency pulse that decays in a linear
  571.   // fashion with time.  However, three echoes
  572.   // can be heard over time with the amplitude
  573.   // of the echoes also decreasing with time.
  574.   void echoPulse(){
  575.     channels = 1;//Java allows 1 or 2
  576.     int bytesPerSamp = 2;//Based on channels
  577.     sampleRate = 16000.0F;
  578.     // Allowable 8000,11025,16000,22050,44100
  579.     int sampLength = byteLength/bytesPerSamp;
  580.     int cnt2 = -8000;
  581.     int cnt3 = -16000;
  582.     int cnt4 = -24000;
  583.     for(int cnt1 = 0; cnt1 < sampLength;
  584.                     cnt1++,cnt2++,cnt3++,cnt4++){
  585.       double val = echoPulseHelper(
  586.                                 cnt1,sampLength);
  587.       if(cnt2 > 0){
  588.         val += 0.7 * echoPulseHelper(
  589.                                 cnt2,sampLength);
  590.       }//end if
  591.       if(cnt3 > 0){
  592.         val += 0.49 * echoPulseHelper(
  593.                                 cnt3,sampLength);
  594.       }//end if
  595.       if(cnt4 > 0){
  596.         val += 0.34 * echoPulseHelper(
  597.                                 cnt4,sampLength);
  598.       }//end if
  599.  
  600.       shortBuffer.put((short)val);
  601.     }//end for loop
  602.   }//end method echoPulse
  603.   //-------------------------------------------//
  604.  
  605.   double echoPulseHelper(int cnt,int sampLength){
  606.     //The value of scale controls the rate of
  607.     // decay - large scale, fast decay.
  608.     double scale = 2*cnt;
  609.     if(scale > sampLength) scale = sampLength;
  610.     double gain =
  611.              16000*(sampLength-scale)/sampLength;
  612.     double time = cnt/sampleRate;
  613.     double freq = 499.0;//an arbitrary freq
  614.     double sinValue =
  615.       (Math.sin(2*Math.PI*freq*time) +
  616.       Math.sin(2*Math.PI*(freq/1.8)*time) +
  617.       Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  618.     return(short)(gain*sinValue);
  619.   }//end echoPulseHelper
  620.  
  621.   //-------------------------------------------//
  622.  
  623.   //This method generates a monaural triple-
  624.   // frequency pulse that decays in a linear
  625.   // fashion with time.  However, three echoes
  626.   // can be heard over time with the amplitude
  627.   // of the echoes also decreasing with time.
  628.   //Note that this method is identical to the
  629.   // method named echoPulse, except that the
  630.   // algebraic sign was switched on the amplitude
  631.   // of two of the echoes before adding them to
  632.   // the composite synthetic signal.  This
  633.   // resulted in a difference in the
  634.   // sound.
  635.   void waWaPulse(){
  636.     channels = 1;//Java allows 1 or 2
  637.     int bytesPerSamp = 2;//Based on channels
  638.     sampleRate = 16000.0F;
  639.     // Allowable 8000,11025,16000,22050,44100
  640.     int sampLength = byteLength/bytesPerSamp;
  641.     int cnt2 = -8000;
  642.     int cnt3 = -16000;
  643.     int cnt4 = -24000;
  644.     for(int cnt1 = 0; cnt1 < sampLength;
  645.                     cnt1++,cnt2++,cnt3++,cnt4++){
  646.       double val = waWaPulseHelper(
  647.                                 cnt1,sampLength);
  648.       if(cnt2 > 0){
  649.         val += -0.7 * waWaPulseHelper(
  650.                                 cnt2,sampLength);
  651.       }//end if
  652.       if(cnt3 > 0){
  653.         val += 0.49 * waWaPulseHelper(
  654.                                 cnt3,sampLength);
  655.       }//end if
  656.       if(cnt4 > 0){
  657.         val += -0.34 * waWaPulseHelper(
  658.                                 cnt4,sampLength);
  659.       }//end if
  660.  
  661.       shortBuffer.put((short)val);
  662.     }//end for loop
  663.   }//end method waWaPulse
  664.   //-------------------------------------------//
  665.  
  666.   double waWaPulseHelper(int cnt,int sampLength){
  667.     //The value of scale controls the rate of
  668.     // decay - large scale, fast decay.
  669.       double scale = 2*cnt;
  670.       if(scale > sampLength) scale = sampLength;
  671.       double gain =
  672.              16000*(sampLength-scale)/sampLength;
  673.     double time = cnt/sampleRate;
  674.     double freq = 499.0;//an arbitrary freq
  675.     double sinValue =
  676.       (Math.sin(2*Math.PI*freq*time) +
  677.       Math.sin(2*Math.PI*(freq/1.8)*time) +
  678.       Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  679.     return(short)(gain*sinValue);
  680.   }//end waWaPulseHelper
  681.  
  682.   //-------------------------------------------//
  683. }//end SynGen class
  684. //=============================================//
  685.  
  686. }//end outer class AudioSynth01.java
  687.  
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704. public class Jacka {
  705.  
  706.     /**
  707.      * @param args the command line arguments
  708.      */
  709.     public static void waWaPulse(){
  710.         //  new AudioSynth01();
  711.         //A buffer to hold two seconds monaural and one
  712.   // second stereo data at 16000 samp/sec for
  713.   // 16-bit samples
  714.   byte audioData[] = new byte[16000*4];
  715.   //The following are audio format parameters.
  716.   // They may be modified by the signal generator
  717.   // at runtime.  Values allowed by Java
  718.   // SDK 1.4.1 are shown in comments.
  719.   //TODO
  720.   float sampleRate =8000.0F;// 16000.0F;
  721.   //Allowable 8000,11025,16000,22050,44100
  722.   int sampleSizeInBits = 16;
  723.   //Allowable 8,16
  724.   int channels = 1;
  725.   //Allowable 1,2
  726.   //Each channel requires two 8-bit bytes per
  727.     // 16-bit sample.
  728.     int bytesPerSamp = 2;
  729.    
  730.   boolean signed = true;
  731.   //Allowable true,false
  732.   boolean bigEndian = true;
  733.   //Allowable true,false
  734.  
  735.    
  736.     ByteBuffer byteBuffer = ByteBuffer.wrap(audioData);
  737.     ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
  738. int byteLength = audioData.length;
  739.    
  740.    
  741.     channels = 1;//Java allows 1 or 2
  742.      bytesPerSamp = 2;//Based on channels
  743.     sampleRate = 8000.0F;
  744.     // Allowable 8000,11025,16000,22050,44100
  745.     int sampLength = byteLength/bytesPerSamp;
  746.     int cnt2 = -8000;
  747.     int cnt3 = -16000;
  748.     int cnt4 = -24000;
  749.     for(int cnt1 = 0; cnt1 < sampLength;
  750.                     cnt1++,cnt2++,cnt3++,cnt4++){
  751.       double val = waWaPulseHelper(
  752.                                 cnt1,sampLength);
  753.       if(cnt2 > 0){
  754.         val += -0.7 * waWaPulseHelper(
  755.                                 cnt2,sampLength);
  756.       }//end if
  757.       if(cnt3 > 0){
  758.         val += 0.49 * waWaPulseHelper(
  759.                                 cnt3,sampLength);
  760.       }//end if
  761.       if(cnt4 > 0){
  762.         val += -0.34 * waWaPulseHelper(
  763.                                 cnt4,sampLength);
  764.       }//end if
  765.  
  766.       shortBuffer.put((short)val);
  767.     }//end for loop
  768.    
  769.      try{
  770.       //Get an input stream on the byte array
  771.       // containing the data
  772.       InputStream byteArrayInputStream =
  773.                         new ByteArrayInputStream(
  774.                                       audioData);
  775.  
  776.       //Get the required audio format
  777.       AudioFormat audioFormat = new AudioFormat(
  778.                                 sampleRate,
  779.                                 sampleSizeInBits,
  780.                                 channels,
  781.                                 signed,
  782.                                 bigEndian);
  783.  
  784.       //Get an audio input stream from the
  785.       // ByteArrayInputStream
  786.       AudioInputStream audioInputStream = new AudioInputStream(
  787.                     byteArrayInputStream,
  788.                     audioFormat,
  789.                     audioData.length/audioFormat.
  790.                                  getFrameSize());
  791.  
  792.       //Get info on the required data line
  793.       DataLine.Info dataLineInfo =
  794.                           new DataLine.Info(
  795.                             SourceDataLine.class,
  796.                                     audioFormat);
  797.  
  798.       //Get a SourceDataLine object
  799.       SourceDataLine sourceDataLine = (SourceDataLine)
  800.                              AudioSystem.getLine(
  801.                                    dataLineInfo);
  802.      
  803.      
  804.       sourceDataLine.open(audioFormat);
  805.       sourceDataLine.start();
  806.  
  807.       int cnt;
  808.       //Get beginning of elapsed time for
  809.       // playback
  810.       long startTime = new Date().getTime();
  811.  
  812.      
  813.       //This is a working buffer used to transfer
  814.   // the data between the AudioInputStream and
  815.   // the SourceDataLine.  The size is rather
  816.   // arbitrary.
  817.   byte playBuffer[] = new byte[16384];
  818.      
  819.       //Transfer the audio data to the speakers
  820.       while((cnt = audioInputStream.read(
  821.                               playBuffer, 0,
  822.                               playBuffer.length))
  823.                                           != -1){
  824.         //Keep looping until the input read
  825.         // method returns -1 for empty stream.
  826.         if(cnt > 0){
  827.           //Write data to the internal buffer of
  828.           // the data line where it will be
  829.           // delivered to the speakers in real
  830.           // time
  831.           sourceDataLine.write(
  832.                              playBuffer, 0, cnt);
  833.         }//end if
  834.       }//end while
  835.  
  836.       //Block and wait for internal buffer of the
  837.       // SourceDataLine to become empty.
  838.       sourceDataLine.drain();
  839.  
  840.  
  841.       //Get and display the elapsed time for
  842.       // the previous playback.
  843.       int elapsedTime =
  844.          (int)(new Date().getTime() - startTime);
  845.       System.out.println(elapsedTime);
  846. //      elapsedTimeMeter.setText("" + elapsedTime);
  847.  
  848.       //Finish with the SourceDataLine
  849.       sourceDataLine.stop();
  850.       sourceDataLine.close();
  851.      
  852.      
  853.           }catch (Exception e) {
  854.       e.printStackTrace();
  855.       System.exit(0);
  856.     }//end catch
  857.    
  858.     }
  859.     public static double waWaPulseHelper(int cnt,int sampLength){
  860.     //The value of scale controls the rate of
  861.     // decay - large scale, fast decay.
  862.       double scale = 2*cnt;
  863.       if(scale > sampLength) scale = sampLength;
  864.       double gain =
  865.              16000*(sampLength-scale)/sampLength;
  866.     double time = cnt/sampleRate;
  867.     double freq = 499.0;//an arbitrary freq
  868.     double sinValue =
  869.       (Math.sin(2*Math.PI*freq*time) +
  870.       Math.sin(2*Math.PI*(freq/1.8)*time) +
  871.       Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  872.     return(short)(gain*sinValue);
  873.   }//end waWaPulseHelper
  874.    
  875.    
  876.    
  877.    
  878.    
  879.     public static float sampleRate =8000.0F;
  880.     public static void main(String[] args) {
  881.         waWaPulse();
  882.       //  new AudioSynth01();
  883.         //A buffer to hold two seconds monaural and one
  884.   // second stereo data at 16000 samp/sec for
  885.   // 16-bit samples
  886.   byte audioData[] = new byte[16000*4];
  887.   //The following are audio format parameters.
  888.   // They may be modified by the signal generator
  889.   // at runtime.  Values allowed by Java
  890.   // SDK 1.4.1 are shown in comments.
  891.   //TODO
  892.   float sampleRate =8000.0F;// 16000.0F;
  893.   //Allowable 8000,11025,16000,22050,44100
  894.   int sampleSizeInBits = 16;
  895.   //Allowable 8,16
  896.   int channels = 1;
  897.   //Allowable 1,2
  898.   //Each channel requires two 8-bit bytes per
  899.     // 16-bit sample.
  900.     int bytesPerSamp = 2;
  901.    
  902.    
  903.        
  904.    
  905.    
  906.  
  907.   boolean signed = true;
  908.   //Allowable true,false
  909.   boolean bigEndian = true;
  910.   //Allowable true,false
  911.  
  912.    
  913.     ByteBuffer byteBuffer = ByteBuffer.wrap(audioData);
  914.     ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
  915.  
  916.     int byteLength = audioData.length;
  917.     int sampLength = byteLength/bytesPerSamp;
  918.     for(int cnt = 0; cnt < sampLength; cnt++){
  919.       double time = cnt/sampleRate;
  920.       double freq = 20000F;//950.0;//arbitrary frequency
  921.       double sinValue =
  922.         (Math.sin(2*Math.PI*freq*time) +
  923.         Math.sin(2*Math.PI*(freq/1.8)*time) +
  924.         Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
  925.       shortBuffer.put((short)(16000*sinValue));
  926.     }
  927.    
  928.           try{
  929.       //Get an input stream on the byte array
  930.       // containing the data
  931.       InputStream byteArrayInputStream =
  932.                         new ByteArrayInputStream(
  933.                                       audioData);
  934.  
  935.       //Get the required audio format
  936.       AudioFormat audioFormat = new AudioFormat(
  937.                                 sampleRate,
  938.                                 sampleSizeInBits,
  939.                                 channels,
  940.                                 signed,
  941.                                 bigEndian);
  942.  
  943.       //Get an audio input stream from the
  944.       // ByteArrayInputStream
  945.       AudioInputStream audioInputStream = new AudioInputStream(
  946.                     byteArrayInputStream,
  947.                     audioFormat,
  948.                     audioData.length/audioFormat.
  949.                                  getFrameSize());
  950.  
  951.       //Get info on the required data line
  952.       DataLine.Info dataLineInfo =
  953.                           new DataLine.Info(
  954.                             SourceDataLine.class,
  955.                                     audioFormat);
  956.  
  957.       //Get a SourceDataLine object
  958.       SourceDataLine sourceDataLine = (SourceDataLine)
  959.                              AudioSystem.getLine(
  960.                                    dataLineInfo);
  961.      
  962.      
  963.       sourceDataLine.open(audioFormat);
  964.       sourceDataLine.start();
  965.  
  966.       int cnt;
  967.       //Get beginning of elapsed time for
  968.       // playback
  969.       long startTime = new Date().getTime();
  970.  
  971.      
  972.       //This is a working buffer used to transfer
  973.   // the data between the AudioInputStream and
  974.   // the SourceDataLine.  The size is rather
  975.   // arbitrary.
  976.   byte playBuffer[] = new byte[16384];
  977.      
  978.       //Transfer the audio data to the speakers
  979.       while((cnt = audioInputStream.read(
  980.                               playBuffer, 0,
  981.                               playBuffer.length))
  982.                                           != -1){
  983.         //Keep looping until the input read
  984.         // method returns -1 for empty stream.
  985.         if(cnt > 0){
  986.           //Write data to the internal buffer of
  987.           // the data line where it will be
  988.           // delivered to the speakers in real
  989.           // time
  990.           sourceDataLine.write(
  991.                              playBuffer, 0, cnt);
  992.         }//end if
  993.       }//end while
  994.  
  995.       //Block and wait for internal buffer of the
  996.       // SourceDataLine to become empty.
  997.       sourceDataLine.drain();
  998.  
  999.  
  1000.       //Get and display the elapsed time for
  1001.       // the previous playback.
  1002.       int elapsedTime =
  1003.          (int)(new Date().getTime() - startTime);
  1004.       System.out.println(elapsedTime);
  1005. //      elapsedTimeMeter.setText("" + elapsedTime);
  1006.  
  1007.       //Finish with the SourceDataLine
  1008.       sourceDataLine.stop();
  1009.       sourceDataLine.close();
  1010.      
  1011.      
  1012.           }catch (Exception e) {
  1013.       e.printStackTrace();
  1014.       System.exit(0);
  1015.     }//end catch
  1016.         // TODO code application logic here
  1017.     }
  1018. }
Advertisement
Add Comment
Please, Sign In to add comment