N7SD logo

HOME      INDEX

The Easiest OpenAL-Ada “Sample1” with GnatStudio


Referenced
https://www.openal.org/documentation/OpenAL_Programmers_Guide.pdf
https://www.openal.org/documentation/openal-1.1-specification.pdf
https://github.com/io7m/coreland-openal-ada/blob/master/openal-context-capture.adb
https://github.com/io7m/coreland-openal-ada-dist/tree/master/doc

1, Prepare these 2 files in ~/ada/Sample1/

Source Files 

sourcefiles.text (download)

Required in GnatStudio build process.
The text file contains the following file names:
The “main.adb” should be your main program name.
1 file name per line.

main.adb
openal.ads
openal-alc_thin.ads
openal-buffer.adb
openal-buffer.ads
openal-context.adb
openal-context.ads
openal-context-capture.adb
openal-context-capture.ads
openal-context-error.adb
openal-context-error.ads
openal-error.adb
openal-error.ads
openal-extension.ads
openal-extension-efx.adb
openal-extension-efx.ads
openal-extension-efx_thin.adb
openal-extension-efx_thin.ads
openal-extension-float32.adb
openal-extension-float32.ads
openal-extension-float32_thin.ads
openal-global.adb
openal-global.ads
openal_info.adb
openal_info.ads
openal_info_main.adb
openal-list.adb
openal-list.ads
openal-listener.adb
openal-listener.ads
openal-load.adb
openal-load.ads
openal-source.adb
openal-source.ads
openal-thin.ads
openal-types.ads

Audio File to playback

~/ada/Sample1/testsound.wav (download), if execute with GnatStudio.
~/ada/Sample1/obj/testsound.wav, if execute directly on obj directory.

1kHz tone, 5 seconds, PCM, Mono, Sample rate 44.1kHz, 16bit, File=441044Byte, Wave data=441000Byte 

2, Setup GnatStudio

This sample project use the new directory ~/ada/Sample1/
~/ada/Sample1$ gnatstudio
+Create new project
Choose “Simple Ada Project” and “Next
Apply” and a new project is open now.
Edit
Project Properties…
Sources—Directories tab: This is the Source directory.
Mine is displayed as “/home/mm/ada/Sample1/src”
Press “+” button, browse
Computerusrlocalincludecorelandopenal-ada, and “OK
Now you can see the OpenAL files directory on the 2nd line in the Source directories
/usr/local/include/coreland/openal-ada

Sources—Files tab:
—Choose “Source list file”, “Browse”, choose “sourcefiles.text” and “OK”.
Just check Sources—Main tab: Check if Main files = “main.adb” is written in the box.
Just check Build—Directories tab: Check, if it is “obj”.
Build—Switches—Ada Linker tab: Enter this line into the bottom rectangular box.
-lopenal -lalut
“Save” to close the properties window.

New Project file was created as next:

~/ada/Sample1/default.gpr (download)

default.gpr

project Default is<br />for Source_Dirs use ("src", "../../../../usr/local/include/coreland/openal-ada");<br />for Object_Dir use "obj";<br />for Main use ("main.adb");<br />for Source_List_File use "sourcefiles.text";<br />package Linker is<br />for Switches ("ada") use ("-lopenal", "-lalut");<br />end Linker;<br />end Default;

Flow chart

Get Default Playback device name
with OpenAL.Context;
UB_Default_Play : Unbounded_String := Get_Default_Device_Specifier return String;
This value is used to see the device name.
On my PC, “OpenAL Soft” is the name

Get OpenAL playback devices (list of the names)
with OpenAL.Context; with OpenAL.List;
Playback_StrVectt := Get_Available_Playback_Devices return String_Vector_t;
Device names are stored into the buffer.
Bool := String_Vectors.Is_Empty(Playback_StrVectt) –Check if Device is existing or not
NrPlayback_Devices := Integer(String_Vectors.Length(Playback_StrVectt)); –Get how many
UB_Playback_Devices := To_Unbounded_String(Playback_StrVectt(Vector_Cnt))
— Get each name and print it out
These names are used to see the device names, and the previous default name should be in the list.
On my PC, only one name “OpenAL Soft”
Open Output Device
with OpenAL.Context;
CX_Devicet := Open_Device (“OpenAL Soft”) return Device_t;
The name should be a standard string (not UB), so I set the direct name.
Create Output Context
with OpenAL.Context;
function Create_Context (Device : in Device_t) return Context_t;
CX_Contextt := Create_Context (CX_Devicet);
Set Active Output Context
with OpenAL.Context;
function Make_Context_Current (Context : in Context_t) return Boolean;
Set_Active_Context := Make_Context_Current(CX_Contextt);
This process resets Error of Get_Error. “Invalid_Operation” Error is cleared by this command.
Load testsound.wav and get the parameters
loadWAVFile(“testsound.wav”,&format,&data,&Length,&freq,&loop);
Result_WaveFileOpen := LoadWaveFile(
SoundWaveFileName,
WAV_Format, — PCM=0001
WAV_Data, — Sample_Array_16_t(1)
WAV_Length, — Number of Wave data Byte
WAV_Freq, — Frequency_t
WAV_Channel, — Mono=0001, Stereo=0002
WAV_Sample); –16bit=0010H
Generate Buffer
with OpenAL.Buffer;
procedure Gen_Buffers
(Size : Types.Size_t;
Buffers : System.Address);
OpenAL.Thin.Gen_Buffers
(Size => OpenAL.Types.Size_t(WAV_Length/2), –Set number of Word
Buffers => Buffer_Arrt(1)’Address);
Note: Not used “OpenAL.Buffer.Generate_Buffers (Buffer_Arrt);”, because it cannot be set length.
This procedure was found in the original source file:
/usr/local/include/coreland/openal-ada/openal-thin.ads
Copy WAV data into AL Buffer
OpenAL.Thin.Buffer_Data(
Buffer_ID => 1, –Types.Unsigned_Integer_t;
Format => OpenAL.Thin.AL_FORMAT_MONO16, –Types.Enumeration_t;
Data => WAV_Data(1)’Address, –system.Address;
Size => OpenAL.Types.Size_t(WAV_Length), –Types.Size_t;==This Length is adjustable
Frequency => WAV_Freq); –Types.Size_t;
Note: Not used OpenAL.Buffer.Set_Data_Mono16, because it can’t set Size freely, so it is good to define maximum WAV buffer
This procedure was found in the original source file:
/usr/local/include/coreland/openal-ada/openal-thin.ads
Generate Sources (It generates Sources’Length sources)
with OpenAL.Source;
procedure Generate_Sources (Sources : in out Source_Array_t);
OpenAL.Source.Generate_Sources (Sound_Source_Array); — this array is (1..1) only one array
Sound_Source := Sound_Source_Array(1); –Sound_Source:Source_t
Attach Buffer to Source
It specifies the current buffer object, making it the head entry in the Source’s queue.
with OpenAL.Source;
with OpenAL.Buffer;
OpenAL.Source.Set_Current_Buffer
(Sound_Source, –Source_t
Buffer_Arrt(1)); –OpenAL.Buffer.Buffer_t
Set Source Position, Velocity and Direction
with OpenAL.Listener;
with OpenAL.Types;
OpenAL.Source.Set_Position_Float_List(Sound_Source, Source_Set_Position);
OpenAL.Source.Set_Velocity_Float_List(Sound_Source, Source_Set_Velocity);
OpenAL.Source.Set_Direction_Float_List(Sound_Source, Source_Set_Direction);
Initial values
Source_Set_Position : OpenAL.Types.Vector_3f_t := (0.0, 1.0, 0.0); –X,Y,Z
Source_Set_Velocity : OpenAL.Types.Vector_3f_t := (0.0, 0.0, 0.0); –X,Y,Z
Source_Set_Direction: OpenAL.Types.Vector_3f_t := (0.0, 1.0, 0.0); –X,Y,Z
Set Listner Position, Velocity and Orientation
with OpenAL.Listener;
with OpenAL.Types;
OpenAL.Listener.Set_Position_Float_List(Listener_Set_Position); –X,Y,Z
OpenAL.Listener.Set_Velocity_Float_List(Listener_Set_Velocity); –X,Y,Z
OpenAL.Listener.Set_Orientation_Float(Listener_Orientation_Forward, Listener_Orientation_Up);
Initial values
Listener_Set_Position : OpenAL.Types.Vector_3f_t := (0.0, 0.0, 0.0); –X,Y,Z
Listener_Set_Velocity : OpenAL.Types.Vector_3f_t := (0.0, 0.0, 0.0); –X,Y,Z
Listener_Orientation_Forward : OpenAL.Types.Vector_3f_t := (0.0, 1.0, 0.0); –X,Y,Z
Listener_Orientation_Up : OpenAL.Types.Vector_3f_t := (0.0, 0.0, 1.0); –X,Y,Z
Play Source(s), Start audio output
with OpenAL.Source;
Either one works
OpenAL.Source.Play (Sound_Source_Array(1)); –Source_Array_t
OpenAL.Source.Play (Sound_Source); –Source_t
Wait 0.5 second. You can listen the tone of the wave file without modification.
Loop until WAV file end
Set Position from left(-) to right(+), 0=Listener’s position
SetPosF := OpenAL.Types.Float_t((Float(TimeCnt)*100.0-3000.0)/150.0);
OpenAL.Source.Set_Position_Float(Sound_Source, SetPosF, 1.0, 0.0); — (-) to (+) XYZ
Set Velocity from Low to High Direction=to Right
SetVelF := OpenAL.Types.Float_t(Float(TimeCnt));
OpenAL.Source.Set_Velocity_Float(Sound_Source, SetVelF, 0.0, 0.0); — Increase from 0, XYZ
Get End of WAV playback.
This Procedure is not on the document, it’s in
OpenAL.Thin.Get_Sourcei
(Source_ID => OpenAL.Types.Unsigned_Integer_t(1), –Source_ID : Types.Unsigned_Integer_t;
Parameter => OpenAL.Thin.AL_SOURCE_STATE, –Parameter : Types.Enumeration_t;
Value => EndFlag’Address); — Value : System.Address);
This procedure was found in the original source file:
/usr/local/include/coreland/openal-ada/openal-thin.ads
procedure Get_Sourcei
(Source_ID : Types.Unsigned_Integer_t;
Parameter : Types.Enumeration_t;
Value : System.Address);
exit when (EndFlag /= OpenAL.Thin.AL_PLAYING); –4114=AL_PLAYING, 4116=AL_STOPPED
Delay 0.1; –wait 0.1sec

Close
with OpenAL.Context;
OpenAL.Context.Close_Device (CX_Devicet); –“OpenAL Soft”
procedure Close_Device (Device : in out Device_t);