Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package jacka;
- /**
- *
- * @author yoga1290
- */
- import javax.swing.*;
- import java.awt.*;
- import java.awt.event.*;
- import javax.sound.sampled.*;
- import java.io.*;
- import java.nio.channels.*;
- import java.nio.*;
- import java.util.*;
- //listed 4rm http://www.developer.com/java/other/article.php/2226701/Java-Sound-Creating-Playing-and-Saving-Synthetic-Sounds.htm
- class AudioSynth01 extends JFrame{
- //The following are general instance variables
- // used to create a SourceDataLine object.
- AudioFormat audioFormat;
- AudioInputStream audioInputStream;
- SourceDataLine sourceDataLine;
- //The following are audio format parameters.
- // They may be modified by the signal generator
- // at runtime. Values allowed by Java
- // SDK 1.4.1 are shown in comments.
- float sampleRate = 16000.0F;
- //Allowable 8000,11025,16000,22050,44100
- int sampleSizeInBits = 16;
- //Allowable 8,16
- int channels = 1;
- //Allowable 1,2
- boolean signed = true;
- //Allowable true,false
- boolean bigEndian = true;
- //Allowable true,false
- //A buffer to hold two seconds monaural and one
- // second stereo data at 16000 samp/sec for
- // 16-bit samples
- byte audioData[] = new byte[16000*4];
- //Following components appear in the North
- // position of the GUI.
- final JButton generateBtn =
- new JButton("Generate");
- final JButton playOrFileBtn =
- new JButton("Play/File");
- final JLabel elapsedTimeMeter =
- new JLabel("0000");
- //Following radio buttons select a synthetic
- // data type. Add more buttons if you add
- // more synthetic data types. They appear in
- // the center position of the GUI.
- final JRadioButton tones =
- new JRadioButton("Tones",true);
- final JRadioButton stereoPanning =
- new JRadioButton("Stereo Panning");
- final JRadioButton stereoPingpong =
- new JRadioButton("Stereo Pingpong");
- final JRadioButton fmSweep =
- new JRadioButton("FM Sweep");
- final JRadioButton decayPulse =
- new JRadioButton("Decay Pulse");
- final JRadioButton echoPulse =
- new JRadioButton("Echo Pulse");
- final JRadioButton waWaPulse =
- new JRadioButton("WaWa Pulse");
- //Following components appear in the South
- // position of the GUI.
- final JRadioButton listen =
- new JRadioButton("Listen",true);
- final JRadioButton file =
- new JRadioButton("File");
- final JTextField fileName =
- new JTextField("junk",10);
- //-------------------------------------------//
- public static void main(
- String args[]){
- new AudioSynth01();
- }//end main
- //-------------------------------------------//
- public AudioSynth01(){//constructor
- //A panel for the North position. Note the
- // etched border.
- final JPanel controlButtonPanel =
- new JPanel();
- controlButtonPanel.setBorder(
- BorderFactory.createEtchedBorder());
- //A panel and button group for the radio
- // buttons in the Center position.
- final JPanel synButtonPanel = new JPanel();
- final ButtonGroup synButtonGroup =
- new ButtonGroup();
- //This panel is used for cosmetic purposes
- // only, to cause the radio buttons to be
- // centered horizontally in the Center
- // position.
- final JPanel centerPanel = new JPanel();
- //A panel for the South position. Note the
- // etched border.
- final JPanel outputButtonPanel =
- new JPanel();
- outputButtonPanel.setBorder(
- BorderFactory.createEtchedBorder());
- final ButtonGroup outputButtonGroup =
- new ButtonGroup();
- //Disable the Play button initially to force
- // the user to generate some data before
- // trying to listen to it or write it to a
- // file.
- playOrFileBtn.setEnabled(false);
- //Register anonymous listeners on the
- // Generate button and the Play/File button.
- generateBtn.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- //Don't allow Play during generation
- playOrFileBtn.setEnabled(false);
- //Generate synthetic data
- new SynGen().getSyntheticData(
- audioData);
- //Now it is OK for the user to listen
- // to or file the synthetic audio data.
- playOrFileBtn.setEnabled(true);
- }//end actionPerformed
- }//end ActionListener
- );//end addActionListener()
- playOrFileBtn.addActionListener(
- new ActionListener(){
- public void actionPerformed(
- ActionEvent e){
- //Play or file the data synthetic data
- playOrFileData();
- }//end actionPerformed
- }//end ActionListener
- );//end addActionListener()
- //Add two buttons and a text field to a
- // physical group in the North of the GUI.
- controlButtonPanel.add(generateBtn);
- controlButtonPanel.add(playOrFileBtn);
- controlButtonPanel.add(elapsedTimeMeter);
- //Add radio buttons to a mutually exclusive
- // group in the Center of the GUI. Make
- // additions here if you add new synthetic
- // generator methods.
- synButtonGroup.add(tones);
- synButtonGroup.add(stereoPanning);
- synButtonGroup.add(stereoPingpong);
- synButtonGroup.add(fmSweep);
- synButtonGroup.add(decayPulse);
- synButtonGroup.add(echoPulse);
- synButtonGroup.add(waWaPulse);
- //Add radio buttons to a physical group and
- // center it in the Center of the GUI. Make
- // additions here if you add new synthetic
- // generator methods.
- synButtonPanel.setLayout(
- new GridLayout(0,1));
- synButtonPanel.add(tones);
- synButtonPanel.add(stereoPanning);
- synButtonPanel.add(stereoPingpong);
- synButtonPanel.add(fmSweep);
- synButtonPanel.add(decayPulse);
- synButtonPanel.add(echoPulse);
- synButtonPanel.add(waWaPulse);
- //Note that the centerPanel has center
- // alignment by default.
- centerPanel.add(synButtonPanel);
- //Add radio buttons to a mutually exclusive
- // group in the South of the GUI.
- outputButtonGroup.add(listen);
- outputButtonGroup.add(file);
- //Add radio buttons to a physical group in
- // the South of the GUI.
- outputButtonPanel.add(listen);
- outputButtonPanel.add(file);
- outputButtonPanel.add(fileName);
- //Add the panels containing components to the
- // content pane of the GUI in the appropriate
- // positions.
- getContentPane().add(
- controlButtonPanel,BorderLayout.NORTH);
- getContentPane().add(centerPanel,
- BorderLayout.CENTER);
- getContentPane().add(outputButtonPanel,
- BorderLayout.SOUTH);
- //Finish the GUI. If you add more radio
- // buttons in the center, you may need to
- // modify the call to setSize to increase
- // the vertical component of the GUI size.
- setTitle("Copyright 2003, R.G.Baldwin");
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- setSize(250,275);
- setVisible(true);
- }//end constructor
- //-------------------------------------------//
- //This method plays or files the synthetic
- // audio data that has been generated and saved
- // in an array in memory.
- private void playOrFileData() {
- try{
- //Get an input stream on the byte array
- // containing the data
- InputStream byteArrayInputStream =
- new ByteArrayInputStream(
- audioData);
- //Get the required audio format
- audioFormat = new AudioFormat(
- sampleRate,
- sampleSizeInBits,
- channels,
- signed,
- bigEndian);
- //Get an audio input stream from the
- // ByteArrayInputStream
- audioInputStream = new AudioInputStream(
- byteArrayInputStream,
- audioFormat,
- audioData.length/audioFormat.
- getFrameSize());
- //Get info on the required data line
- DataLine.Info dataLineInfo =
- new DataLine.Info(
- SourceDataLine.class,
- audioFormat);
- //Get a SourceDataLine object
- sourceDataLine = (SourceDataLine)
- AudioSystem.getLine(
- dataLineInfo);
- //Decide whether to play the synthetic
- // data immediately, or to write it into
- // an audio file, based on the user
- // selection of the radio buttons in the
- // South of the GUI..
- if(listen.isSelected()){
- //Create a thread to play back the data and
- // start it running. It will run until all
- // the data has been played back
- new ListenThread().start();
- }else{
- //Disable buttons until existing data
- // is written to the file.
- generateBtn.setEnabled(false);
- playOrFileBtn.setEnabled(false);
- //Write the data to an output file with
- // the name provided by the text field
- // in the South of the GUI.
- try{
- AudioSystem.write(
- audioInputStream,
- AudioFileFormat.Type.AU,
- new File(fileName.getText() +
- ".au"));
- }catch (Exception e) {
- e.printStackTrace();
- System.exit(0);
- }//end catch
- //Enable buttons for another operation
- generateBtn.setEnabled(true);
- playOrFileBtn.setEnabled(true);
- }//end else
- }catch (Exception e) {
- e.printStackTrace();
- System.exit(0);
- }//end catch
- }//end playOrFileData
- //=============================================//
- //Inner class to play back the data that was
- // saved.
- class ListenThread extends Thread{
- //This is a working buffer used to transfer
- // the data between the AudioInputStream and
- // the SourceDataLine. The size is rather
- // arbitrary.
- byte playBuffer[] = new byte[16384];
- public void run(){
- try{
- //Disable buttons while data is being
- // played.
- generateBtn.setEnabled(false);
- playOrFileBtn.setEnabled(false);
- //Open and start the SourceDataLine
- sourceDataLine.open(audioFormat);
- sourceDataLine.start();
- int cnt;
- //Get beginning of elapsed time for
- // playback
- long startTime = new Date().getTime();
- //Transfer the audio data to the speakers
- while((cnt = audioInputStream.read(
- playBuffer, 0,
- playBuffer.length))
- != -1){
- //Keep looping until the input read
- // method returns -1 for empty stream.
- if(cnt > 0){
- //Write data to the internal buffer of
- // the data line where it will be
- // delivered to the speakers in real
- // time
- sourceDataLine.write(
- playBuffer, 0, cnt);
- }//end if
- }//end while
- //Block and wait for internal buffer of the
- // SourceDataLine to become empty.
- sourceDataLine.drain();
- //Get and display the elapsed time for
- // the previous playback.
- int elapsedTime =
- (int)(new Date().getTime() - startTime);
- elapsedTimeMeter.setText("" + elapsedTime);
- //Finish with the SourceDataLine
- sourceDataLine.stop();
- sourceDataLine.close();
- //Re-enable buttons for another operation
- generateBtn.setEnabled(true);
- playOrFileBtn.setEnabled(true);
- }catch (Exception e) {
- e.printStackTrace();
- System.exit(0);
- }//end catch
- }//end run
- }//end inner class ListenThread
- //=============================================//
- //Inner signal generator class.
- //An object of this class can be used to
- // generate a variety of different synthetic
- // audio signals. Each time the getSyntheticData
- // method is called on an object of this class,
- // the method will fill the incoming array with
- // the samples for a synthetic signal.
- class SynGen{
- //Note: Because this class uses a ByteBuffer
- // asShortBuffer to handle the data, it can
- // only be used to generate signed 16-bit
- // data.
- ByteBuffer byteBuffer;
- ShortBuffer shortBuffer;
- int byteLength;
- void getSyntheticData(byte[] synDataBuffer){
- //Prepare the ByteBuffer and the shortBuffer
- // for use
- byteBuffer = ByteBuffer.wrap(synDataBuffer);
- shortBuffer = byteBuffer.asShortBuffer();
- byteLength = synDataBuffer.length;
- //Decide which synthetic data generator
- // method to invoke based on which radio
- // button the user selected in the Center of
- // the GUI. If you add more methods for
- // other synthetic data types, you need to
- // add corresponding radio buttons to the
- // GUI and add statements here to test the
- // new radio buttons. Make additions here
- // if you add new synthetic generator
- // methods.
- if(tones.isSelected()) tones();
- if(stereoPanning.isSelected())
- stereoPanning();
- if(stereoPingpong.isSelected())
- stereoPingpong();
- if(fmSweep.isSelected()) fmSweep();
- if(decayPulse.isSelected()) decayPulse();
- if(echoPulse.isSelected()) echoPulse();
- if(waWaPulse.isSelected()) waWaPulse();
- }//end getSyntheticData method
- //-------------------------------------------//
- //This method generates a monaural tone
- // consisting of the sum of three sinusoids.
- void tones(){
- channels = 1;//Java allows 1 or 2
- //Each channel requires two 8-bit bytes per
- // 16-bit sample.
- int bytesPerSamp = 2;
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- for(int cnt = 0; cnt < sampLength; cnt++){
- double time = cnt/sampleRate;
- double freq = 950.0;//arbitrary frequency
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- shortBuffer.put((short)(16000*sinValue));
- }//end for loop
- }//end method tones
- //-------------------------------------------//
- //This method generates a stereo speaker sweep,
- // starting with a relatively high frequency
- // tone on the left speaker and moving across
- // to a lower frequency tone on the right
- // speaker.
- void stereoPanning(){
- channels = 2;//Java allows 1 or 2
- int bytesPerSamp = 4;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- for(int cnt = 0; cnt < sampLength; cnt++){
- //Calculate time-varying gain for each
- // speaker
- double rightGain = 16000.0*cnt/sampLength;
- double leftGain = 16000.0 - rightGain;
- double time = cnt/sampleRate;
- double freq = 600;//An arbitrary frequency
- //Generate data for left speaker
- double sinValue =
- Math.sin(2*Math.PI*(freq)*time);
- shortBuffer.put(
- (short)(leftGain*sinValue));
- //Generate data for right speaker
- sinValue =
- Math.sin(2*Math.PI*(freq*0.8)*time);
- shortBuffer.put(
- (short)(rightGain*sinValue));
- }//end for loop
- }//end method stereoPanning
- //-------------------------------------------//
- //This method uses stereo to switch a sound
- // back and forth between the left and right
- // speakers at a rate of about eight switches
- // per second. On my system, this is a much
- // better demonstration of the sound separation
- // between the two speakers than is the
- // demonstration produced by the stereoPanning
- // method. Note also that because the sounds
- // are at different frequencies, the sound
- // produced is similar to that of U.S.
- // emergency vehicles.
- void stereoPingpong(){
- channels = 2;//Java allows 1 or 2
- int bytesPerSamp = 4;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- double leftGain = 0.0;
- double rightGain = 16000.0;
- for(int cnt = 0; cnt < sampLength; cnt++){
- //Calculate time-varying gain for each
- // speaker
- if(cnt % (sampLength/8) == 0){
- //swap gain values
- double temp = leftGain;
- leftGain = rightGain;
- rightGain = temp;
- }//end if
- double time = cnt/sampleRate;
- double freq = 600;//An arbitrary frequency
- //Generate data for left speaker
- double sinValue =
- Math.sin(2*Math.PI*(freq)*time);
- shortBuffer.put(
- (short)(leftGain*sinValue));
- //Generate data for right speaker
- sinValue =
- Math.sin(2*Math.PI*(freq*0.8)*time);
- shortBuffer.put(
- (short)(rightGain*sinValue));
- }//end for loop
- }//end stereoPingpong method
- //-------------------------------------------//
- //This method generates a monaural linear
- // frequency sweep from 100 Hz to 1000Hz.
- void fmSweep(){
- channels = 1;//Java allows 1 or 2
- int bytesPerSamp = 2;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- double lowFreq = 100.0;
- double highFreq = 1000.0;
- for(int cnt = 0; cnt < sampLength; cnt++){
- double time = cnt/sampleRate;
- double freq = lowFreq +
- cnt*(highFreq-lowFreq)/sampLength;
- double sinValue =
- Math.sin(2*Math.PI*freq*time);
- shortBuffer.put((short)(16000*sinValue));
- }//end for loop
- }//end method fmSweep
- //-------------------------------------------//
- //This method generates a monaural triple-
- // frequency pulse that decays in a linear
- // fashion with time.
- void decayPulse(){
- channels = 1;//Java allows 1 or 2
- int bytesPerSamp = 2;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- for(int cnt = 0; cnt < sampLength; cnt++){
- //The value of scale controls the rate of
- // decay - large scale, fast decay.
- double scale = 2*cnt;
- if(scale > sampLength) scale = sampLength;
- double gain =
- 16000*(sampLength-scale)/sampLength;
- double time = cnt/sampleRate;
- double freq = 499.0;//an arbitrary freq
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- shortBuffer.put((short)(gain*sinValue));
- }//end for loop
- }//end method decayPulse
- //-------------------------------------------//
- //This method generates a monaural triple-
- // frequency pulse that decays in a linear
- // fashion with time. However, three echoes
- // can be heard over time with the amplitude
- // of the echoes also decreasing with time.
- void echoPulse(){
- channels = 1;//Java allows 1 or 2
- int bytesPerSamp = 2;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- int cnt2 = -8000;
- int cnt3 = -16000;
- int cnt4 = -24000;
- for(int cnt1 = 0; cnt1 < sampLength;
- cnt1++,cnt2++,cnt3++,cnt4++){
- double val = echoPulseHelper(
- cnt1,sampLength);
- if(cnt2 > 0){
- val += 0.7 * echoPulseHelper(
- cnt2,sampLength);
- }//end if
- if(cnt3 > 0){
- val += 0.49 * echoPulseHelper(
- cnt3,sampLength);
- }//end if
- if(cnt4 > 0){
- val += 0.34 * echoPulseHelper(
- cnt4,sampLength);
- }//end if
- shortBuffer.put((short)val);
- }//end for loop
- }//end method echoPulse
- //-------------------------------------------//
- double echoPulseHelper(int cnt,int sampLength){
- //The value of scale controls the rate of
- // decay - large scale, fast decay.
- double scale = 2*cnt;
- if(scale > sampLength) scale = sampLength;
- double gain =
- 16000*(sampLength-scale)/sampLength;
- double time = cnt/sampleRate;
- double freq = 499.0;//an arbitrary freq
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- return(short)(gain*sinValue);
- }//end echoPulseHelper
- //-------------------------------------------//
- //This method generates a monaural triple-
- // frequency pulse that decays in a linear
- // fashion with time. However, three echoes
- // can be heard over time with the amplitude
- // of the echoes also decreasing with time.
- //Note that this method is identical to the
- // method named echoPulse, except that the
- // algebraic sign was switched on the amplitude
- // of two of the echoes before adding them to
- // the composite synthetic signal. This
- // resulted in a difference in the
- // sound.
- void waWaPulse(){
- channels = 1;//Java allows 1 or 2
- int bytesPerSamp = 2;//Based on channels
- sampleRate = 16000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- int cnt2 = -8000;
- int cnt3 = -16000;
- int cnt4 = -24000;
- for(int cnt1 = 0; cnt1 < sampLength;
- cnt1++,cnt2++,cnt3++,cnt4++){
- double val = waWaPulseHelper(
- cnt1,sampLength);
- if(cnt2 > 0){
- val += -0.7 * waWaPulseHelper(
- cnt2,sampLength);
- }//end if
- if(cnt3 > 0){
- val += 0.49 * waWaPulseHelper(
- cnt3,sampLength);
- }//end if
- if(cnt4 > 0){
- val += -0.34 * waWaPulseHelper(
- cnt4,sampLength);
- }//end if
- shortBuffer.put((short)val);
- }//end for loop
- }//end method waWaPulse
- //-------------------------------------------//
- double waWaPulseHelper(int cnt,int sampLength){
- //The value of scale controls the rate of
- // decay - large scale, fast decay.
- double scale = 2*cnt;
- if(scale > sampLength) scale = sampLength;
- double gain =
- 16000*(sampLength-scale)/sampLength;
- double time = cnt/sampleRate;
- double freq = 499.0;//an arbitrary freq
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- return(short)(gain*sinValue);
- }//end waWaPulseHelper
- //-------------------------------------------//
- }//end SynGen class
- //=============================================//
- }//end outer class AudioSynth01.java
- public class Jacka {
- /**
- * @param args the command line arguments
- */
- public static void waWaPulse(){
- // new AudioSynth01();
- //A buffer to hold two seconds monaural and one
- // second stereo data at 16000 samp/sec for
- // 16-bit samples
- byte audioData[] = new byte[16000*4];
- //The following are audio format parameters.
- // They may be modified by the signal generator
- // at runtime. Values allowed by Java
- // SDK 1.4.1 are shown in comments.
- //TODO
- float sampleRate =8000.0F;// 16000.0F;
- //Allowable 8000,11025,16000,22050,44100
- int sampleSizeInBits = 16;
- //Allowable 8,16
- int channels = 1;
- //Allowable 1,2
- //Each channel requires two 8-bit bytes per
- // 16-bit sample.
- int bytesPerSamp = 2;
- boolean signed = true;
- //Allowable true,false
- boolean bigEndian = true;
- //Allowable true,false
- ByteBuffer byteBuffer = ByteBuffer.wrap(audioData);
- ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
- int byteLength = audioData.length;
- channels = 1;//Java allows 1 or 2
- bytesPerSamp = 2;//Based on channels
- sampleRate = 8000.0F;
- // Allowable 8000,11025,16000,22050,44100
- int sampLength = byteLength/bytesPerSamp;
- int cnt2 = -8000;
- int cnt3 = -16000;
- int cnt4 = -24000;
- for(int cnt1 = 0; cnt1 < sampLength;
- cnt1++,cnt2++,cnt3++,cnt4++){
- double val = waWaPulseHelper(
- cnt1,sampLength);
- if(cnt2 > 0){
- val += -0.7 * waWaPulseHelper(
- cnt2,sampLength);
- }//end if
- if(cnt3 > 0){
- val += 0.49 * waWaPulseHelper(
- cnt3,sampLength);
- }//end if
- if(cnt4 > 0){
- val += -0.34 * waWaPulseHelper(
- cnt4,sampLength);
- }//end if
- shortBuffer.put((short)val);
- }//end for loop
- try{
- //Get an input stream on the byte array
- // containing the data
- InputStream byteArrayInputStream =
- new ByteArrayInputStream(
- audioData);
- //Get the required audio format
- AudioFormat audioFormat = new AudioFormat(
- sampleRate,
- sampleSizeInBits,
- channels,
- signed,
- bigEndian);
- //Get an audio input stream from the
- // ByteArrayInputStream
- AudioInputStream audioInputStream = new AudioInputStream(
- byteArrayInputStream,
- audioFormat,
- audioData.length/audioFormat.
- getFrameSize());
- //Get info on the required data line
- DataLine.Info dataLineInfo =
- new DataLine.Info(
- SourceDataLine.class,
- audioFormat);
- //Get a SourceDataLine object
- SourceDataLine sourceDataLine = (SourceDataLine)
- AudioSystem.getLine(
- dataLineInfo);
- sourceDataLine.open(audioFormat);
- sourceDataLine.start();
- int cnt;
- //Get beginning of elapsed time for
- // playback
- long startTime = new Date().getTime();
- //This is a working buffer used to transfer
- // the data between the AudioInputStream and
- // the SourceDataLine. The size is rather
- // arbitrary.
- byte playBuffer[] = new byte[16384];
- //Transfer the audio data to the speakers
- while((cnt = audioInputStream.read(
- playBuffer, 0,
- playBuffer.length))
- != -1){
- //Keep looping until the input read
- // method returns -1 for empty stream.
- if(cnt > 0){
- //Write data to the internal buffer of
- // the data line where it will be
- // delivered to the speakers in real
- // time
- sourceDataLine.write(
- playBuffer, 0, cnt);
- }//end if
- }//end while
- //Block and wait for internal buffer of the
- // SourceDataLine to become empty.
- sourceDataLine.drain();
- //Get and display the elapsed time for
- // the previous playback.
- int elapsedTime =
- (int)(new Date().getTime() - startTime);
- System.out.println(elapsedTime);
- // elapsedTimeMeter.setText("" + elapsedTime);
- //Finish with the SourceDataLine
- sourceDataLine.stop();
- sourceDataLine.close();
- }catch (Exception e) {
- e.printStackTrace();
- System.exit(0);
- }//end catch
- }
- public static double waWaPulseHelper(int cnt,int sampLength){
- //The value of scale controls the rate of
- // decay - large scale, fast decay.
- double scale = 2*cnt;
- if(scale > sampLength) scale = sampLength;
- double gain =
- 16000*(sampLength-scale)/sampLength;
- double time = cnt/sampleRate;
- double freq = 499.0;//an arbitrary freq
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- return(short)(gain*sinValue);
- }//end waWaPulseHelper
- public static float sampleRate =8000.0F;
- public static void main(String[] args) {
- waWaPulse();
- // new AudioSynth01();
- //A buffer to hold two seconds monaural and one
- // second stereo data at 16000 samp/sec for
- // 16-bit samples
- byte audioData[] = new byte[16000*4];
- //The following are audio format parameters.
- // They may be modified by the signal generator
- // at runtime. Values allowed by Java
- // SDK 1.4.1 are shown in comments.
- //TODO
- float sampleRate =8000.0F;// 16000.0F;
- //Allowable 8000,11025,16000,22050,44100
- int sampleSizeInBits = 16;
- //Allowable 8,16
- int channels = 1;
- //Allowable 1,2
- //Each channel requires two 8-bit bytes per
- // 16-bit sample.
- int bytesPerSamp = 2;
- boolean signed = true;
- //Allowable true,false
- boolean bigEndian = true;
- //Allowable true,false
- ByteBuffer byteBuffer = ByteBuffer.wrap(audioData);
- ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
- int byteLength = audioData.length;
- int sampLength = byteLength/bytesPerSamp;
- for(int cnt = 0; cnt < sampLength; cnt++){
- double time = cnt/sampleRate;
- double freq = 20000F;//950.0;//arbitrary frequency
- double sinValue =
- (Math.sin(2*Math.PI*freq*time) +
- Math.sin(2*Math.PI*(freq/1.8)*time) +
- Math.sin(2*Math.PI*(freq/1.5)*time))/3.0;
- shortBuffer.put((short)(16000*sinValue));
- }
- try{
- //Get an input stream on the byte array
- // containing the data
- InputStream byteArrayInputStream =
- new ByteArrayInputStream(
- audioData);
- //Get the required audio format
- AudioFormat audioFormat = new AudioFormat(
- sampleRate,
- sampleSizeInBits,
- channels,
- signed,
- bigEndian);
- //Get an audio input stream from the
- // ByteArrayInputStream
- AudioInputStream audioInputStream = new AudioInputStream(
- byteArrayInputStream,
- audioFormat,
- audioData.length/audioFormat.
- getFrameSize());
- //Get info on the required data line
- DataLine.Info dataLineInfo =
- new DataLine.Info(
- SourceDataLine.class,
- audioFormat);
- //Get a SourceDataLine object
- SourceDataLine sourceDataLine = (SourceDataLine)
- AudioSystem.getLine(
- dataLineInfo);
- sourceDataLine.open(audioFormat);
- sourceDataLine.start();
- int cnt;
- //Get beginning of elapsed time for
- // playback
- long startTime = new Date().getTime();
- //This is a working buffer used to transfer
- // the data between the AudioInputStream and
- // the SourceDataLine. The size is rather
- // arbitrary.
- byte playBuffer[] = new byte[16384];
- //Transfer the audio data to the speakers
- while((cnt = audioInputStream.read(
- playBuffer, 0,
- playBuffer.length))
- != -1){
- //Keep looping until the input read
- // method returns -1 for empty stream.
- if(cnt > 0){
- //Write data to the internal buffer of
- // the data line where it will be
- // delivered to the speakers in real
- // time
- sourceDataLine.write(
- playBuffer, 0, cnt);
- }//end if
- }//end while
- //Block and wait for internal buffer of the
- // SourceDataLine to become empty.
- sourceDataLine.drain();
- //Get and display the elapsed time for
- // the previous playback.
- int elapsedTime =
- (int)(new Date().getTime() - startTime);
- System.out.println(elapsedTime);
- // elapsedTimeMeter.setText("" + elapsedTime);
- //Finish with the SourceDataLine
- sourceDataLine.stop();
- sourceDataLine.close();
- }catch (Exception e) {
- e.printStackTrace();
- System.exit(0);
- }//end catch
- // TODO code application logic here
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment