Synthetic sound


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: Synthetic sound

  1. #1
    Join Date
    Feb 2005
    Posts
    10

    Synthetic sound

    Hi,
    I am having trouble with this code. I am trying to create a Player class (GUI) for Oscillator classes, but the first one that I did will not work properly. It gives me a very distorted noise and I cannot control the frequency properly. Could someone have a look and see where I am going wrong?

    Thanks
    Jay

    I have two seprate classes:

    public class FinalSounds {
    //---------------------------Globals------------------------------
    JFrame myFrame;
    JPanel centerPanel;
    JButton startButton;

    AudioInputStream audioInputStream; //used to handle the audio being written
    SourceDataLine sourceDataLine; //audio is written to this and then is passed to the mixer
    byte audioData[] = new byte[16000*4];
    AudioFormat audioFormat = getAudioFormat();

    //---------------------Main-------------------------------
    public static void main(String[] args){
    FinalSounds myProgram = new FinalSounds();
    myProgram.makeGui();
    }

    //------------------------------Methods-----------------------
    public void makeGui(){
    myFrame = new JFrame("FinalSound");
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    centerPanel = new JPanel();

    startButton = new JButton("Start");
    startButton.addActionListener(new StartListener());

    centerPanel.add(startButton);
    myFrame.getContentPane().add(BorderLayout.CENTER, centerPanel);


    myFrame.setLocation(100,100);
    myFrame.pack();
    myFrame.setVisible(true);
    }

    private AudioFormat getAudioFormat(){
    float sampleRate = 16000.0F;
    int sampleSizeInBits = 16;
    int channels = 2;
    boolean signed = true;
    boolean bigEndian = false;

    return new AudioFormat(sampleRate,sampleSizeInBits,channels,signed,bigEndian);
    }


    public void playSound(){
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(audioData);

    audioInputStream = new AudioInputStream(byteArrayInputStream,audioFormat,
    audioData.length/audioFormat.getFrameSize());
    DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat);
    try{
    sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
    }catch(Exception e){
    e.printStackTrace();
    }
    new PlayThread().start();
    }

    //----------------------------ActionListeners------------------

    class StartListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
    SimpleOsc simpleOsc = new SimpleOsc();
    simpleOsc.getSound(audioData);
    playSound();
    }
    }

    class PlayThread extends Thread{
    byte playBuffer[] = new byte[16000];

    public void run(){
    try{
    sourceDataLine.open(audioFormat);
    sourceDataLine.start();

    int counter;
    while((counter = audioInputStream.read(playBuffer,0,playBuffer.length)) != -1){
    if(counter > 0){
    sourceDataLine.write(playBuffer,0,counter);
    }
    }
    sourceDataLine.drain();
    sourceDataLine.stop();
    sourceDataLine.close();
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }
    }
    *
    public class SimpleOsc {
    ByteBuffer byteBuffer; //takes audioData[]
    ShortBuffer shortBuffer; //turns audioData[] into shortBuffer
    int byteLength; //hold length of audioData[]

    public void getSound(byte[] audioData){
    byteBuffer = ByteBuffer.wrap(audioData);
    shortBuffer = byteBuffer.asShortBuffer();

    byteLength = audioData.length;

    makeWave();
    }

    public void makeWave(){
    //int channels = 2;
    int bytesPerSample = 2;
    float sampleRate = 16000.0F;
    int sampleLength = byteLength/bytesPerSample;
    for(int i = 0; i< sampleLength;i++){
    double time = i/sampleRate;
    double freq = 440.0;
    double sinWave = Math.sin(2*Math.PI*freq*time);
    shortBuffer.put((short)(16000*sinWave));
    }
    }
    }

  2. #2
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    I am completely nooob in this area, but when i tried your soundprogram w. a jslider
    for selecting frequency, it made a resonably clean beeep at freq=400

    Here is my mod:
    Code:
    package stubs2;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.sound.sampled.*;
    import java.io.*;
    import java.nio.*;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public class FinalSounds implements ChangeListener {
    //---------------------------Globals------------------------------
      JFrame myFrame;
      JPanel centerPanel;
      JButton startButton;
      static javax.swing.JSlider slider=new javax.swing.JSlider(10,800);
      JLabel lbl=new JLabel("        ");
    
      AudioInputStream audioInputStream; //used to handle the audio being written
      SourceDataLine sourceDataLine; //audio is written to this and then is passed to the mixer
      byte audioData[] = new byte[16000 * 4];
      AudioFormat audioFormat = getAudioFormat();
      SimpleOsc sos = new SimpleOsc();
    
    //---------------------Main-------------------------------
      public static void main(String[] args) {
        FinalSounds myProgram = new FinalSounds();
        myProgram.makeGui();
      }
    
    //------------------------------Methods-----------------------
      public void makeGui() {
        myFrame = new JFrame("FinalSound");
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        centerPanel = new JPanel();
    
        startButton = new JButton("Start");
        startButton.addActionListener(new StartListener());
    
        centerPanel.add(startButton);
        slider.addChangeListener(this);
        centerPanel.add(slider);
         centerPanel.add(lbl);
        myFrame.getContentPane().add(BorderLayout.CENTER, centerPanel);
    
        myFrame.setLocation(100, 100);
        myFrame.pack();
        myFrame.setVisible(true);
      }
    
      private AudioFormat getAudioFormat() {
        float sampleRate = 16000.0F;
        int sampleSizeInBits =16;
        int channels = 2;
        boolean signed = true;
        boolean bigEndian = false;
    
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
                               bigEndian);
      }
    
      public void playSound() {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
            audioData);
    
        audioInputStream = new AudioInputStream(byteArrayInputStream, audioFormat,
                                                audioData.length /
                                                audioFormat.getFrameSize());
        DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
            audioFormat);
        try {
          sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        new PlayThread().start();
      }
    
    //----------------------------ActionListeners------------------
    
      class StartListener
          implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          SimpleOsc simpleOsc = new SimpleOsc();
          simpleOsc.getSound(audioData);
          playSound();
        }
      }
    
      class PlayThread
          extends Thread {
        byte playBuffer[] = new byte[16000];
    
        public void run() {
          try {
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();
    
            int counter;
            while ( (counter = audioInputStream.read(playBuffer, 0,
                                                     playBuffer.length)) != -1) {
              if (counter > 0) {
                sourceDataLine.write(playBuffer, 0, counter);
              }
            }
            sourceDataLine.drain();
            sourceDataLine.stop();
            sourceDataLine.close();
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      public void stateChanged(ChangeEvent e) {
        JSlider sld=(JSlider)e.getSource();
        lbl.setText(Integer.toString(sld.getValue()));
          sos.getSound(audioData);
          playSound();
    
      }
    }
    
    class SimpleOsc {
      ByteBuffer byteBuffer; //takes audioData[]
      ShortBuffer shortBuffer; //turns audioData[] into shortBuffer
      int byteLength; //hold length of audioData[]
    
      public void getSound(byte[] audioData) {
        byteBuffer = ByteBuffer.wrap(audioData);
        shortBuffer = byteBuffer.asShortBuffer();
    
        byteLength = audioData.length;
    
        makeWave();
      }
    
      public void makeWave() {
    //int channels = 2;
        int bytesPerSample = 2;
        float sampleRate = 16000.0F;
        int sampleLength = byteLength / bytesPerSample;
        for (int i = 0; i < sampleLength; i++) {
          double time = i / sampleRate;
          //double freq = 440.0;
          //double freq = 300.0d;
          double freq=FinalSounds.slider.getValue();
          double sinWave = Math.sin(2 * Math.PI * freq * time);
          shortBuffer.put( (short) (16000 * sinWave));
        }
      }
    }
    eschew obfuscation

  3. #3
    Join Date
    Feb 2005
    Posts
    10
    Thanks for your reply. I posted this question on about five different forums and your the only one who at least tried to help me.
    I found the problem yesterday night. Stupid mistake. In the audioFormat method I put

    boolean bigEndian = false;

    And it should be true. I am not sure what bigEndian is but I know that most machines use it and if its false my machine doesn't like it.

    Thanks again
    Jay

  4. #4
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    eschew obfuscation

  5. #5
    Join Date
    Feb 2005
    Posts
    10
    Thanks again.
    That makes a lot of sense. The reason why my sound was so strange was because it was storing the bytes and playing them back in reverse order - I assume.

    Not to mention, it's a pretty good tid-bit of information concerning languages. One more thing to tell my friends so they can roll their eyes and tell me i spend too much time behind the computer.

    cheers
    Jay

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center