Sound-Sampling: Sinuston; kein Fehler, aber auch kein Ton :-(

Goldi

Aktives Mitglied
Hallo zusammen,

die Literatur und das Internet konnten mir bisher nicht weiterhelfen, weil es doch wohl ein sehr spezielles Thema ist. Ich brauche Unterstützung von jemandem, der sich im Sound-Sampling auskennt. Was mache ich falsch? Die Kiste gibt zwar keinen Fehler aus, aber hören tut man auch nix. Ich bin mir hinsichtlich der zahlreichen Parameter, die es beim Sound-Sampling gibt, aber auch noch nicht so 100-%-ig sicher - mangels Literatur ;-). Ich habe mal ein möglichst knappes Programm geschrieben, das natürlich auch nicht funktioniert, und möchte gerne wissen, was falsch ist. Bitte um Hilfe!

Java:
import java.io.*;
import javax.sound.sampled.*;

public class Sinuston {

	// Meine Parameter:
	float frequenz = 558.15f; 			// Frequenz des Sinustons in Hz (ungefähr ein "cis")
	float mySampleRate = 44100f; 		// Frequenz des Samplings in Hz
	int mySampleSizeInBits = 16;		// Auflösung der Abtastung; ein Sample umfasst 16 Bit = 2 Byte.
	int myChannels = 2;					// Ich mags Stereo
	int myFrameSizeInByte = (int)(mySampleSizeInBits / 2 * myChannels);
	int amplitude = 30000;				// Entspricht der Lautstärke; eine "Verstärkung" des y-Wertes der Sinus-
										// Funktion
	float myFrameRate = mySampleRate;   // Java: "The number of frames played or recorded per second"
	boolean myBigEndian = false;		// Die Bedeutung des "Big-Endian" oder "Little-Endian" in diesem Kontext
										// ist mir noch unklar!!
	
	
	// Liefert die Sampling-Daten eines Sinustons in Form eines Byte-Streams zurück:
	public ByteArrayOutputStream SinusDaten() {
		
		ByteArrayOutputStream oByteReihe = new ByteArrayOutputStream();
		
		/* Errechnet zu jedem Zeitpunkt eines Samples (Bruchteil einer Sekunde) den Sinuswert. Mathematisch 
		   betrachtet: Sinus = Winkelfunktion; Eine Sinuskurve ist vollständig abgelaufen, wenn quasi der Einheits-
		   kreis (r = 1) einmal umrundet ist, beginnend bei Bogenmaß = 0, endendend bei Bogenmaß = Kreißumfang = 
		   2 x r x Pi = 2 x 1 x Pi = 2 x Pi. Der Einheitskreis muss 558,15 Mal pro Sekunde umrundet werden (= Frequenz: 
		   558,15 Hz). 1 Umrundung dauert 1/558,15 sec. Frage: Welcher Sinuswert besteht bei z. B. einer 3/44100 sec.
		   (3. Abtastpunkt)?
		 */
		
		double BMBruchteil = (double)(frequenz / mySampleRate); // BMBruchteil = Bogenmaßbruchteil pro Sample (0,0127)
													 // Umkehrschluss: 1 Sinusschwingung hat 0,0127 x 558,15 Hz 
													 // = ca. 7 Abtastpunkte (Samples).
		double Kreisumfang = (float)(Math.PI * 2);	 // entspr. 360° = 1 abgeschlossene Sinuskurve; siehe Mathe-Buch ;-).
		double Bogenmass = 0;
		double Sinus;
		
		for (int i = 0; i <= mySampleRate; i = i++) {
			Sinus = (Math.sin(Bogenmass)) * amplitude;
			
			// Schreibe an den ByteStream:
			oByteReihe.write((byte)Sinus);
			// Schreibe den 2. Byte:
			oByteReihe.write((byte)Sinus >>> 8);
			
			// Für nächsten Abtastpunkt:
			Bogenmass = Bogenmass + Kreisumfang * BMBruchteil;
		}
		
		return oByteReihe;
	}
	
	
	public void SinusTonAbspielen() {
		
		// Definiere ein Audio-Format:
		AudioFormat aif = new AudioFormat(
				AudioFormat.Encoding.PCM_SIGNED, 	// empfohlen in einem Buch
				mySampleRate, 						// 44100
				mySampleSizeInBits, 				// 16 Bit
				myChannels, 						// 2 = Stereo
				myFrameSizeInByte, 					// 4, resultierend aus SampleSizeInBits und Channels
				myFrameRate,						// 44100
				myBigEndian);						// false; empfohlen in einem Buch
		
		// Für den Sinuston einen Audio-Inputstream:
		ByteArrayOutputStream bos = SinusDaten();
		InputStream is = new ByteArrayInputStream(bos.toByteArray());
		AudioInputStream ais = new AudioInputStream(is, aif, bos.size() / aif.getFrameSize());
		
		// Jetzt brauche ich eine Line, ...
		DataLine.Info myDataLineInfo = new DataLine.Info(Clip.class, aif);
		
		// ... die ich auf einen Clip caste:
		Clip myClip = null;
		try {
			myClip = (Clip)AudioSystem.getLine(myDataLineInfo);
		} catch (LineUnavailableException e) {
			System.out.println("Line mag nicht auf Clip!");
			System.exit(0);
		}
		
		// Jetzt wrid's ernst: Der Clip soll abgespielt werden:
		try {
			myClip.open(ais);
		} catch (LineUnavailableException e) {
			System.out.println("Der Clip mag nicht (LineUnavailableException)!");
		} catch (IOException e) {
			System.out.println("Der Clip mag nicht (IOException)");
		}
	}
	
	
	public static void main(String[] args) {
		Sinuston st = new Sinuston();
		st.SinusTonAbspielen();
	}
}
 

Goldi

Aktives Mitglied
Ich habe mittlerweile selbst was entdeckt - aber leider das Problem nicht gelöst. Also, um Euch die Mühe zu sparen, darauf noch einzugehen, hier 3 kleine Änderungen des Codes:

Mit ner Endlosschleife vor dem Clip kanns natürlich keinen Ton geben - peinlich :applaus::
[JAVA=39](int i = 0; i <= mySampleRate; i++)[/code]

Die Formel für die Frame-Rate war natürlich falsch (zumindest für mein Verständnis, aber was weiß ich vom Sound-API :-():
[JAVA=11]int myFrameSizeInByte = (int)(mySampleSizeInBits / 8 * myChannels);[/code]

Und dann dachte ich mir, ich veersuchs noch mit einem Loop, der das Sampling ein paar mal abspielt:
[JAVA=85]try {
myClip.open(ais);
myClip.loop(2);
} catch (LineUnavailableException e)
usw.[/code]

Hat nur alles nix gebracht: Keine Fehlermeldung, aber auch kein Ton. Ich hoffe nach wie vor auf jemanden, der mir da ein bisschen Licht in das Dunkel meiner Verzweiflung bringt :rtfm:.

Besten Dank schon mal und schöne Grüße
Goldi
 
Zuletzt bearbeitet:

rme

Top Contributor
Hallo,

ein Problem ist, dass du nicht auf das Ende des Abspielen wartest. Der Ton wird nebenläufig abgespielt, d.h. dein Programm blockiert nicht während des Abspielens - stattdessen wird es beendet, weil main endet. Das lässt sich folgendermaßen beheben:

Java:
// Jetzt wrid's ernst: Der Clip soll abgespielt werden:
try {
    myClip.open(ais);
    myClip.start();
    Thread.sleep(2000);
    ...

Ein anderes Problem ist, dass du den Sinus-Wert auf byte castest - dadurch verlierst du die nötige Größe, denn deine Amplitude geht bis 30.000, byte-Werte werden aber ab 127 abgeschnitten. Die Lösung ist es, erst zu shiften und dann zu casten:

Java:
int data = (int) ((Math.sin(Bogenmass)) * amplitude);

// Schreibe an den ByteStream:
oByteReihe.write(data & 0xFF);
// Schreibe den 2. Byte:
oByteReihe.write((data >> 8) & 0xFF);

Damit wird bei mir ein schöner Ton gespielt, bei dir auch? :)
 

Goldi

Aktives Mitglied
Hi rme!

:toll: Vielen Dank! Das war's!! Ich bin restlos begeistert!!!

Ich habe in der Zwischenzeit noch eine andere Lösung mit einem DataSourceStream und einem Streaming-Verfahren über einen Byte-Puffer gefunden. Das ist natürlich für so kleine Datenmengen umständlich. Jetzt geht beides - viel gelernt :applaus:

Das mit dem Shiften ... Ich sag's ehrlich: Da muss ich mich auch erst mal einlesen, nach dem Mittagessen :popcorn:. Ich habe dazu auch noch eine Lösung gefunden, und zwar mit der java.noi-Bibliothek. Da packe ich den Datenstrom erst in einen Short-Stream (Short = 2 Byte = 16 Bit), der dann in einen Byte-Stream übersetzt wird.

Jedenfalls herzlichen Dank für die Lösung und noch einen schönen Sonntag!

Gruß
Godli

PS: Eine weitere Entdeckung, die ich freilich allen zu Teil werden lassen möchte, die's interessiert: Dick Baldwin hat sehr erschöpfende und gute Tutorials u. a. was das Sound-API angeht - halt in Englisch, da kann man sprachlich auch noch zulegen :idea:. Hier ein Link:
Java and JavaScript Programming, by Richard G Baldwin
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L Sound in Java Spiel Spiele- und Multimedia-Programmierung 5
L Audio-volume /w input Sound.sampled Spiele- und Multimedia-Programmierung 1
D Java sound pulseaudio Spiele- und Multimedia-Programmierung 0
K Sound im loop abspielen, wenn boolscher wert true ist Spiele- und Multimedia-Programmierung 3
M Sound Problem Spiele- und Multimedia-Programmierung 3
M Sound Engin Problem 2 Spiele- und Multimedia-Programmierung 2
J Sound und Musik Spiele- und Multimedia-Programmierung 4
C virtueller stereomix (java sound API) Spiele- und Multimedia-Programmierung 0
I Sound Dateien abspielen Spiele- und Multimedia-Programmierung 9
C Sound einfügen und abspielen Spiele- und Multimedia-Programmierung 6
M Bilderwechsel in Video an Sound anpassen Spiele- und Multimedia-Programmierung 2
A Problem mit Sound Spiele- und Multimedia-Programmierung 5
F Kein Sound bei javazoom Spiele- und Multimedia-Programmierung 2
J Sound einbinden funktioniert nicht Spiele- und Multimedia-Programmierung 13
S Java Sound-API stagniert Spiele- und Multimedia-Programmierung 16
F Einen Sound mit veränderter Tonhöhe und Geschwindigkeit abspielen - Hilfe erbeten Spiele- und Multimedia-Programmierung 29
H Java Sound: WAVE Format17 einlesen. Spiele- und Multimedia-Programmierung 2
Kr0e Java Sound API - DataLine Spiele- und Multimedia-Programmierung 2
S testen ob Sound läuft Spiele- und Multimedia-Programmierung 3
J Windows Sound Aufnehmen Spiele- und Multimedia-Programmierung 10
C Alles hängt, wenn ein Sound abgespielt wird Spiele- und Multimedia-Programmierung 9
K javax.sound.sampled.Clip clone() Spiele- und Multimedia-Programmierung 2
C Java3D Sound spielt nur einen Sound ab. Spiele- und Multimedia-Programmierung 8
G Ortsabhängiger Sound Spiele- und Multimedia-Programmierung 5
T Sound schneller abspielen Spiele- und Multimedia-Programmierung 4
S Java Sound - Skipping in .mp3 Files und Bug (Bitte überprüfenl) Spiele- und Multimedia-Programmierung 14
G Beste Sound Api Spiele- und Multimedia-Programmierung 2
C Java Sound API Clip.Close() Problem Spiele- und Multimedia-Programmierung 1
Zettelkasten Spezialwiedergabe von Sound vorzeitig beenden Spiele- und Multimedia-Programmierung 3
A Sound Amplitude ermitteln bzw Sound auslöschen Spiele- und Multimedia-Programmierung 4
P Sound auf zwei Lautsprechern getrennt abspielen Spiele- und Multimedia-Programmierung 9
G javafx MediaPlayer sound problem Spiele- und Multimedia-Programmierung 2
Developer_X Sound Lautstärke ohne spezifische API regulieren Spiele- und Multimedia-Programmierung 3
M Java Sound API : Zuordnung Port-Mixer zu Input-Mixer Spiele- und Multimedia-Programmierung 9
P Java Sound OutOfMemoryError Spiele- und Multimedia-Programmierung 2
T Java Sound Probleme Spiele- und Multimedia-Programmierung 8
Pithecanthropus Sound geht nicht Spiele- und Multimedia-Programmierung 6
Dragonfire Java Sound API - Lautstärke ändert sich nicht Spiele- und Multimedia-Programmierung 2
N sound absoielen Spiele- und Multimedia-Programmierung 3
DEvent Java sound Bibliothek Spiele- und Multimedia-Programmierung 11
P Sound Datein mit JAVA zusammenstellen?! Spiele- und Multimedia-Programmierung 3
Developer_X Java3D Point Sound Spiele- und Multimedia-Programmierung 71
B sound mit behavior geht nicht Spiele- und Multimedia-Programmierung 4
M Sound-Lösung für Java/JMF Spiele- und Multimedia-Programmierung 8
0 Sound Spiele- und Multimedia-Programmierung 5
S sound zuverlässig wiedergeben Spiele- und Multimedia-Programmierung 15
G Sound Probleme Spiele- und Multimedia-Programmierung 2
D Sound und Bilddateien vorladen Spiele- und Multimedia-Programmierung 7
R Probleme mit Sound in Applikation. HILFE Spiele- und Multimedia-Programmierung 5

Ähnliche Java Themen

Neue Themen


Oben