Frequenzen vom Mikrofon bestimmen

Poehli

Mitglied
Hallo,
ich bin schon seit mehreren Tagen auf der Suche nach dem Thema, wie ich es hinbekomme Frequenzen aus meinem Mikro zu erhalten. Ich habe Grundlegende Kenntnisse im Audiobereich, weiß über Samples bescheid und hab von FFT gelesen (Versuche es zu verstehen, sobald sich mir erschließt wofür ich das brauche). Ein kleines Programm, was aufgenommenes Audio speichert konnte ich schreiben und verstehen:
Java:
public class AudioTest {
	AudioFormat format;
	TargetDataLine targetDataLine;
	public AudioTest() {

		format = new AudioFormat(8000.0F, 16, 1, true, false);

		DataLine.Info dataLineInfo =
			new DataLine.Info(
					TargetDataLine.class,
					format);
		try {
			targetDataLine = (TargetDataLine)
			AudioSystem.getLine(dataLineInfo);

			System.out.println("start");
			long time = System.currentTimeMillis();
			new CaptureThread().start();
			while (time + 3000 > System.currentTimeMillis())
				try {
					Thread.sleep(100);
				} catch (Exception e) {
					// TODO: handle exception
				}
				System.out.println("done rec");
				targetDataLine.stop();
				targetDataLine.close();
		} catch (LineUnavailableException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	class CaptureThread extends Thread{

		@Override
		public void run(){
		try {
			targetDataLine.open(format);
			targetDataLine.start();
			AudioInputStream istream = new AudioInputStream(targetDataLine);
			AudioSystem.write(istream, AudioFileFormat.Type.WAVE, new File("test.wav"));
			
		} catch (LineUnavailableException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
	}

	public static void main (String[] args){
		new AudioTest();
	}
(Keine Weltneuheit, aber es funktioniert)
Leider verstehe ich absolut nicht, mit welchen Hilfsmitteln die Frequenzen herauszufinden sind.

Wie bekomme ich die Samples, mit denen ich weiterarbeiten kann?
Wofür brauche ich die FFT?
Und was für Frequenzen bekommt man (Long, Double oder was auch immer)

Ich weiß, dass dies ein nicht zu unterschätzendes Thema ist, wäre trotzdem nett, wenn ihr mir dabei helfen könntet.
Vielen Dank
Pöhli
 
Zuletzt bearbeitet:
Hi

was willst du denn am Ende eigentlich erreichen?

Hier drei Bilder im Post:
http://www.tutorials.de/c-c/155796-frequenzen-2.html#post2004125

Bild 3 sind Sampledaten als graphisches Diagramm.
Die bekommt man vom Mikrofon, die wollen Wiedergabegeräte zur Wiedergabe,
und die sind (als Array von irgendwelchen Kommazahlen) alles, was man braucht,
um Musik als Datei etc. zu speichern.
Mit bestimmten Komprimierungsverfahren und einigen anderen Kleinigkeiten
hat man Formate wie MP3, Ogg usw.

Fouriertransformation ist ein math. Verfahren, um diese Sampledaten
in die vielen einzelnen Schwingungen (wie Bild 1 und 2) zu zerlegen.
FFT (Fast F.T.) ist eine computermäßig relativ schnelle Methode zur Berechnung.

(warum wollen eigentlich immer mehr Leute eine FT auf Audiodaten machen?)
 
Ich habe als Hobby noch HIFI und allgemein Musik. Demanch ist es naheliegend diese beiden Bereiche zu verbinden ;)

Mein eigentlicher Wunsch ist es eine Art Stimmgerät für ein X-Beliebiges Instrument zu schreiben.
Da jeder Ton eine eigene festgelegte Frequenz hat, liegt es Nahe, diese herauszufinden. Komprimierung ist erstmal nebensache und auch das speichern wird nicht nötig sein. Dieser Code zeigt nur meine bisheren Kenntnisse im Bereich Audioprogrammierung. Und da ich es liebe Algorythmen zu entwerfen und verstehen, lag es Nahe kein vorhandenes Programm zu verwenden (mal abgesehen davon, dass ich keins gefunden habe ;) ).
(Wenn ich jetzt falsch liege korrigiert micht bitte:)
Ein Gesampeltes Audioformat besteht doch, wie der Name schon sagt aus einzelnen Samples, also Punkten auf dem Graphen der Audiowelle, wenn man das so beschreiben kann. Demnach müssten diese doch die Dezibel des Punktes angeben. Um nun die Frequenz zu bestimmen, müssten die jeweiligen Maxima bestimmt werden (z.B. über ableiten oder andere Prüfverfahren). Dafür müsste ich jedoch die Samples erst einmal bestimmen können. Deshalb versuche ich herzufinden, wie man die einzelnen Samples auslesen kann.

Ich hätte gedacht, dass relativ häufig die Frequenz gebraucht wird und dehalb in irgendeiner API steht, die ich trotz ewig langem Suchen nicht gefunden habe. Das scheint offensichtlich nicht der Fall zu sein, womit nur noch die Frage des Samples bleibt ;)
Vielen Dank schonmal, für die schnelle Antwort :)
 
Also FFT brauchst du um Frequenzen aus einem Gemisch herauszufiltern - wobei der FFT Filter eine Bandbreite besitzt - sprich ist entsprechend ungenau.

Wenn du aber Stimmen willst hast du den Vorteil das du nur einen gegeben Ton hast - sprich nur eine Frequenz.
Da (denke ich) Würde sich anbieten aus der Eingangsfrequenz den Nulldurchgang zu bestimmen.
Also aus deinem Stream ermittelen wann genau der kleinste Eingangspegel vorhanden ist = Nulldurchgang.

Zu den Samples - da scheint es wirklich nichts zu geben was fertig ist :)
da mache ich mir auch im Moment Gedanken wie man das Javatechnisch umsetzen kann.

Es gibt ja ettlichen Codierungsmöglichkeiten, auch wenn man sich auf PCM einschränkt.
8/16/24 Bit
Mono / Stereo
erst Lo dann Hi Part oder umgekehrt wenn man mit mehr wie 8 bit arbeitet.

mal kucken wie weit ich komme :)
 
Zuletzt bearbeitet:
Hi

(warum wollen eigentlich immer mehr Leute eine FT auf Audiodaten machen?)

weils geht :)
Nee spass beiseite - ich möchte einfach mal sehen wie brauchbar solche ergebnisse sind wenn man mit FFT arbeitet
und wenn nur am Ende Eine Classe rauskommt die ein Equalizer für Swing bereitstellt - ist dat nix :)

EDIT:
Ich verstehe nicht woher die Info kommen soll das vom Micro aufgenommen wird - ich habe schon andre Beispiele gesehen aber ich verstehe das nicht - wo wird die Info übergeben welcher Eingang benutzt wird
 
Zuletzt bearbeitet:
Ja genau das hab ich mir auch gedacht melmager, aber wie bekommt man denn den eingangspegel?
Dann würde ich ja auch selbst versuchen damit weiterzuarbeiten, aber ohne den komme ich nicht voran.
Was genauch macht denn eigentlich die read() Methode von TargetDataLine, bzw AudioInputStream? Was kann ich mit den Bytes anfangen, bzw. was repräsentieren die? Ich werd aus der API leider nicht schlau....
Vielen Danke, schonmal :)
 
Die Bytes sind deine Samples - wobei es auf die Codierung ankommt wie die Daten ankommen.
mal gesetzt den einfachen Fall du nimmst ein Auflösung von 8 bit und MONO dann ist ein Sample genau ein Byte gross, bei 16 Bit auflösung, und Stereo brauchst für ein Sample 4 bytes.

Code:
int samplesize = 1;
byte block[] = new byte[samplesize];
// sound ist hier dein AudioInputStream
int rc = sound.read(block,0,samplesize);

jetz muss daraus ein int gemacht werden (Achtung es gibt Werte mit oder ohne Vorzeichen!)

Code:
int value = block[0]; // nimmt Vorzeichen mit

jetzt sollte man ein Samplewert haben. Gesetzt den Fall du hast nur ein Ton (am besten Sinus)
dann kann man die Frequenz dadurch ermitteln das man die Anzahl der Null durchgänge zählt im vorgegeben Zeitraum. Sprich Messung 1 sekunde -> 880 Durchgänge = 440 Hz

Code:
int messzeitraum = 8000; //samplerate 8000 = 1 sec
int null = 0; // samlewert von Null
boolean plus = true; // true bei positiver Schwingung 
int count = 0; // unser Zähler
for (int lo=0; lo < messzeitraum; lo++) {
 while (sound.available() <= samplesize) {//warte bis genug daten vorhanden
   // hier ev ein kleinen sleep rein
 } 
 // hole werte siehe oben!
 if ((value > null) ^ plus) { // test ob wechsel der Schwingung 
  plus = value > null;
  count++;
 }
}

alles theoretisch und ungetestet !!

Der Nullwert deiner Samples kommt auch auf die Codierung an - immer noch bei 8 Bit
ist der Null wert bei Werten mit Vorzeichen bei 0 da werte zwischen 127 und -127 liegen
bei Werten ohne Vorzeichen (hier im Coden nicht ausgewertet) liegt der Wert zwischen 0 und 254 daher ist da der nullwert 127.

Link: http://wiki.multimedia.cx/index.php?title=PCM

Oder noch ne Möglichkeit Frequenz ungefähr zu bestimmen:
Warte auf Wechel von Negativ auf Positiv Werte ;
zähle die Samples bis erneuten Wechsel negativ / positiv;
rechnen :)

das ganze Verfahren hier klappt nicht wenn mehrere Frequezen gemischt sind !!
Und dat ganze ist nur eine Näherungsmessung je näher die Messfrequenz der Samplefrequenz ist um so ungenauer wird es!
 
Zuletzt bearbeitet:
Also FFT brauchst du um Frequenzen aus einem Gemisch herauszufiltern - wobei der FFT Filter eine Bandbreite besitzt - sprich ist entsprechend ungenau.
Richtig. Wenn Sampledauer und Samplerate ausreichend groß sind, sollte das kein Problem geben.
Wenn du aber Stimmen willst hast du den Vorteil das du nur einen gegeben Ton hast - sprich nur eine Frequenz.
Da (denke ich) Würde sich anbieten aus der Eingangsfrequenz den Nulldurchgang zu bestimmen.
Also aus deinem Stream ermittelen wann genau der kleinste Eingangspegel vorhanden ist = Nulldurchgang.
Nulldurchgang bringt dir überhaupt nichts, weil er durch Schwingungen anderer Frequenzen beliebig verzerrt/verschoben werden kann. FFT ist auf jeden Fall der richtige Ansatz. In der Praxis setzt man das so um, dass man die FFT per Formel/DSP berechnet und dann im Frequenzspektrum nach Peaks/Maxima sucht. Der höchste Peak liegt bei der Frequenz, bei der der Ton mit der höchsten Intensität schwingt, d.h. bei der stärksten Schwingung.
 
Ein Gesampeltes Audioformat besteht doch, wie der Name schon sagt aus einzelnen Samples, also Punkten auf dem Graphen der Audiowelle, wenn man das so beschreiben kann. Demnach müssten diese doch die Dezibel des Punktes angeben. Um nun die Frequenz zu bestimmen, müssten die jeweiligen Maxima bestimmt werden (z.B. über ableiten oder andere Prüfverfahren). Dafür müsste ich jedoch die Samples erst einmal bestimmen können. Deshalb versuche ich herzufinden, wie man die einzelnen Samples auslesen kann.
Ableiten wäre viel zu aufwändig, weil du die Funktion selbst ja nicht kennst, sondern nur approximieren kannst. Um das tatsächlich mit Ableitungen oder ähnlichen mathematischen Verfahren umzusetzen, solltest du fortgeschrittene Kentnisse in numerischen Verfahren mitbringen…
 
Nulldurchgang bringt dir überhaupt nichts, weil er durch Schwingungen anderer Frequenzen beliebig verzerrt/verschoben werden kann. FFT ist auf jeden Fall der richtige Ansatz. In der Praxis setzt man das so um, dass man die FFT per Formel/DSP berechnet und dann im Frequenzspektrum nach Peaks/Maxima sucht. Der höchste Peak liegt bei der Frequenz, bei der der Ton mit der höchsten Intensität schwingt, d.h. bei der stärksten Schwingung.

Stimmt da ist das problem .. ich weiss ja nicht wie ein Gitarrensound (Beispiel) aussieht aber wenn der Sound durch eine andre Frequenz überlagert wird dann fällt mein Messverfahren aus - ich gehe vom Sinus aus ...

sobald ich rausgefunden habe wie man die Quelle festlegt schreibe ich erstmal ein programm das mir die samples ausgibt um mal zu sehen wie die werte aussehen :)
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück