Delphi

OpenAL

Tutorials

Lesson #11 (SoftSynth Part 1)

In this tuturial we lay the basis for an softsynth application using OpenAL.

Once again we start by using the files from lesson#1.

For a softsynth application we do not want to load the sound data from wave or ogg files, but we want to generate them while running our application. Therefore we do not need the following lines anymore:

AlutLoadWavFile('ding.wav', format, data, size, freq, loop);
AlutUnloadWav(format, data, size, freq);

Remove those lines.

Sine Wave

Basicly all sounds that you hear can be seen as waves (like the ones in the ocean). A basic waveform is a sine wave. This means that all the waves are equaly in shape. For calculation a sine wave you need to add the following lines into the var section of your application:

 SR: integer;                   //sample rate
  L: integer;                    //lenth of sample
  F: single;                    //frequency of sample
  Hz: integer;                   //frequency in hertz of sample (cycles per second)
  A: integer;                    //amplitude
  O: Array[0..1000] OF SmallInt; //output sample (1000=L) signed 16-bit
 T: integer;                    //time

You need to calculate the sine wave in the initialisation part of your form. So it is best to place it just in front where you generate the buffer. The code looks like this:

  //calculate the sine waveform
  Hz := 440; //440
  L := 1000;  //be carefull when changing this value as we use a static array O
  A := 32760; //maximum amplitude value for 16bit
  SR := 22000;
  F :=(2*pi*Hz)/SR;
  For T:=0 to L do
  begin
    O[T]:=Round(A*sin(F*T));
  end;

This will generate a 440hz sine wave with an sample rate of 2200hz and a depth of 16bit.

To hear this sound you need to ajust the albufferdata call to:

alBufferData(buffer, AL_FORMAT_MONO16, @O, L, SR);

Try changing the Hz variable value to hear different versions of the sine wave.

Additive Synthesis

To make things sound more interesting it is possible to layer sine waves on top of each other by just adding them and divide by the number of layers you added together.

Add the folowing lines to the var section:

  O1: Array[0..1000] OF SmallInt; //output sample (1000=L) signed 16-bit
  O2: Array[0..1000] OF SmallInt; //output sample (1000=L) signed 16-bit

Also add the folowing code just before the albufferdata call:

  //sample O1
  Hz:=800;
  F :=(2*pi*Hz)/SR;
  For T:=0 to L do
  begin
    O1[T]:=round(A*sin(F*T));
  end;
  //sample O2
  Hz:=1200;
  F :=(2*pi*Hz)/SR;
  For T:=0 to L do
  begin
    O2[T]:=round(A*sin(F*T));
  end;
  //combine sample O1 & O2 into O
  For T:=0 to L do
  begin
    O[T]:=(O1[T]+O2[T]) div 2;
  end;

This will layer a 1200hz sine on top of an 800hz sine wave to generate a third new wave sound.

Feedback Sine Wave

For some further effects you can use a previous generated sine to distort a newly calculated wave like this:

  //sample O feedback
  Hz:=440;
  F :=(2*pi*Hz)/SR;
  FB := 10 / ( A*25); //keep the value 10 between 0 and 100
  For T:=0 to L do
  begin
    O[T]:=round(A*(sin(F*T)+(FB*O[T])));
  end;

Do not forget to add:

FB: single;

to the var section.

In the line FB := 10 / (A*25) the 10 is the amount influence of the previous calculated sind on the new one. Try lowering or increasing it.

To be continued

For now try to experiment with changing the sine hz values and layering them in different combinations. In the next softsynth lesson you will learn how to do FM synthesis.