Durchschnittston des Soundinputs heraus finden
Übersicht

![]() |
DAKBetreff: Durchschnittston des Soundinputs heraus finden |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hat jemand eine Ahnung, wie man den Durchschnittston oder die Tonhöhe des lautesten Tons vom Mic-in/Line-in herausfinden kann?
Was ich machen möchte, ist auf die Art ein Guitar Hero mit ner echten e-Gitarre. |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Goodjee |
![]() Antworten mit Zitat ![]() |
---|---|---|
frag bdoch mal den kollegen hier: https://www.blitzforum.de/gallery/1521/ | ||
"Ideen sind keine Coladosen, man kann sie nicht recyclen"-Dr. House
http://deeebian.redio.de/ http://goodjee.redio.de/ |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
perfekt, danke
steht dort alles, was ich brauch.. openal + fast fourier transformation. die fft is zwar ned grad leicht, aber machbar. danke! |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da ich das auch schon einmal programmiert habe, allerdings auf die Gesangsstimme spezialisiert. Für die Gitarre sollte es besser funktionieren.
Zum Ersten ist das nicht der "Durchschnittston" sondern der Grundton, den du da bestimmen möchtest, sonst wirst du auch nichts bei Google finden. Weitere Schlüsselwörter sind "Pitch Extraction" und "Fundamental Frequency". Über die Techniken kannst du dich hier informieren. Statt FFT (Frequenzbereich) würde ich Autokorrelation (Zeitbereich) nutzen. Eine Funktion f(t) ist mit sich selbst verglichen natürlich am ähnlichsten. Autokorrelation erkennt Periodizität, in dem es f(t) mit (f-T) vergleicht (T ist eine Zeitkonstante und t die Zeitvariable): A(T) = Integral von -Infin. bis +Infin über f(t)*(f-T) dT Man muss also eine Periodendauer T suchen, bei der A(T) der größten Wert liefert. Über die Gleichung T = 1/f bzw. f = 1/T kannst Du aus der Periodendauer (Einheit ist s) die Frequenz (Einheit Hz, 1/s) ermitteln und vice versa. Du möchtest herausfinden, welche Musiknote der Benutzer spielt. Um nicht jede Periodenzeit T durchprobieren zu müsse, prüfst bspw. 3 Oktaven mit je 12 Tönen ab. Das wären dann 36 Ähnlichkeitswerte, die Du miteinander vergleichen müsstest. Nehmen wir als Konstante für den C-Ton in der ersten Oktave C_TONE : Float = 65.406391325 ' Hz (Habe ich mal errechnet, ausgehend vom Kammerton A mit 440 Hz.) Du kannst die weiteren Frequenzen mit frequency = C_Tone*2.0^(Float(octave*12 + tone)/12.0) ausrechnen. Die Variable octave geht von 0 bis 2 (ist aber egal) und tone von 0 bis 11 (C, C#, D, D#, E, F, F#, G, G#, A, A#, H). Möchtest du die Frequenz für den Ton F# in der zweiten Oktave wissen, musst octave = 1 und tone = 6 setzen. Damit hast du das Mittel in der Hand, welcher Ton (bspw. 36 Töne musst du prüfen) das größte Gewicht hat. Die numerische Integration (also programmatisch nur Funktionswerte aufaddieren) ist nicht sehr rechenintensiv. Komplexität ist O(n). FFT müsste auch O(n) sein, hat aber den Nachteil das sie rekursiv ist (für Autokorrelation reicht eine einfache Vorschleife). Bei FFT kommt zusätzlich noch sqrt zum Einsatz, um die komplexe Funktion in eine reelle Funktion zu transformieren, bei Autokorrelation reicht Addieren und Dividieren von Floatzahlen aus. Also ich habe damals einfach mein Mikro ans Keyboard gehalten und bei Saiteninstrumenten hat es sehr gut funktioniert. Bei einer Trompete mit 5 Nebentönen und Vibrato war es allerdings nicht mehr perfekt funktioniert. Was am geeignetsten ist, kannst mit Audacity ausprobieren (Analyse > Frequenzanalyse). "Spektrum" ist FFT und "Standard-Autokorrelation" ist das oben beschriebene. Über die "Erweiterte Autokorrelation" wurde hier geschrieben. Mir fehlte es eigentlich immer an geeigneten Testaudiomaterial und mein Mikro ist qualitativ auch sehr schlecht, so das Experimente (bspw. welche Fensterfunktion am geeignetsten ist) keinen Sinn gemacht hatten. ciao |
||
vertex.dreamfall.at | GitHub |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
hehe^^ wieder mal typisch^^ kaum hat ma sich n paar std mit einem lösungsweg auseinander gesetzt und das ganze zum laufen gebracht, schon kommt da wer und liefert einem einen wesentlich besseren lösungsweg ![]() sag mal, hast du zufällig eine ahnung, wie zb per openal die eingabefrequenz rein kriegen kann? ich raff openal nicht ganz... du scheinst ziemlich eine ahnung zu haben, vertex. soviel ich gesehen hab, hast du nen openal-wrapper geschrieben. könntest du mir da n bissale helfen? |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Samplingfrequenz (das meinst du sicher mit Eingabefrequenz) musst du bei alcCaptureOpenDevice angeben. Schau einfach mal hier, wie du OpenAL zum laufen bringst. Beachte, wenn du eine Frequenz bis zu f ermitteln willst (egal mit FFT oder Autokorr.), musst du mit der Nyquist-Frequenz das Signal sampeln. Damit muss die Samplingfrequenz mindestens zwei mal f groß sein.
Achja, Fensterfunktionen gibt es hier. Mir fällt gerade ein, dass du ja auch Akkorde aufspüren müsstest. Am einfachsten wäre hier aus den 36 Wichtungen der Autokorr.-fkt. die drei größten herauszusuchen aber ob das auch so funktioniert bezweifle ich (schau dir dazu nochmal das Autokorrelogramm in Audacity an). Hier mal ein paar Bilder, warum Akkorde so schwer zu erkennen sind: (Audacity) (BMax) Ich habe hier einen reinen 440 Hz Sinuston erzeugt und ihn dann analysiert. Beide Programme haben zwar einen Peak bei 440 Hz (Audacity sagt Kammerton A in der vierten Oktave, meines sagt, es wäre die dritte Oktave) aber auch mehrere weitere Ausschläge sind zu sehen, die sich event. mit zwei weiteren Grundfrequenzen überlagern könnten. Damals hatte ich FFT zuerst ausprobiert und es hat nur bei meinem Keyboard funktioniert, aber mit der Stimme nicht (ganz einfach im Sepktrogramm den Peak ausgemacht). Bei einer Gitarre könnte aber FFT tatsächlich besser funktionieren. Es gibt dazu Algorithmen mehrere Peaks in einer Funktion zu Detektieren. Aber erst einmal mit Audacity prüfen, ob FFT oder Autokorr. am geeignetsten ist. ciao |
||
vertex.dreamfall.at | GitHub |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
hmm... verstehe...
das ganze wird doch etwas intressanter als gedacht... im mom häng ich aber bei einer anderen sache... wie schaff ichs, dass das, was ich mit openal aufnehme (möglichst realtime) an die FFT weitergegeben wird? die fft, so wie ich sie jetz hab, nimmt zwei Arrays von Frequenzwerten (gRe und gIm, für den realen und imaginären teil der schwingung.) danke für die hilfe! (sag mal, könntest du mir vllt den source von deinem programm zeigen?... das hier ist das erste mal, dass ich so weit unten mit sound arbeite. vorher war das größte, was ich damit gemacht hab im grunde ein simples PlaySound() oder so... das hier is für mich recht neu und ich steig da noch nicht so ganz durch. wär voll super) |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] ' Tone weights
For Index = 0 Until TRecorder.NUM_OCTAVES*12 Frequency = TRecorder.C_Tone*2.0^(Float(Index)/12.0) Weight = TRecorder.ToneWeight(Frequency) TRecorder.ToneWeights[Index] = Weight If Weight > MaxWeight Then TRecorder.Tone = Index MaxWeight = Weight EndIf Next Code: [AUSKLAPPEN] ' Tone weight by using autocorellation
Function ToneWeight:Float(Frequency:Float) Local Sum : Float, .. Source : Int, .. Destination : Int, .. Count : Int Source = 1 Destination = 1 + Int(44100.0/Frequency) While Destination < TRecorder.NumSamples Sum :+ Abs(TRecorder.Samples[Source] - .. TRecorder.Samples[Destination])/Float($10000) Source :+ 1 Destination :+ 1 Count :+ 1 Wend Return 1.0 - TRecorder.Boost*(Sum/Float(Count)) End Function /Float($10000) ist glaube dazu da, um die Samples in den Bereich [0.0 1.0] oder [-1.0 1.0] zu normieren. Weiß es allerdings auch nicht mehr. Das Device habe ich so geöffnet: Code: [AUSKLAPPEN] TRecorder.NumSamples = Int(Floor(44100.0/(BPM/60.0)))
TRecorder.SampleCount = 0 TRecorder.Recorder = alcCaptureOpenDevice(.. Name, 44100, AL_FORMAT_MONO16, TRecorder.NumSamples*2) 'TRecorder.NumSamples Für FFT kannst du hier was finden. Meins basiert auf dem Artikel der FH Flensburg. Ciao |
||
vertex.dreamfall.at | GitHub |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group