DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

+ Reply to Thread
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

Bookmarks

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


Top DevX Stories

Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL


Sponsored Links