Audiovisualisierung mit C# und Bass.Net

19. Dezember 2008

C# Bass.Net
Visualisierungen von Audio sind nichts mehr neues und gehörten heutzutage zu fast jeder guten Wiedergabesoftware. In diesem Beispiel wird eine Visualisierung auf Basis von FFT (diskreten Fourier-Transformation) erstellt, welche von einem Eingehenden Audiostream erzeugt wird. Diie FFT müssen wir nicht selber vornehmen, sondern nehmen hier Bass.Net zur Hand. Bass.Net ist die .Net Api für die Audiobibliothek BASS.

Bass.Net einbinden

Bass.Net von der Un4seen Seite herunterladen und installieren. Danach einfach einen Verweis in das Projekt hinzufügen sowie den Namespace “n4seen.Bass” einfügen.

Visualisierung

Die Initialisierung von Bass.Net erfolgt mit folgendem Code:

// Bass Initialisieren
Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero, null);
// Record auf Default Defice
Bass.BASS_RecordInit(-1);
_myRecProc = new RECORDPROC(MyRecording);
// Channel festlegen
int recChannel = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, 50, _myRecProc, IntPtr.Zero);
// Record starten
Bass.BASS_ChannelPlay(recChannel, false);

Nun ist Bass.Net bereit den Audiostream, welcher über den Standardmikrofoneingang der Soundkarte kommt abzufangen und zu analysten und weiter zu verarbeiten.

Die Methode MyRecording dient dazu, die FFT-Daten abzufragen und den Stream weiterzuverarbeiten, z. B. auf die Festplatte zu streamen, etc. Für eine reine Visiualisierung ist das Speichern der Daten nicht notwendig und können gleich wieder verworfen werden.

public static bool MyRecording(int handle, IntPtr buffer, int length, IntPtr user)
{
    // Array zum speichern der FFT Daten
    _data = new float[256];
    // Handle
    _handle = handle;
 
    // Handle erstellen
    GCHandle hGC = GCHandle.Alloc(_data, GCHandleType.Pinned);
 
    // Daten auslesen
    Bass.BASS_ChannelGetData(handle, hGC.AddrOfPinnedObject(), (int)BASSData.BASS_DATA_FFT512);
 
    return true;
}

Im Array _data stehen nun die Daten der FFT. Diese können wir nun zu unserer Visualisierung weiterverarbeiten. Im folgenden Beispiel werden 32 Balken erstellen und auf der Console ausgegeben. Das Ergebnis könnte dann in etwas so aussehen:
Visualisierung

public static void drawBalken()
{
    float tmp = 0;
 
    for(int i = 0; i < 256; i++)
    {
        if(_data[i] + (_data[i] * (i  * 50)) > data[i])
            data[i] = _data[i] + (_data[i] * i * 50);
        else
            if(data[i] > 1)
                data[i] = data[i] - 1;
            else
                data[i] = 0;
    }
 
    Console.SetCursorPosition(0, 0);
 
    // Balken zeichnen
    for (int i = 0; i < 256; i += 8)
    {
        tmp = (data[i] + data[i + 1] + data[i + 2] + data[i + 3] + data[i + 4] + data[i + 5] + data[i + 6] + data[i + 7]) / 8;
        if (tmp > max)
            max = tmp;
 
        balken(tmp);
        Console.WriteLine();
    }
}

Dabei dient hier die Methode balken(float length) dazu, einen Balken in der angegebenen Länge auf der Console zu schreiben.

{ 4 Kommentare } { 1 Shares }

{ 4 Kommentare… lies sie unten oder schreib selbst einen }

Marius September 19, 2011 um 23:05

Hallo,
ich finde das sehr interessant, ich würde das gerne für eine Lichtersteuerung verwenden……. Kann man damit auch nur die Tiefen ausfiltern? Ist es möglich auch einen Event-Handler darauf zu erstellen, der immer bei einem Tiefenausschlag eine Methode aufruft?

Gruß Marius

Antworten

Martin Bauer September 20, 2011 um 08:29

Hallo,

sollte so auf jeden Fall theoretisch möglich sein. Die Überprüfung auf Bass und das auslösen des Events sollten dann in der Methode “MyRecording” (hier im Beispielcode) erfolgen.

Antworten

Manuel März 2, 2012 um 23:57

Hallo,
schön, sowas zu finden. Kannst du vielleicht das gesamte Projektverzeichnis online stellen, irgendwie krieg ich das nicht zum laufen (unter C#.NET 2010 Express).

Antworten

Martin Bauer März 3, 2012 um 09:25

Hallo,

leider hab ich das Projekt nicht mehr. Ist ja auch schon etwas länger her. Aber wenn du Dein Problem beschreiben würdest, könnt ihr dir vielleicht so helfen.

Antworten

Schreib einen Kommentar

Previous post:

Next post: