Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

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

Useful Links









Link to us