
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:

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.