|

OpenAl Einführung - Teil 2 - by Delax
Das erste Programm, was wir uns ansehen wollen ist das von Ulf Ochsenfahrt beigelegte Beispiel. Es handelt sich um ein simples DOS Programm.
Program TestAL;
Uses Crt, Dos, AL;
Var
buffer : ALuint;
source : ALuint;
device : ALCDevice;
context : ALCContext;
test : Array[0..1000] OF Byte;
z : LongInt;
Begin
For z := 0 to 1000 Do
test[z] := Round(100*sin(z*(2*pi)/50.0)+128);
device := alcOpenDevice('DirectSound3D');
context := alcCreateContext(device, Nil);
alcMakeContextCurrent(context);
alGenBuffers(1, buffer);
alBufferData(buffer, AL_FORMAT_MONO8, test, 1000, 11024);
Writeln(alGetError);
alGenSources(1, source);
alSourcef(source, AL_PITCH, 1.0);
alSourcef(source, AL_GAIN, 1.0);
alSourcei(source, AL_BUFFER, buffer);
alSourcei(source, AL_LOOPING, AL_TRUE);
alSourcei(source, AL_BUFFER, buffer);
Writeln(alGetError);
alSourcePlay(source);
Writeln(alGetError);
Readkey;
alSourceStop(source);
alcDestroyContext(context);
alcCloseDevice(device);
End.
Gehen wir den Source von oben nach unten durch. Als erstes definieren wir 6 Variablen. "buffer" und "source" sind beides ALuint (AL unsigned integer =
DWord in FPC). "buffer" dient dazu unseren Buffer zu identifizieren und "source" ist die Quelle unserer Ausgabe.
An der Stelle einmal die Definition von "Quelle". OpenAL hat 2 grundlegende Objekte: die Quelle (Source) und der Zuhörer (Listener). Diese werden benötigt, um Geräusche in einer Umgebung zu platzieren. In diesem Beispiel sind diese Objekte jedoch nicht nötig, da wir die Quelle nicht platzieren, sondern direkt ausgeben wollen.
Die nächsten Variablen sind "device", in der wir das Gerät zum Abspielen festlegen und "context", unseren GeräteContext. Windows bzw. OpenGL Programmierern wird das bekannt vorkommen. Schließlich noch ein Array "test", in den wir unsere Wellenform ablegen werden und eine Zählervariable namens "z".
Wir beginnen nun damit eine Klangwelle zu erzeugen. Dazu nutzen wir eine Schleife mit einer Sinuskurrve, deren Ergebnis wir als Wert in den Array speichern. Wer jetzt nicht weiß, wie Wellenformen aussehen, wie Töne "aussehen", der hat schlechte Karten. Man kann damit anfangen, indem man sich ein Musikprogramm besorgt, bei dem man die Wellenformen ähnlich wie hier als Formel direkt eingeben kann. Tip des Hauses hierzu: GoldWave. Außerdem sollte man sich Dokumentation zu diesem Thema besorgen (die Hilfedatei von GoldWave
ist ein Anfang. Weitere Stichworte sind Matlab oder Harmony-Central).
Nun definieren wir die Ausgabe. Zuerst setzen wir das Ausgabegerät mit device := alcOpenDevice('DirectSound3D'); auf die primäre DirectSound Ausgabe. Danach holen wir uns mit context := alcCreateContext(device, Nil); einen GeräteContext und aktivieren diesen mit alcMakeContextCurrent(context);.
Jetzt erstellen wir unseren Sound Buffer. Dies geht ähnlich wie Display Listen in OpenGL (für diejenigen, die damit etwas anfangen können). Man erzeugt erst mit alGenBuffers(1, buffer); einen leeren Buffer. Die Variable "buffer" dient dabei als Identifikation. Danach definieren wir den Buffer an sich. alBufferData(buffer, AL_FORMAT_MONO8, test, 1000, 11024); In dem Fall definieren wir ihn als 8 Bit Mono Buffer mit 1000 Schritt Länge. Wir verweisen als Inhalt auf unseren Array "test" und als Frequenz geben wir 11 KHz an. Wieder der Hinweis: wer mit diesen Bezeichnungen nichts anfangen kann möge bei oben angegebenen Adressen nachschlagen.
Jetzt definieren wir eine Klangquelle. Das Prinzip ist das gleiche, nur die Definition ist etwas anders. Diesmal werden die Attribute nacheinander angegeben. alSourcef(source, AL_PITCH, 1.0); definiert die Geschwindigkeit. alSourcef(source, AL_GAIN, 1.0); die Verstärkung. alSourcei(source, AL_BUFFER, buffer); verweist auf unseren Buffer. alSourcei(source, AL_LOOPING, AL_TRUE); ist entweder true oder false, je nachdem ob der Ton wiederholt werden soll oder nicht.
Abspielen tun wir den Ton jetzt mit alSourcePlay(source);. Den Ton anhalten besorgt alSourceStop(source);. Danach räumen wir auf und geben den Context und das Gerät wieder frei. alcDestroyContext(context);, alcCloseDevice(device);.
Zum Schluß noch für die Spielkinder ein paar Wellenformen zum ausprobieren.
|
Wave Form
|
Normal
|
Example
|
|
Sine Wave
|
sin(2*pi*frequency*t)
|
Round(Frequency*sin(Counter1*(2*pi)/50.0)+128);
|
|
Saw Wave
|
1 - 2*abs(1 - 2*frequency*t%2)
|
Round(1-2*(1-Frequency*Counter1 / 100));
|
|
White Noise
|
amplitude - rand(2*amplitude)
|
Round(1 - random(12000)+8000);
|
|
Pulse Wave
|
int(2*t*frequency)%2*2-1
|
Round(((counter1 div 100) mod 2)*Frequency+200);
|
Soweit erst einmal. Das nächste Mal schauen wir uns die Umsetzung des Beispiels auf Windows an.
Delax/ Sundancer Inc.
[delax@sundancerinc.de]
Back to previous page
|