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/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
Computer—usr—local—include—coreland—openal-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:
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 |
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); |