# Frequenzausgabe (2 Kanal) über Lautsprecherausgang



## Robohac (20. Feb 2011)

Hallo,

*Vorgeschichte:*
Ich experimentiere schon etwas länger mit Lasern. Mitlerweile habe ich mir eine Aparatur gebastelt, mit der man einen Laserstrahl so ablenken kann, dass sogenannte Lissajous-Figuren entstehen.
Hierzu wird ein spiegel in vertikaler Richtung in einer bestimmten Frequenz bewegt und einer in horizontaler Richtung.

Diese ganze abaratur habe ich bisher mit "Sweepgen" angesteuert. das ist aber sehr ungenau.

*Vorhaben:*
Deswegen würde ich gerne ein kleines Java Programm schreiben, welches dem rechten und linken Audiokanal getrennte und exakt einstellbare Frequenzen ausgiebt.

*Meine Java Kentnisse:*
Ich beherrsche die grundlegenden Strukturen eines Java-Programms (Konsole)

*Bisherige Recherge::rtfm:*
Bei meiner bisherigen Recherge bin ich nur auf eine Möglichkeit, die ich für nicht verwendbar halte gestoßen: 
Einen via MIDI generierten ton abzuspielen.

*Was im Programm noch ganz nett sein würde:*
Wenn man die Frequenzen verschieben könnte (das nicht beide bei 0 anfangen), da die Figuren so ganz anders aussehen.


Ich weiß, dass das viel ist, aber mich würde es trotzdem freuen, wenn ihr mir helfen könntet. Deswegen schonmal danke im Voraus.:toll:

LG


----------



## tuxedo (21. Feb 2011)

Na solange die Frequenz in dem Bereich liegt den die SOurndkarte ausgeben kann geht das. Musst nur das passende Signal "generieren". Vereinfacht gesprochen: Einfach einen Sinus (oder was auch immer du brauchst) als byte-Strom erzeugen und in die Soundkarte stecken.

Alle wichtigen Informationen zur Soundkartenansteuerung bekommst du hier: 

Java Sound Resources

- Alex

[update]
Hier gibt's sogar ein Sample zum erzeugen von Frequenzen verschiedenster Formen:

Playing waveforms


----------



## Robohac (21. Feb 2011)

Ich habe auch etwas gefunden:


```
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;

public class Main {

        public byte[] getSinusTone(int frequency, AudioFormat af) {
            byte sample_size = (byte) (af.getSampleSizeInBits() / 8);
            byte[] data = new byte[(int) af.getSampleRate() * sample_size];
            double step_width = (2 * Math.PI) / af.getSampleRate();
            double x = 0;

            for (int i = 0; i < data.length; i += sample_size) {
                int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
                int value = (int) (sample_max_value * Math.sin(frequency * x));
                for (int j = 0; j < sample_size; j++) {
                    byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
                    data[i + j] = sample_byte;
                }
                x += step_width;
            }
            return data;
        }

        public void play(int frequenzy) {
            AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
            byte[] data = getSinusTone(frequenzy, af);
            try {
                Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));

                c.open(af, data, 0, data.length);
                c.start();
                c.loop(1000);
                while(c.isRunning()) {
                    try {
                        Thread.sleep(50);
                    } catch (Exception ex) {}
                }
            } catch (LineUnavailableException ex) {
                ex.printStackTrace();
            }
        }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("Usage: ToneGeneratorExample <frequency>");
            System.exit(-1);
        }
        play(500);
        new ToneGeneratorExample().play(Integer.parseInt(args[0]));
    }
}
```
Des is aber irgendwie verkorkst und lässt sich mit Netbeans nicht Kompilieren:

```
run:
java.lang.NoClassDefFoundError: frequenz/Main
Caused by: java.lang.ClassNotFoundException: frequenz.Main
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: frequenz.Main.  Program will exit.
Exception in thread "main" Java Result: 1
BUILD SUCCESSFUL (total time: 4 seconds)
```

Trotzdem schonmal danke tuxedo.


----------



## Andi_CH (21. Feb 2011)

So läufts bei mir

Aber eigentlich war ja die Frage nach den beiden Stereokanälen - wie werden die angesteuert?


```
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;

public class ToneGeneratorExample {

	public byte[] getSinusTone(int frequency, AudioFormat af) {
		byte sample_size = (byte) (af.getSampleSizeInBits() / 8);
		byte[] data = new byte[(int) af.getSampleRate() * sample_size];
		double step_width = (2 * Math.PI) / af.getSampleRate();
		double x = 0;

		for (int i = 0; i < data.length; i += sample_size) {
			int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
			int value = (int) (sample_max_value * Math.sin(frequency * x));
			for (int j = 0; j < sample_size; j++) {
				byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
				data[i + j] = sample_byte;
			}
			x += step_width;
		}
		return data;
	}

	public void play(int frequenzy) {
		AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
		byte[] data = getSinusTone(frequenzy, af);
		try {
			Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));

			c.open(af, data, 0, data.length);
			c.start();
			c.loop(5);
			while(c.isRunning()) {
				try {
					Thread.sleep(50);
				} catch (Exception ex) {}
			}
		} catch (LineUnavailableException ex) {
			ex.printStackTrace();
		}
	}

	public static void main(String[] args) {
		ToneGeneratorExample tge = new ToneGeneratorExample();
		if (args.length != 1) {
			tge.play(500);
		} else {
			tge.play(Integer.parseInt(args[0]));
		}
	}
}
```


----------



## tuxedo (21. Feb 2011)

AudioFormat (Java Platform SE 6)

Der dritte Parameter gibt die Anzahl Channels an. Hier im Beispiel steht das auf 1, und nicht auf 2.

Wie man für rechts und links einen getrennten Audiostream auf das Interface ausgibt weiß ich auch nicht auswendig. Aber ich bin mir sicher dass die von mir gelinkte Webseite die Antwort darauf hat.

- Alex


----------



## Robohac (21. Feb 2011)

@tuxedo:  Ich habe mir die seite mal durgelesen und habe zwar gefunden, wie man die anzahl der Chanels einstellt, aber nicht wie man sie einzeln ansteuert

@Andi_CH:  In Netbeans funktioniert des schonwieder net:

```
run:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - cannot find symbol
  symbol:   class ToneGeneratorExample
  location: class NewClass
        at NewClass.main(NewClass.java:47)
Java Result: 1
BUILD SUCCESSFUL (total time: 5 seconds)
```
aber im "Java Editor" funktioniert es. ich habe mal mit den chanels rumgespielt:
[JAVA=27]    public void play2(int frequenzy) {
        AudioFormat af = new AudioFormat(44100, 16, 2, true, false);[/code]
[JAVA=45]    public void play1(int frequenzy) {
        AudioFormat af = new AudioFormat(44100, 16, 1, true, false);[/code]
[JAVA=66]        if (args.length != 1) {
            tge.play1(500);
            tge.play2(200);
        } else {
            tge.play1(Integer.parseInt(args[0]));
            tge.play2(Integer.parseInt(args[0]));
        }[/code]

Aber leider funktioniert das so nicht, also es kommt zwar immer Ton raus, aber immer auf beiden Kanälen.


----------



## hansmueller (21. Feb 2011)

Hallo,

schau dir mal diese Links an:
Trail: Sound (The Java™ Tutorials)
Overview of the Sampled Package (The Java™ Tutorials > Sound)

MfG
hansmueller


----------



## Andi_CH (21. Feb 2011)

Der Code funktioniert mit Stereo.
Wie du den als Bohne kompilieren und laufen lassen kannst weiss ich nicht. -> Gurus vor!

Noch zum Thema API-Beschreibung - das was ich da mache war einfach so ein Schuss ins Blaue, dass die Samples nacheinander kommen stand auf jeden Fall nicht auf der verlinkten Seite.


```
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;

public class ToneGeneratorExample {

	public byte[] getMonoSinusTone(int frequency, AudioFormat af) {
		byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
		byte[] data = new byte[(int) af.getSampleRate() * sampleSize];
		double step_width = (2 * Math.PI) / af.getSampleRate();
		double x = 0;
		for (int i = 0; i < data.length; i += sampleSize) {
			int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
			int value = (int) (sample_max_value * Math.sin(frequency * x));
			for (int j = 0; j < sampleSize; j++) {
				byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
				data[i + j] = sample_byte;
			}
			x += step_width;
		}
		return data;
	}

	public byte[] getStereoSinusTone(int frequency1, int frequency2, AudioFormat af) {
		byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
		byte[] data = new byte[(int) af.getSampleRate() * sampleSize  * 2];
		double stepWidth = (2 * Math.PI) / af.getSampleRate();
		double x = 0;
		for (int i = 0; i < data.length; i += sampleSize * 2) {
			int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
			int value = (int) (sample_max_value * Math.sin(frequency1 * x));
			for (int j = 0; j < sampleSize; j++) {
				byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
				data[i + j] = sampleByte;
			}
			value = (int) (sample_max_value * Math.sin(frequency2 * x));
			for (int j = 0; j < sampleSize; j++) {
				byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
				int index = i + j + sampleSize;
				data[index] = sampleByte;
			}
			x += stepWidth;
		}
		return data;
	}

	public void play(int frequenzy) {
		AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
		byte[] data = getMonoSinusTone(frequenzy, af);
		try {
			Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
			c.open(af, data, 0, data.length);
			c.loop(1);
			while(c.isRunning()) {
				try {
					Thread.sleep(50);
				} catch (Exception ex) {}
			}
		} catch (LineUnavailableException ex) {
			ex.printStackTrace();
		}
	}

	public void play(int frequenzy1, int  frequency2) {
		AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
		byte[] data = getStereoSinusTone(frequenzy1, frequency2, af);
		try {
			Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
			c.open(af, data, 0, data.length);
			c.loop(1);
			while(c.isRunning()) {
				try {
					Thread.sleep(50);
				} catch (Exception ex) {}
			}
		} catch (LineUnavailableException ex) {
			ex.printStackTrace();
		}
	}

	public static void main(String[] args) {
		ToneGeneratorExample tge = new ToneGeneratorExample();
		if (args.length == 1) {
			tge.play(Integer.parseInt(args[0]));
		} else if (args.length == 2) {
			tge.play(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
		} else {
			tge.play(500);
			tge.play(500, 1300);
		}
	}
}
```


----------



## Robohac (21. Feb 2011)

Das das nacheinander kommt war mir klar! Mit dem Prograsmm bekommt man schon zwei frequenzen :applaus:.

Ich habe mir die Links nochmal alle durchgelesen und bin dann auf der seite Hier in der Tabelle auf eine funktion gestoßen. Man könnte den Mixer nutzen, und die Balance Schnell ändern. Nur leider hege ich die Vermutung, dass das die soundkarte eventuell nicht mitmacht, oder sich die Töne dadurch verzerren.

Ich versuche das mal auszuprobieren.

Noch zwo Links:
Trail: Sound (The Java™ Tutorials)
Java Sound Programmer Guide


----------



## HoaX (21. Feb 2011)

Zum Ändern der Lautstärke kannst du auch einfach deine einzelnen Samples mit einem entsprechenden Wert multiplizieren. Ist ja PCM, und kleinere Amplitude -> geringere Lautstärke, und umgedreht.


----------



## Robohac (21. Feb 2011)

Es geht ja aber nicht um die Lautstärke, sondern um die Problematik dass z.B. auf dem linken Lautsprecher 500Hz und auf dem anderen 1000Hz sein sollen

Edit:
Irgendwie versteh ich nicht wie man den Befehl im Programmzusammenhang verwenden soll


----------



## Andi_CH (22. Feb 2011)

Robohac hat gesagt.:


> Es geht ja aber nicht um die Lautstärke, sondern um die Problematik dass z.B. auf dem linken Lautsprecher 500Hz und auf dem anderen 1000Hz sein sollen
> 
> Edit:
> Irgendwie versteh ich nicht wie man den Befehl im Programmzusammenhang verwenden soll



Ahem Halloooo?

Was hab ich dir denn geschrieben?

```
public byte[] getStereoSinusTone(int frequency1, int frequency2, AudioFormat af)
```

Kannst die Parameter ja gerne  auf frequenencyLeft und frequencyRight umbenennen wenn dir das besser gefällt ...

So nebenbei eine Frequenz von 0 ergibt schweigen auf dem Kanal  Kannst dich also gerne davon überzeugen, dass das als Stereo widergegeben wird und nicht einfach als Mischsignal, indem du einen der Werte auf 0 setzt.

Für deine Anwendung würde ich das generieren des Signales in einen eigenen Thread packen und mit einem anderen Thread Amplitude und Frequenz setzen. 
Wie sich das dann unterbruchsfrei steuern lässt muss man halt ausprobieren - ich weiss nicht ob der Soundkontext das Samplearray in die Soundkarte kopiert oder immer wieder ausliest ....


----------



## Robohac (22. Feb 2011)

Also ich habe das Programm nochmal ausgiebig in allen variationen getestet.

Bei mir Funktioniert das programm tadellos. Es giebt erst eine Frequenz auf beiden Boxen aus, danach die Beiden anderen und zwar wie folgt: Auf beiden Kanälen das gleiche: Die beiden Frequenzen gemischt.
Und ja ich habe auch mal eine der beiden Frequenzen (und auch die andere) auf null gesetzt, und es kam auf beiden Lautsprechern die Frequenz die nicht auf null gesetzt war.

P.S.
Ich nutze diesen Java-Editor


----------



## Andi_CH (24. Feb 2011)

Robohac hat gesagt.:


> Also ich habe das Programm nochmal ausgiebig in allen variationen getestet
> ....
> Ich nutze diesen Java-Editor



Welche Variationen denn???
Wie soll uns dein Editor weiterhelfen?

Also mit etwas Eigeninitiative hättest du auch selbst drauf kommen können! :noe:

Das ist ein Copy-Past Fehler drin!
new AudioFormat muss natürlich für 2 Kanäle instanziert werden.
Für ganz Langsame: 2. Zeile des folgenden codes


```
public void play(int frequenzyLeft, int  frequencyRight) {
        AudioFormat af = new AudioFormat(44100, 16, 2, true, false);
        byte[] data = getStereoSinusTone(frequenzyLeft, frequencyRight, af);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }
```


----------



## Robohac (24. Feb 2011)

Dankeschön!

Jetzt funktioniert das Programm (zumindest der teil) Tadellos.

Hier nocheinmal der Code:

```
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;

public class ToneGeneratorExample {

    public byte[] getMonoSinusTone(int frequency, AudioFormat af) {
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[(int) af.getSampleRate() * sampleSize];
        double step_width = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sample_byte;
            }
            x += step_width;
        }
        return data;
    }

    public byte[] getStereoSinusTone(int frequency1, int frequency2, AudioFormat af) {
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[(int) af.getSampleRate() * sampleSize  * 2];
        double stepWidth = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize * 2) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency1 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sampleByte;
            }
            value = (int) (sample_max_value * Math.sin(frequency2 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                int index = i + j + sampleSize;
                data[index] = sampleByte;
            }
            x += stepWidth;
        }
        return data;
    }

    public void play(int frequenzy) {
        AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
        byte[] data = getMonoSinusTone(frequenzy, af);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

 public void play(int frequenzyLeft, int  frequencyRight) {
        AudioFormat af = new AudioFormat(44100, 16, 2, true, false);
        byte[] data = getStereoSinusTone(frequenzyLeft, frequencyRight, af);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ToneGeneratorExample tge = new ToneGeneratorExample();
        if (args.length == 1) {
            tge.play(Integer.parseInt(args[0]));
        } else if (args.length == 2) {
            tge.play(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
        } else {
            tge.play(500);
            tge.play(500, 1300);
        }
    }
}
```

Ich werde wenn das Komplette Programm vertig ist es hier auchnoch irgendwie Hochstellen.


Danke für die Hilfe

Robohac


----------



## Robohac (25. Feb 2011)

Hallo, Ich habe mir jetzt eine Grafische Oberfläche gebastelt, in die ich das Programm eingefügt habe.
Leider funktioniert der Tongenerator jetzt nichtmehr, ich weiß aber nicht warum. Es währe nett wenn ihr mir helfen könntet.

Das Programm:

```
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;




//Fenstergenerierung
public class ToneGeneratorExample extends Frame {
  // Anfang Attribute

  private TextField textField1 = new TextField();
  private TextField textField2 = new TextField();
  private TextField textField3 = new TextField();
  private Label label1 = new Label();
  private Label label2 = new Label();
  private Label label3 = new Label();
  private Button button1 = new Button();
  private Button button2 = new Button();
  // Ende Attribute

  public ToneGeneratorExample(String title) {
    // Frame-Initialisierung
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { dispose(); }
    });
    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    Panel cp = new Panel(null);
    add(cp);
    // Anfang Komponenten


    textField1.setBounds(16, 56, 129, 24);
    textField1.setText("500");
    cp.add(textField1);
    textField2.setBounds(160, 56, 113, 24);
    textField2.setText("500");
    cp.add(textField2);
    textField3.setBounds(24, 160, 161, 24);
    textField3.setText("40");
    cp.add(textField3);
    label1.setBounds(16, 16, 47, 16);
    label1.setText("Frequenz links");
    label1.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label1);
    label2.setBounds(160, 16, 47, 16);
    label2.setText("Frequenz rechts");
    label2.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label2);
    label3.setBounds(24, 120, 47, 16);
    label3.setText("Länge (70-1)");
    label3.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label3);
    button1.setBounds(16, 224, 121, 33);
    button1.setLabel("Start");
    button1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button1_ActionPerformed(evt);
      }
    });
    cp.add(button1);
    button2.setBounds(144, 224, 121, 33);
    button2.setLabel("Ende");
    button2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button2_ActionPerformed(evt);
      }
    });
    cp.add(button2);
    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }
  
    public byte[] getMonoSinusTone(int frequency, AudioFormat af) {
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[(int) af.getSampleRate() * sampleSize];
        double step_width = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sample_byte;
            }
            x += step_width;
        }
        return data;
    }

    public byte[] getStereoSinusTone(int frequency1, int frequency2, AudioFormat af, int laenge) {     // laenge kann man ändern  max 70 min 1
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[((int) af.getSampleRate() * sampleSize  * 10) / laenge];
        double stepWidth = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize * 2) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency1 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sampleByte;
            }
            value = (int) (sample_max_value * Math.sin(frequency2 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                int index = i + j + sampleSize;
                data[index] = sampleByte;
            }
            x += stepWidth;
        }
        return data;
    }

    public void play(int frequenzy) {
        AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
        byte[] data = getMonoSinusTone(frequenzy, af);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

    public void play(int frequenzyLeft, int  frequencyRight, int laenge) {      // laenge kann man ändern  max 70 min 1
        AudioFormat af = new AudioFormat(44100, 16, 2, true, false);
        byte[] data = getStereoSinusTone(frequenzyLeft, frequencyRight, af, laenge);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

  // Anfang Methoden
  public boolean button1_ActionPerformed(ActionEvent evt) {
     String left = textField1.getText();
     String right = textField2.getText();
     String laenge = textField3.getText();
     boolean i = true;
     return(i);
  }


  public void button2_ActionPerformed(ActionEvent evt) {
    System.exit(-1);
  }

  // Ende Methoden

  public static void main(String[] args) {
    new ToneGeneratorExample("ToneGeneratorExample");
    boolean i = false;
    int left = 1;
    int right = 1;
    int laenge = 1;
    while(true) {
      if (i = true) {
       ToneGeneratorExample tge = new ToneGeneratorExample();
        if (args.length == 1) {
            tge.play(String.parseInt(args[0]));
        } else if (args.length == 3) {
            tge.play(String.parseInt(args[0]), String.parseInt(args[1]), String.parseInt(args[2]));
        } else {
            tge.play(left, right, laenge);
        }
      }
    }

  }
}
```

und die Fehler die der Compiler ausspuckt:

```
Compiliere C:\Users\Sebastian\Desktop\ToneGeneratorExample.java mit Java-Compiler
ToneGeneratorExample.java:187:35: cannot find symbol
symbol  : constructor ToneGeneratorExample()
location: class ToneGeneratorExample
       ToneGeneratorExample tge = new ToneGeneratorExample();
                                  ^
ToneGeneratorExample.java:189:28: cannot find symbol
symbol  : method parseInt(java.lang.String)
location: class java.lang.String
            tge.play(String.parseInt(args[0]));
                           ^
ToneGeneratorExample.java:191:28: cannot find symbol
symbol  : method parseInt(java.lang.String)
location: class java.lang.String
            tge.play(String.parseInt(args[0]), String.parseInt(args[1]), String.parseInt(args[2]));
                           ^
ToneGeneratorExample.java:191:54: cannot find symbol
symbol  : method parseInt(java.lang.String)
location: class java.lang.String
            tge.play(String.parseInt(args[0]), String.parseInt(args[1]), String.parseInt(args[2]));
                                                     ^
ToneGeneratorExample.java:191:80: cannot find symbol
symbol  : method parseInt(java.lang.String)
location: class java.lang.String
            tge.play(String.parseInt(args[0]), String.parseInt(args[1]), String.parseInt(args[2]));
                                                                               ^
5 errors
```


----------



## Robohac (25. Feb 2011)

Die Oberfläche beschränkt sich auf drei Eingabefelder und zwei Buttons, aber trotzdem find ich iwie nicht den Fehler.


----------



## Robohac (26. Feb 2011)

Ich konnte die Fehler auf einen reduzieren:


```
import java.awt.*;
import java.awt.event.*;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;

import javax.swing.*;
import javax.swing.event.*;


//Fenstergenerierung
public class ToneGeneratorExample extends Frame {
  // Anfang Attribute
  private TextField textField1 = new TextField();
  private TextField textField2 = new TextField();
  private TextField textField3 = new TextField();
  private Label label1 = new Label();
  private Label label2 = new Label();
  private Label label3 = new Label();
  private Button button1 = new Button();
  private Button button2 = new Button();

  // Ende Attribute
  public ToneGeneratorExample(String title) {
    // Frame-Initialisierung
    super(title);
    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent evt) {
          dispose();
        }
      });

    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);

    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);

    Panel cp = new Panel(null);
    add(cp);
    // Anfang Komponenten
    textField1.setBounds(16, 56, 129, 24);
    textField1.setText("500");
    cp.add(textField1);
    textField2.setBounds(160, 56, 113, 24);
    textField2.setText("500");
    cp.add(textField2);
    textField3.setBounds(24, 160, 161, 24);
    textField3.setText("40");
    cp.add(textField3);
    label1.setBounds(16, 16, 47, 16);
    label1.setText("Frequenz links");
    label1.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label1);
    label2.setBounds(160, 16, 47, 16);
    label2.setText("Frequenz rechts");
    label2.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label2);
    label3.setBounds(24, 120, 47, 16);
    label3.setText("Länge (70-1)");
    label3.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
    cp.add(label3);
    button1.setBounds(16, 224, 121, 33);
    button1.setLabel("Start");
    button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
          button1_ActionPerformed(evt);
        }
      });
    cp.add(button1);
    button2.setBounds(144, 224, 121, 33);
    button2.setLabel("Ende");
    button2.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
          button2_ActionPerformed(evt);
        }
      });
    cp.add(button2);
    // Ende Komponenten
    setResizable(false);
    setVisible(true);
  }

  public byte[] getMonoSinusTone(int frequency, AudioFormat af) {
    byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
    byte[] data = new byte[(int) af.getSampleRate() * sampleSize];
    double step_width = (2 * Math.PI) / af.getSampleRate();
    double x = 0;

    for (int i = 0; i < data.length; i += sampleSize) {
      int sample_max_value = ((int) Math.pow(2, af.getSampleSizeInBits()) / 2) -
                             1;
      int value = (int) (sample_max_value * Math.sin(frequency * x));

      for (int j = 0; j < sampleSize; j++) {
        byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
        data[i + j] = sample_byte;
      }

      x += step_width;
    }

    return data;
  }

  public byte[] getStereoSinusTone(int frequency1, int frequency2,
                                   AudioFormat af, int laenge) { // laenge kann man ändern  max 70 min 1

    byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
    byte[] data = new byte[((int) af.getSampleRate() * sampleSize * 10) / laenge];
    double stepWidth = (2 * Math.PI) / af.getSampleRate();
    double x = 0;

    for (int i = 0; i < data.length; i += (sampleSize * 2)) {
      int sample_max_value = ((int) Math.pow(2, af.getSampleSizeInBits()) / 2) -
                             1;
      int value = (int) (sample_max_value * Math.sin(frequency1 * x));

      for (int j = 0; j < sampleSize; j++) {
        byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
        data[i + j] = sampleByte;
      }

      value = (int) (sample_max_value * Math.sin(frequency2 * x));

      for (int j = 0; j < sampleSize; j++) {
        byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
        int index = i + j + sampleSize;
        data[index] = sampleByte;
      }

      x += stepWidth;
    }

    return data;
  }

  public void play(int frequenzy) {
    AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
    byte[] data = getMonoSinusTone(frequenzy, af);

    try {
      Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
      c.open(af, data, 0, data.length);
      c.loop(1);

      while (c.isRunning()) {
        try {
          Thread.sleep(50);
        } catch (Exception ex) {
        }
      }
    } catch (LineUnavailableException ex) {
      ex.printStackTrace();
    }
  }

  public void play(int frequenzyLeft, int frequencyRight, int laenge) { // laenge kann man ändern  max 70 min 1

    AudioFormat af = new AudioFormat(44100, 16, 2, true, false);
    byte[] data = getStereoSinusTone(frequenzyLeft, frequencyRight, af, laenge);

    try {
      Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
      c.open(af, data, 0, data.length);
      c.loop(1);

      while (c.isRunning()) {
        try {
          Thread.sleep(50);
        } catch (Exception ex) {
        }
      }
    } catch (LineUnavailableException ex) {
      ex.printStackTrace();
    }
  }

  // Anfang Methoden
  public boolean button1_ActionPerformed(ActionEvent evt) {
    String left = textField1.getText();
    String right = textField2.getText();
    String laenge = textField3.getText();
    boolean i = true;

    return (i);
  }

  public void button2_ActionPerformed(ActionEvent evt) {
    System.exit(-1);
  }

  // Ende Methoden
  public static void main(String[] args) {
    ToneGeneratorExample tge = new ToneGeneratorExample();
    boolean i = false;
    int left = 1;
    int right = 1;
    int laenge = 1;

    while (true) {
      if (i = true) {
        if (args.length == 1) {
          tge.play(Integer.parseInt(args[0]));
        } else if (args.length == 3) {
          tge.play(Integer.parseInt(args[0]), Integer.parseInt(args[1]),
                   Integer.parseInt(args[2]));
        } else {
          tge.play(left, right, laenge);
        }
      }
    }
  }
}
```


```
Compiliere C:\Users\Sebastian\Desktop\Java\ToneGeneratorExample.java mit Java-Compiler
ToneGeneratorExample.java:187:35: cannot find symbol
symbol  : constructor ToneGeneratorExample()
location: class ToneGeneratorExample
       ToneGeneratorExample tge = new ToneGeneratorExample();
                                  ^
1 error
```


----------



## HoaX (26. Feb 2011)

Steht doch da, es gibt den Konstruktor nicht, welchen du aufrufst.



> ToneGeneratorExample.java:187:35: cannot find symbol
> symbol  : constructor ToneGeneratorExample()


----------



## Robohac (26. Feb 2011)

Das Problem ist aber, dass das Programm mit exakt dem Greichen Aufruf schon mal funktioniert hat, und ich schon nach Kopy/Paste fehlern gesucht habe, aber keine gefunden habe!


----------



## Robohac (28. Feb 2011)

Hy,

ich wer die Fehler iwie net los. Hier eine andere Version mit ner Checkbox als Startknopf, von der ich eigentlich gedacht hätte es wäre einfacher.


```
import java.awt.*;
import java.awt.event.*;
import javax.sound.sampled.Clip;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFormat;
/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 28.02.2011
  * @author
  */

public class Tonegenerator_final extends Frame {
  // Anfang Attribute
  private TextField textField1 = new TextField();
  private TextField textField2 = new TextField();
  private TextField textField3 = new TextField();
  private Button button2 = new Button();
  private Checkbox checkbox1 = new Checkbox();
  // Ende Attribute

  public Tonegenerator_final(String title) {
    // Frame-Initialisierung
    super(title);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) { dispose(); }
    });
    int frameWidth = 300;
    int frameHeight = 300;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    Panel cp = new Panel(null);
    add(cp);
    // Anfang Komponenten

    textField1.setBounds(16, 56, 129, 24);
    textField1.setText("500");
    cp.add(textField1);
    textField2.setBounds(152, 56, 121, 24);
    textField2.setText("500");
    cp.add(textField2);
    textField3.setBounds(32, 136, 145, 24);
    textField3.setText("35");
    cp.add(textField3);
    button2.setBounds(144, 216, 121, 33);
    button2.setLabel("Exit");
    button2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        button2_ActionPerformed(evt);
      }
    });
    cp.add(button2);
    checkbox1.setBounds(24, 224, 97, 17);
    checkbox1.setLabel("Start");
    cp.add(checkbox1);
    // Ende Komponenten

    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  
    public byte[] getMonoSinusTone(int frequency, AudioFormat af) {
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[(int) af.getSampleRate() * sampleSize];
        double step_width = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sample_byte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sample_byte;
            }
            x += step_width;
        }
        return data;
    }

    public byte[] getStereoSinusTone(int frequency1, int frequency2, AudioFormat af, int laenge) {     // laenge kann man ändern  max 70 min 1
        byte sampleSize = (byte) (af.getSampleSizeInBits() / 8);
        byte[] data = new byte[((int) af.getSampleRate() * sampleSize  * 10) / laenge];
        double stepWidth = (2 * Math.PI) / af.getSampleRate();
        double x = 0;
        for (int i = 0; i < data.length; i += sampleSize * 2) {
            int sample_max_value = (int) Math.pow(2, af.getSampleSizeInBits()) / 2 - 1;
            int value = (int) (sample_max_value * Math.sin(frequency1 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                data[i + j] = sampleByte;
            }
            value = (int) (sample_max_value * Math.sin(frequency2 * x));
            for (int j = 0; j < sampleSize; j++) {
                byte sampleByte = (byte) ((value >> (8 * j)) & 0xff);
                int index = i + j + sampleSize;
                data[index] = sampleByte;
            }
            x += stepWidth;
        }
        return data;
    }

    public void play(int frequenzy) {
        AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
        byte[] data = getMonoSinusTone(frequenzy, af);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

    public void play(int frequenzyLeft, int  frequencyRight, int laenge) {      // laenge kann man ändern  max 70 min 1
        AudioFormat af = new AudioFormat(44100, 16, 2, true, false);
        byte[] data = getStereoSinusTone(frequenzyLeft, frequencyRight, af, laenge);
        try {
            Clip c = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            c.open(af, data, 0, data.length);
            c.loop(1);
            while(c.isRunning()) {
                try {
                    Thread.sleep(50);
                } catch (Exception ex) {}
            }
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
    }

  


  public void button2_ActionPerformed(ActionEvent evt) {
    System.exit(-1);
  }

  // Ende Methoden

  public static void main(String[] args) {
    new Tonegenerator_final("Tonegenerator_final");
    boolean checkbox = false;
    
    while(true) {
      if (checkbox1.checked == true) {
        ToneGeneratorExample2 tge = new ToneGeneratorExample2();
        if (args.length == 1) {
            tge.play(Integer.parseInt(args[0]));
        } else if (args.length == 3) {
            tge.play(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
        } else {
            tge.play(500);
            tge.play(500, 1000, 1);
            tge.play(500, 1000, 70);
        }
      }
    }

  }
}
```

Un natürlich meine besten Freunde: Die Fehler

```
Compiliere C:\Users\Sebastian\Desktop\Java\Tonegenerator_final.java mit Java-Compiler
Tonegenerator_final.java:158:11: non-static variable checkbox1 cannot be referenced from a static context
      if (checkbox1.checked == true) {
          ^
Tonegenerator_final.java:158:20: cannot find symbol
symbol  : variable checked
location: class java.awt.Checkbox
      if (checkbox1.checked == true) {
                   ^
2 errors
```


----------



## Woodstock (1. Mrz 2011)

Hallo,

wer hat dir denn gesagt, dass die Klasse 
	
	
	
	





```
Checkbox
```
 ein öffentliches Feld 
	
	
	
	





```
checked
```
 hat?

Laut API könntest du es mal mit der Methode 
	
	
	
	





```
getState()
```
 probieren...


----------



## raegten (1. Mrz 2011)

wenn du schon eine Instanz von Tonegenerator_final erzeugst, dann würd ich sie auch verweden. du kannst nicht aus der statischen main methode auf die Instanzvariablen zugreifen, sondern nur über die Referenz der Instanz selbst.

```
Tonegenerator_final.java:158:11: non-static variable checkbox1 cannot be referenced from a static context
```
sagt eigentlich eh alles.


```
public static void main(String[] args) {
    final Tonegenerator_final tge = new Tonegenerator_final("Tonegenerator_final");
    boolean checkbox = false;
    
    while(true) {
      if (tge.checkbox1.getState() == true) {       
        if (args.length == 1) {
            tge.play(Integer.parseInt(args[0]));
        } else if (args.length == 3) {
            tge.play(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
        } else {
            tge.play(500);
            tge.play(500, 1000, 1);
            tge.play(500, 1000, 70);
        }
      }
    } 
  }
```


----------

