Frequenzen ermitteln mit FFT


melmager

Erfahrenes Mitglied
#1
Ich möchte aus einem gegeben Soundstream die Noten ermitteln.
Als Lösung bin ich schon über FFT gestolpert.
Ich habe nur ein generelles Problem das Verfahren zu verstehen da ich in Mathe sowas nie hatte. :(

Anyway
Ich muss mit Complexen zahlen arbeiten und zwar mit Vectoren die mit 2 Werten dagestellt werden und wenn ich 128 Ergebnisse haben will brauche ich auch 128 Eingangswerte (Vectoren)

da habe ich ein Code her:
http://www.iti.fh-flensburg.de/lang/algorithmen/fft/fft.htm
Code:
void fft(Complex[] a, int n, int lo, Complex w)
{
    int i, m;
    Complex z, v, h;

    if (n>1)
    {
        m=n/2;
        z=1;
        for (i=lo; i<lo+m; i++)
        {
            h=a[i]-a[i+m];
            a[i]=a[i]+a[i+m];
            a[i+m]=h*z;
            z=z*w;
        }
        v=w*w;
        fft(a, m, lo, v);
        fft(a, m, lo+m, v);
        shuffle (a, n, lo);
    }
"Rechenoperationen mit komplexen Zahlen sind der Übersichtlichskeit halber mit normalen Rechenzeichen (+, -, *) dargestellt, obwohl diese in Java eigentlich nicht zur Verfügung stehen."

also müsste doch die Classe Complex so aussehen:
Code:
class Complex {
  int x,y;
  void add(Complex in) {
  }
  void sub(Complex in) {
  }
  void mul(Complex in) {
}
}
um die nötigen Rechenschritte machen zu können.

nur wie müssen die Functionen aussehen ?
wie addiert man eine complexe zahl - null Plan

und wo ist das Ergebnis ? es sollte irgenwo ein Array (in meinem Fall mit 128 Positionen) entstehen wo die beteiligten Frequenzbereiche drin sind ...
 
Zuletzt bearbeitet:
#2
Hi

Zuerst mal würde ich die "int x,y" in Complex zu Kommazahlen machen
und vllt. real und img nennen oder so.

Zu den Grundrechenarten: + und - einfach auf Real- und Imaginärteil getrennt ausführen.
Real=Real1+Real2, Img=Img1+Img2
Das Selbe für -

Multiplikation:
Real = Real1*Real2 - Img1*Img2
Img = Real1*Img2 + Real2*Img1

Steht übrigens auch alles schön auf Wikipedia :google:


...und nichts für ungut, aber bist du dir sicher, dass du eine Fouriertransformation machen willst?
Das ist ein anderes Level.

(Und noch dazu in Java :suspekt:)
 

melmager

Erfahrenes Mitglied
#3
Naja wenn einem Komplexe Zahlen nix sagen versteht man einige Erklärungen nicht.

Klar dürfte das langsam sein - aber hey warum nicht
ich habe ein AndroidApp gesehen die genau das macht was ich vorhabe
Sound rein - Mididaten raus und da ist noch weniger Rechenpower vorhanden...

Code:
class Complex {
  public long rel,img;
  void add(Complex ina,Complex inb) {
    rel = ina.rel + inb.rel;
    img = ina.img + inb.img;
  }
  void sub(Complex ina,Complex inb) {
    rel = ina.rel - inb.rel;
    img = ina.img - inb.img;
  }
  void mul(Complex ina,complex inb) {
    rel = ina.rel * inb.rel - ina.img * inb.img;
    img = ina.rel * inb.rel + ina.rel * inb.img;
}
}
Code:
/*  h=a[i]-a[i+m] ; wird dann zu */
h = new Complex();
h.sub(a[i],a[i+m]);

da eingangswerte int sind und ausgangswerte int sollte doch long reichen oder doch besser real ?
 
Zuletzt bearbeitet:

ComFreek

Mod | @comfreek
Moderator
#4
Mit long kannst du aber keine Kommazahlen abbilden!

ich habe ein AndroidApp gesehen die genau das macht was ich vorhabe
Sound rein - Mididaten raus und da ist noch weniger Rechenpower vorhanden...
Android-Apps kann man auch mit dem NDK und C++ programmieren.
Von daher muss es nicht unbedingt Java sein.
 

genodeftest

Erfahrenes Mitglied
#7
Klar dürfte das langsam sein - aber hey warum nicht
ich habe ein AndroidApp gesehen die genau das macht was ich vorhabe
Sound rein - Mididaten raus und da ist noch weniger Rechenpower vorhanden...
Wenn du Glück hast kann diese Android-App den DSP (Digital Signaling Processor) verwenden, der macht das quasi umsonst, d.h. kein Rechenaufwand für die CPU. Quasi in Hardware gegossene FFT. Wenn irgendwie möglich würde ich also versuchen, solche Hardware zu verwenden.