Einzelnen Beitrag anzeigen

BenjaminH

Registriert seit: 14. Okt 2004
Ort: Freiburg im Breisgau
713 Beiträge
 
Turbo Delphi für Win32
 

Beat Detection

  Alt 7. Sep 2009, 15:36
Der Beat Detector erkennt aus einer Aufnahmequelle heraus Beats. Es liefert allerdings nicht die bpm Zahl oder so etwas, sondern sendet bei jedem erkannten Beat eine MIDI-Signal.
Der Nutzen des Programms liegt in der Kombination mit anderen Programmen, z.B. DMXControl(Lichtsteuerung über DMX Controller am PC) wobei hier mit jedem Beat in eine neue Lichtszene gewechselt wird(Lauflicht o.ä.).
Das Programm wurde darauf optimiert im laufenden Betrieb möglichst schnell zu sein.

Wichtigste Besonderheit: Ab Windows Vista wird direkt auf die "Hauptlautstärke" zugegriffen. D.h. auch ohne Stereomix kann die Audioausgabe direkt abgegriffen werden.

Beschreibung der neuesten Version hier


Zur Erkennung des Beats wird ein Algorithmus verwendet, den ich bei Gamedev gefunden habe. Wahrscheinlich habe ich nicht alles genau richtig gemacht, weil ich nicht alles so genau verstanden habe. Aber es funktioniert.
Der Toneingang wird mittels der Bass.dll gelesen, auch die Fourier-Analyse übernimmt sie.

Ich freue mich über jeden Verbesserungsvorschlag!

Das Programm erstellt im Benutzerverzeichnis/Lokale Einstellungen/Anwendungsdaten eine Datei(.BeatDetector.ini).
Damit die Core-Audio Features funktionieren(Aufnahme der Wiedergabe durch den Lautsprecher) muss die bass.dll aus diesem Beitrag verwendet werden: http://www.un4seen.com/forum/?topic=8816 (Bzw direktlink: http://www.un4seen.com/stuff/bass.dll)

Grobe Funktion der Beat-Analyse(wird mit ca. 40Hz aufgerufen)
Delphi-Quellcode:
type
    THistArray= array[0..43] of Single;
var
    fft : array[0..1023] of Single;
    i,
    bound_lower, //untere -
    bound_upper:Integer; //obere Grenze zum erstellen der Bänder
    Sum:Single;//Energie eines Bandes

    BandHistory:array [0..31] of THistArray;//Alte Werte der Bänder gespeichert
    Histposition:0..43;//Aktuelle Stelle im Band History Array
    LastBeat:Cardinal;//GetTickCount beim letzten erkannten Beat

//FFT berechnen, Amplituden speichern
BASS_ChannelGetData(MainForm.Channel, @fft, BASS_DATA_FFT1024); // get the FFT data

//FFT in Bänder aufteilen
bound_lower:=0;
for i := 0 to bands - 1 do
begin
  //Bandbreite bestimmen
  bound_upper:=Trunc(Power(2, i * 10.0 / (BANDS - 1)));
  if bound_upper>1023 then
    bound_upper:=1023;
  if bound_upper<=bound_lower then//mindestens 1 FFT bin verwenden
    bound_upper:=bound_lower+1;

  //Summe der Amplituden innerhalb eines Bandes
  Sum:=0;
  while bound_lower<bound_upper do
  begin
    Sum:=Sum + fft[bound_lower+1];
    inc(bound_lower);
  end;
  //Amplitude des ganzen Bandes speichern
  BandHistory[i,HistPosition]:=sum;
end;
Inc(MainForm.HistPosition);

//Erkennen eines Beats(nur, wenn die gesamte Lautstärke nicht zu gering ist
if LOWORD(BASS_ChannelGetLevel(Channel)) >= 500 then
begin
  //Beat ist dann, wenn der Ausschlag des Bandes um den Faktor x größer ist als der Durchschnitt der letzten 43 Ausschläge
  if AverageBandEnergy(BandHistory[SelectedBand]) * DetectingFactor < BandHistory[SelectedBand,HistPosition-1] then
//AverageBandEnergy berechnet den Durchschnitt der letzten 43 Ausschläge im gegebenen Band
    if gettickcount>lastbeat+WaitingTime then//zu schnell aufeinanderfolgende Beats vermeiden
    begin
      Beat;//Beat Signal weitergeben
      lastbeat:=gettickcount;
    end;
end;
Miniaturansicht angehängter Grafiken
screenshot-1-1-0.png  
Angehängte Dateien
Dateityp: exe beatdetector_307.exe (542,5 KB, 202x aufgerufen)
Benjamin

Geändert von BenjaminH (22. Jun 2010 um 13:08 Uhr)
  Mit Zitat antworten Zitat