-
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));
}
}
}
-
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
-
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
-
-
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
Forum Rules
|
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
|
Bookmarks