# Frequenzanalyse



## dergrüne (10. Jun 2009)

Servus,

ich denke jeder kennt Audio surf oder auch Guitar Hero, beide spiele basieren ja im Grunde darauf das sie die Frequenz bzw. die Amplituden der MUsik scannen und die Ergebniss entsprechend weiter verarbeiten.

Jetzt miene Frage kennt jemand freie libs für Java die musik analysieren können und wo man im Grunde was ähnlichen programmieren könnte?

Gruß


----------



## Noctarius (10. Jun 2009)

Schnell gegooglt nach "Frequenzanalyse Java" und schon hat man etwas, das fast hilfreich (ohne genauere Betrachtung) aussieht: http://www.uni-stuttgart.de/gi/education/diplomarbeiten/wengert.pdf


----------



## dergrüne (10. Jun 2009)

Danke für die schnelle Antwort, allerdings ist eine Diplomarbeit nicht wirklich das passende, zum einen weiß ich nicht wie es mit copyright aussieht zum anderen ist das meistens nur sehr spezieller experimenteller Code und bietet höchstens einen Ansatz.

Ich werde es mir aber noch genauer heute Abend anschauen, falls noch jemand was weiß wäre ich Dankbar.

Gruß


----------



## Noctarius (10. Jun 2009)

Aber zu einer Diplomarbeit gehört normal auch der Sourcecode, den du sicher irgendwo finden kannst. Oft steht dieser unter einer freien Lizenz zur Verfügung.

Ansonsten siehst du den passenden Ansatz und kannst ihn für deine Zwecke anpassen. Ansonsten such doch bei Google mal weiter, das war ja gerade mal der 3. oder 4. Link.


----------



## HoaX (11. Jun 2009)

Fertige Libs braucht man nicht wirklich, nur ne Fouriertransformation. Die ist in wenigen Zeilen geschrieben bzw gibts auch so zum Runterladen. Hab ich schonmal mir J2ME verwendet für mein Stimmgerät. Aber frag mich nicht wo ich den Code hin hab ...


----------



## 19_Rave_89 (15. Jun 2009)

Hallo! Glaube bin hier richtg.......
Ich programmiere auch ein Stimmgerät(haupsächlich für E-gitarre und E-bass) mit java für die Abschlussprüfung in 2 wochen, habe aber große probleme mit der frequenzanalyse mittels fft habe einige codes gefunden aber die helfen mir nicht weiter. ;(

Könntest du mir da einige infs geben????
Wäre sehr danbar....

Gruß


----------



## 19_Rave_89 (15. Jun 2009)

Meine FFt - Algorithmus dauert ca. 20 sec für 1 min gesampleten Sound mit 8000 samples.......

Und wenn ich mir die Pnkte in Excel zeichnen lasse kommt kein schönes Signal zum Vorschein.....


----------



## HoaX (15. Jun 2009)

Dann hast du doch eh nur 6 bzw. 4 Töne zu stimmen? In dem Fall würde ich anstatt FFT lieber den Görtzel-Algorithmus verwenden, geht schneller.
20s für 60s Sound ist aber übel, ich würde mal die Implementation überarbeiten?

Ich werd heut abend mal schaun ob ich meinen Code noch irgendwo finde, mein Protoyp war für Java SE und iirc nicht so langsam.


----------



## 19_Rave_89 (15. Jun 2009)

Ok danke! Wäre sehr hilfreich!


----------



## HoaX (15. Jun 2009)

Da ich gerade lese dass du das Stimmgerät als Abschlussarbeit schreibst werde ich hier meinen Code vorerst nicht publizieren. Du darfst aber gerne deinen FFT hier zeigen und dir Tips usw. holen.


----------



## 19_Rave_89 (15. Jun 2009)

Ist nur für die matura 
Dient nur zum Vorführen....... Quellcode wird nicht veröffentlicht!!!

Musst ih ja nicht hier publizieren.... könntest ihn mir auch mailen... 

Könntest du mir dann evtl einige gute links zu Codebsp für den Görtzel-Code geben!
Häng jetzt schon wochenlang bei dieser fft kacke fest.... wäre froh wenn ihr mir helfen könnt
______________________________________________________________________________________________

```
DER FFT-ALGORITHMUS DEN ICH VERWENDE:

class Fft02{

  public static void main(String[] args){

    Transform transform = new Transform();


 	int sampleAnzahl=8000;
	float sampleINFloat = 8000F;
	final double seconds = 0.5;

    AudioFormat audioFormat = new  AudioFormat(AudioFormat.Encoding.PCM_SIGNED,sampleINFloat,8,1,1,sampleINFloat,false);
	targetDataLIne Soundhandler = new targetDataLIne();
	byte[] recArray = Soundhandler.getSound(audioFormat, seconds);
    System.out.println("Case A");
    double[] realInA=new double[sampleAnzahl];
    
    int count=0;
    for(int i = 0;i<recArray.length;i++)
    {
    	//System.out.println(""+recArray[i]);
    	realInA[count] = recArray[i];
    	count++;
    }
    System.out.println("Case B");
    double[] imagInA = new double[sampleAnzahl];
    double[] realOutA = new double[sampleAnzahl];
    double[] imagOutA = new double[sampleAnzahl];

    transform.doIt(realInA,imagInA,2.0,realOutA,
                                       imagOutA);
    display(realOutA,imagOutA);

  }//end main
  //===========================================//

}//end class Fft02

//=============================================//



class Transform{

  void doIt(double[] realIn,double[] imagIn,
            double scale,double[] realOut,
            double[] imagOut){

    for(int cnt = 0;cnt < realIn.length;cnt++){
      correctAndRecombine(realIn[cnt],
                          imagIn[cnt],
                          cnt,
                          realIn.length,
                          scale,
                          realOut,
                          imagOut);
    }//end for loop
  }//end doIt

  //===========================================//

  void correctAndRecombine(
            double realSample,double imagSample,
            int position,int length,double scale,
            double[] realOut,double[] imagOut){

    for(int cnt = 0; cnt < length; cnt++){
      double angle =
               (2.0*Math.PI*cnt/length)*position;

      realOut[cnt] +=
                realSample*Math.cos(angle)/scale;
      imagOut[cnt] +=
                realSample*Math.sin(angle)/scale;

      realOut[cnt] -=
                imagSample*Math.sin(angle)/scale;
      imagOut[cnt] +=
                imagSample*Math.cos(angle)/scale;
    }//end for loop
  }//end correctAndRecombine

}//end class transform
```
_________________________________________________________________________

diesen habe ich im internet gefunden......

___________________________________________________________________________--


----------



## HoaX (15. Jun 2009)

Find meinen Code grad eh net und bin zu faul den alten Rechner nochmal aufzubauen. Geht mir ja net darum den zu Veröffentlichen, sondern darum zu verhindern dass du fremde Arbeit als deine ausgibts. Ist es nicht deine Aufgabe zu verstehen was der Code macht?
Wie dem auch sei, schau mal hier: A Faster Discrete Fourier Transform

Ansonsten Görtzel ist verdammt leicht zu implementieren, siehe hierfür z.B. Embedded.com - The Goertzel Algorithm


----------



## 19_Rave_89 (16. Jun 2009)

Mein Englsch ist nicht gerade gut.......



> Goertzel block size N is like the number of points in an equivalent FFT. It controls the frequency resolution (also called bin width). For example, if your sampling rate is 8kHz and N is 100 samples, then your bin width is 80Hz.


Frage:
N kann also beliebig gewählt werden zwischen 1-8000(8000= sampling Rate)



> The third factor influencing your choice of N is the relationship between the sampling rate and the target frequencies. Ideally you want the frequencies to be centered in their respective bins. In other words, you want the target frequencies to be integer multiples of sample_rate/N.



target_frequence ist also meine gewünschte frequenz .... also die Sollfrequenz mienes gestimmten Tons(Bsp die Frequenz der A-Seite der Bassgitarre = 55Hz odr der Gitarre=110Hz)??


----------



## HoaX (16. Jun 2009)

ja und ja


----------



## 19_Rave_89 (24. Jun 2009)

Hallo!
Funktioniert immernoch nicht! Vieleicht hab ich alles falsch verstanden odr ich bin einfach zu blöd.....???:L

Mein Goertzl- Algorithmus:

```
int sampleAnzahl=8000;
		float sampleINFloat = 8000F;
		final double seconds = 1;
		int N=100;
		double target_freq = 98;
                
// hier fehlt der teil der aufnahme ------> recArray beinhaltet die Soundsamples die ich
// mit der TArgetdataline erfasst habe
                
                double k =(double)(0.5+((N*target_freq)/sampleAnzahl));
		double pi = Math.PI;
		double realW = 2*Math.cos((2*pi*k)/N);
		double imagW = Math.sin((2*pi*k)/N);
		double y=0,d2=0,d1=0,resultr=0,resulti=0,result=0;
		
		for(int i=0;i<recArray.length;++i)
		{
			y=recArray[i]+(realW*d1)-d2;
			d2=d1;
			d1=y;
		}
		System.out.println("y: "+y);
		
		resultr=d1-d2*(Math.cos((2*pi*k)/N));
		resulti=imagW*d2;
		result=(resulti*resulti)+(resultr*resultr);
		
		System.out.println("Result: "+result);
		System.out.println("Result_sqrt: "+Math.sqrt(result));
```

Die Ausgabe Result_sqrt oder Result müsste mir dan also die ca 98 Hz liefern von meiner gestimmte G- Saite oder???
Bei mir stimmt das jedoch nicht......obwohl ich die gitarre direkt am line in angeschlossen habe......

Bitte um Hilfe!
Gruß


----------

