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
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:
project Default is
for Source_Dirs use (“src”, “../../../../usr/local/include/coreland/openal-ada”);
for Object_Dir use “obj”;
for Main use (“main.adb”);
for Source_List_File use “sourcefiles.text”;
package Linker is
for Switches (“ada”) use (“-lopenal”, “-lalut”);
end Linker;
end Default;
Flowchart
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); |
Output Audio
Listen with stereo headphone.
Source List
with Text_IO; use Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
with OpenAL.Context; use OpenAL.Context;
with OpenAL.List;
with OpenAL.Types;
with OpenAL.Buffer;
with OpenAL.Error; use OpenAL.Error; –use is needed
with OpenAL.Listener;
with OpenAL.Source;
with OpenAL.Thin;
with Interfaces; use Interfaces;
with Ada.Sequential_IO; –use Ada.Sequential_IO;
procedure Main is
type Sample_16_t is range -32768 .. 32767;
for Sample_16_t’Size use 16;
———————————————————
— Function Display OpenAL Procedure/Function Result
— In: OpenAL result Code number, Out: Boolean result.
— Get_Error doesn’t work perfectly
— Error Codes are different between in Spec and in Code.
———————————————————
Function Test_Error (Display_Message : String) return Boolean is
Result : Boolean;
Errort : OpenAL.Error.Error_t;
begin
Errort := OpenAL.Error.Get_Error;
If(Errort = No_Error) then
Result := True;
else
Result := False;
end if;
Put(Display_Message & ” “);
Case Errort is
when No_Error => Put_Line(“GOOD: SUCCESS”);
when Invalid_Name => Put_Line(“ERROR!!! Invalid_Name####################”);
when Invalid_Enumeration => Put_Line(“ERROR!!! Invalid_Enumeration###########################”);
when Invalid_Value => Put_Line(“ERROR!!! Invalid_Value####################”);
when Invalid_Operation => Put_Line(“ERROR!!! Invalid_Opearation######################”);
when Out_Of_Memory => Put_Line(“ERROR!!! Out_Of_Memory###################”);
when Unknown_Error => Put_Line(“ERROR!!! Unknown_Error###################”);
when Others => Put_Line(“ERROR!!! UNDEFINED ERROR######################”);
end case;
Return Result;
end Test_Error;
———————————————————
— Function Open WAV file and store the parameters and data
— IN: File name and valiable addresses, OUT: Boolean result
———————————————————
Function LoadWaveFile(
WaveFile: in String; — File name string
Format : out Unsigned_16; –PCM=01,00
Data : out OpenAL.Buffer.Sample_Array_16_t;
Length : out Unsigned_32; –Byte, Only Data portion=(05..08)+8-44
Freq : out OpenAL.Types.Size_t;
Channel : out Unsigned_16; –1ch=01,00, 2ch=02,00
Sample : out Unsigned_16 –16bit=10,00
) Return Boolean is
package UWI_IO is new Ada.Sequential_IO (Unsigned_16);
use UWI_IO;
FT :UWI_IO.File_Type;
WAttrb : array (1..50) of Unsigned_16 := (1..50 => 0); –Wave file Attribute portion
Cnt : Integer;
Index : array (1..2) of Unsigned_16 := (Others=>0); –“data” search buffer in WAV file header
K1,K2 : Unsigned_16;
Data1U16 : Unsigned_16;
Data1S16t : OpenAL.Buffer.Sample_16_t;
DataCnt : Integer;
Begin
Begin –File open
UWI_IO.Open (File=>FT, Mode=>In_File, Name=>WaveFile); –Text_IO Open doesnot work for Binary file
exception
when others=>
Put_Line(“ERROR!!! WAV File cannot Open”);
raise;
end; –File open end
Put_Line(“File Open done”);
Cnt := 1;
while not End_Of_File (FT) loop
Read(FT, WAttrb(Cnt));
Index(1):=Index(2); Index(2):=WAttrb(Cnt);
exit when ((Index(1)=16#6164#) and (Index(2)=16#6174#)); — Found “data”=Subchunk2 ID
If (Cnt=50-2) then
Put_Line(“ERROR WAV file Index is too long”);
Return False;
end if; –WAVE FORMAT ERROR
Cnt := Cnt+1;
end loop;
Read(FT, K1);
WAttrb(Cnt):=K1; — Data number of BYTE Length 32bit
Cnt := Cnt + 1;
Read(FT, K2);
WAttrb(Cnt):=K2;
Length := Unsigned_32(K2)*65536 + Unsigned_32(K1); — Data Length, number of BYTE
DataCnt := 1;
while not End_Of_File (FT) loop
Read(FT, Data1U16);
if(Data1U16<32768) then Data1S16t := OpenAL.Buffer.Sample_16_t(Data1U16);
else Data1S16t := OpenAL.Buffer.Sample_16_t(-(Integer_16(NOT Data1U16) + 1)); –Negative value
end if;
Data(OpenAL.Buffer.Sample_Size_t(DataCnt)) := Data1S16t; –Store data
DataCnt := DataCnt + 1;
If (DataCnt > Integer(Length)/2+1) then –DataCnt=16bit, Length=8bit
Put_Line(“ERROR WAV file DATA is too long”);
Return False;
end if;
end loop;
Close (FT); — File close
Format := WAttrb(11); –PCM=0001=01,00
Freq := OpenAL.Types.Size_t(Unsigned_32(WAttrb(13)) + Unsigned_32(WAttrb(14))*65536);
Channel := WAttrb(12);
Sample := Wattrb(18);
Return True; –Success End
End LoadWaveFile;
————————————————-
— MAIN ===============================================================================
Bool : Boolean;
NrPlayback_Devices : Integer;
Vector_Cnt : Integer;
Playback_StrVectt : OpenAL.List.String_Vector_t;
UB_Default_Play : Unbounded_String;
UB_Playback_Devices : Unbounded_String;
CX_Devicet : OpenAL.Context.Device_t;
CX_Contextt : OpenAL.Context.Context_t;
Set_Active_Context : Boolean;
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
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
Sound_Source : OpenAL.Source.Source_t;
Sound_Source_Array : OpenAL.Source.Source_Array_t(1..1);
SoundWaveFileName : String := “testsound.wav”;
Result_WaveFileOPen : Boolean;
WAV_Format : Interfaces.Unsigned_16; –PCM=01,00
WAV_Data : OpenAL.Buffer.Sample_Array_16_t(1..1000000); –WAV File Word Max Capacity
WAV_Length : Unsigned_32; –Only Data portion number of Byte (chunk2 data area)
WAV_Freq : OpenAL.Types.Size_t;
WAV_Channel : Unsigned_16; –1ch=01,00, 2ch=02,00
WAV_Sample : Unsigned_16; –16bit=10,00
Buffer_Arrt : OpenAL.Buffer.Buffer_Array_t (1..1000000); –WAV File Word Max Capacity
ProcessedNr : Natural;
EndFlag : Integer; –Playback loop End Flag
TimeCnt : Integer; –Playback Time/Location/Speed Counter
SetPosF, SetVelF : OpenAL.Types.Float_t; –Vector Calculation
begin
Put_Line(“OpenAL Program Sample1”);
–***********
–Get_Default_Device_Specifier (Default Playback)
–***********
–use To_Unbounded_String, because the length is unknown
UB_Default_Play:=To_Unbounded_String(OpenAL.Context.Get_Default_Device_Specifier);
Put_Line(“Default Playback=” & UB_Default_Play);
–***********
–Get_All_Device_Specifiers (All Playbacks)
–***********
Playback_StrVectt := OpenAL.Context.Get_Available_Playback_Devices;
Vector_Cnt := 1;
Put_Line(“”);
Bool := OpenAL.List.String_Vectors.Is_Empty(Playback_StrVectt); –TRUE=EMPTY
NrPlayback_Devices := Integer(OpenAL.List.String_Vectors.Length(Playback_StrVectt));
If(Bool) then –EMPTY
Put_Line(“No Playback Device, N=” & Integer’Image(NrPlayback_Devices));
else
Put_Line(“Playback Devices N=” & Integer’Image(NrPlayback_Devices));
Vector_Cnt := 1;
Loop
UB_Playback_Devices := To_Unbounded_String(Playback_StrVectt(Vector_Cnt));
Put_Line(“Playback Devices Length=” & Integer’image(Length(UB_Playback_Devices)));
Put_Line(“Playback Device#” & Integer’Image(Vector_Cnt) & “=” & UB_Playback_Devices);
Vector_Cnt := Vector_Cnt + 1;
Exit when Vector_Cnt >= NrPlayback_Devices;
end loop;
end if;
———————————————————————————————
— OPEN Playback Device
— C: device = alcOpenDevice(NULL); // open default device
———————————————————————————————
CX_Devicet := OpenAL.Context.Open_Device (“OpenAL Soft”); –“OpenAL Soft”)
Put_Line(“UB_Playback_Device=” & UB_Playback_Devices);
if (CX_Devicet = Invalid_Device) then –Ref file: openal-alc_thin.ads
Put_Line(“BAD-Invalid Device!!! Cannot open Playback Device*******”);
else
Put_Line(“GOOD, Open Output Device Success”);
end if;
—————————————————————————————–
— Create Context
— C: context=alcCreateContext(device,NULL); // create context
—————————————————————————————–
CX_Contextt := Create_Context (CX_Devicet);
if (CX_Contextt = Invalid_Context) then –Ref file: openal-alc_thin.ads
Put_Line(“BAD-Invalid Context!!! Cannot Create Context *******”);
else
Put_Line(“GOOD, Create Context Success”);
end if;
—————————————————————————————–
— Set Active Context
— C: alcMakeContextCurrent(context); // set active context
—————————————————————————————–
Set_Active_Context := Make_Context_Current(CX_Contextt);
if (Set_Active_Context = False) then
Put_Line(“ERROR Set Active Context!!! Cannot Set Active Context *******”); end if;
If (Test_Error(“Set_Active_Context”) = False) then goto END_OF_PROGRAM; end if;
——————————————————————————————-
— Load testsound.wav
— loadWAVFile(“testsound.wav”,&format,&data,&Length,&freq,&loop);—-This is Obsolete
——————————————————————————————-
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,
WAV_Sample);
If (Result_WaveFileOpen=False) then
Put_Line(“Wave file Open ERROR”);
goto END_OF_PROGRAM;
end if;
Put_Line(“Sound File=” & SoundWaveFileName);
Put(“Format=” & Unsigned_16’image(WAV_Format));
If(WAV_Format=1) then Put_Line(” PCM”); else Put_Line(” Some format”); end if;
Put_Line(“WAV Data Length=” & Unsigned_32’image(WAV_Length) & ” Byte”);
Put_Line(“Sampling Freq=” & OpenAL.Types.Size_t’image(WAV_Freq) & “Hz”);
Put_Line(“Channel=” & Unsigned_16’image(WAV_Channel));
Put_Line(“Sample=” & unsigned_16’image(WAV_Sample) & “bit”);
——————————————————————————————————
–// Generate Buffers
— C: alGenBuffers(NUM_BUFFERS, g_Buffers);
— Ada: procedure Generate_Buffers (Buffers : in out Buffer_Array_t);
— The Generate_Buffers procedure generates Buffers’Length buffers.
——————————————————————————————————
OpenAL.Thin.Gen_Buffers
(Size => OpenAL.Types.Size_t(WAV_Length/2), –Set number of Word
Buffers => Buffer_Arrt(1)’Address);
Put_Line(“Generated Buffer, WAV_Length=” & Unsigned_32’Image(WAV_Length) & ” Byte”);
——————————————————————————————————
–Copy WAV data into AL Buffer 0
–C: alBufferData(g_Buffers[0],format,data,Size(number of Bytes),freq);
— This was not in the manual, it is in OpenAL.Thin,
— It can set Size freely, so it is good to define maximum WAV 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;
);
—————————————————————————————
— Generate Sources
— C: alGenSources((ALuint)1, &source); //generates one or more sources, n=number
— If error: alDeleteBuffers(NUM_BUFFERS, g_Buffers) ???? This was not written in the sample program
—————————————————————————————-
OpenAL.Source.Generate_Sources (Sound_Source_Array); –Sound_Source_Array(1..1) only one array
Sound_Source := Sound_Source_Array(1); –Sound_Source:Source_t
If (Test_Error(“Generate-Sources (Sound_Source_Array)”) = False) then goto END_OF_PROGRAM; end if;
OpenAL.Source.Get_Buffers_Processed (Sound_Source, ProcessedNr);
Put_Line(“1 Number of Processed buffers=” & Natural’image(ProcessedNr)); –Nu=0 Just to monitor
OpenAL.Source.Get_Buffers_Queued (Sound_Source, ProcessedNr);
Put_Line(“Number of Processed buffers Queued=” & Natural’image(ProcessedNr)); –Queued=0 just to monitor
If(OpenAL.Source.Is_Valid(Sound_Source)=True) then Put_Line(“Is_Vlaid=True”);
else Put_Line(“Is_Valid=False”); end if;
——————————————————————————————————-
–// Attach buffer to source
— C: alSourcei(source[0], AL_BUFFER, g_Buffers[0]);
–procedure Set_Current_Buffer
— (Source : in Source_t;
— Buffer : in OpenAL.Buffer.Buffer_t);
——————————————————————————————————-
OpenAL.Source.Set_Current_Buffer (Sound_Source, Buffer_Arrt(1));
Put_Line(“Attached buffer to Source”);
OpenAL.Source.Get_Buffers_Processed (Sound_Source, ProcessedNr);
Put_Line(“2 Number of Processed buffers=” & Natural’image(ProcessedNr)); –Nr=0 just to monitor
OpenAL.Source.Get_Buffers_Queued (Sound_Source, ProcessedNr);
Put_Line(“Number of Processed buffers Queued=” & Natural’image(ProcessedNr)); –Queued=1 just to monitor
If(OpenAL.Source.Is_Valid(Sound_Source)=True) then Put_Line(“Is_Vlaid=True”); else Put_Line(“Is_Valid=False”); end if;
——————————————————————————————–
— Set SOURCE
— procedure Set_Position_Float_List
— (Source : in Source_t;
— Position : in Types.Vector_3f_t);
——————————————————————————————–
OpenAL.Source.Set_Position_Float_List(Sound_Source, Source_Set_Position);
If (Test_Error(“Set Source Set_Position_Float_List”) = False) then goto END_OF_PROGRAM; end if;
OpenAL.Source.Set_Velocity_Float_List(Sound_Source, Source_Set_Velocity);
If (Test_Error(“Set Source Set_Velocity_Float_List”) = False) then goto END_OF_PROGRAM; end if;
OpenAL.Source.Set_Direction_Float_List(Sound_Source, Source_Set_Direction);
If (Test_Error(“Set Source Set_Direction_Float_List”) = False) then goto END_OF_PROGRAM; end if;
——————————————————————————————–
— Set LISTENER
— procedure Set_Position_Float_List
— (Position : in Types.Vector_3f_t);
——————————————————————————————
OpenAL.Listener.Set_Position_Float_List(Listener_Set_Position); –X,Y,Z set the position of the listener
If (Test_Error(“Set Listener Set_Position_Float_List”) = False) then goto END_OF_PROGRAM; end if;
OpenAL.Listener.Set_Velocity_Float_List(Listener_Set_Velocity); –X,Y,Z set the velocity of the listener
If (Test_Error(“Set Listener Set_Velocity_Float_List”) = False) then goto END_OF_PROGRAM; end if;
OpenAL.Listener.Set_Orientation_Float(Listener_Orientation_Forward, Listener_Orientation_Up);
If (Test_Error(“Set Listener Orientation Fwd/Up”) = False) then goto END_OF_PROGRAM; end if;
——————————————————————————————————-
— The Play procedure sets the source specified by Source to the playing state.
— OpenAL.Source.Play (Sound_Source_Array(1)); or
— procedure Play (Source : in Source_t); Either one is works.
——————————————————————————————————-
OpenAL.Source.Play (Sound_Source_Array(1));
— OpenAL.Source.Play (Sound_Source);
Put_Line(“Play(Sound_Source)”);
delay 0.5; –wait timer 0.5sec to listen initial settings
TimeCnt := 0;
EndFlag := 0;
for J in integer range 1..1000 loop –Not for forever loop
— Set Position from left to right
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); — Left(-) to Right(+), XYZ Float
— 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 Float
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);
exit when (EndFlag /= OpenAL.Thin.AL_PLAYING); –4114=AL_PLAYING, 4116=AL_STOPPED
delay 0.1;
TimeCnt := TimeCnt + 1;
end loop;
Put_Line(“Last TimeCnt=” & Integer’Image(TimeCnt));
<< END_OF_PROGRAM >> — label for goto
OpenAL.Context.Close_Device (CX_Devicet); –“OpenAL Soft”
end Main;
— END MAIN =====================================================================================
Build with GnatStudio
gprbuild -d -P/home/mm/ada/Sample1/default.gpr /home/mm/ada/Sample1/src/main.adb
Compile
[Ada] main.adb
[Ada] openal.ads
[Ada] openal-buffer.adb
[Ada] openal-context.adb
[Ada] openal-error.adb
[Ada] openal-list.adb
[Ada] openal-listener.adb
[Ada] openal-source.adb
[Ada] openal-thin.ads
[Ada] openal-types.ads
[Ada] openal-alc_thin.ads
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
[2021-04-12 22:56:59] process terminated successfully, elapsed time: 01.61s
Execution Screen
~/ada/Sample1/obj$ ./main
OpenAL Program Sample1
Default Playback=OpenAL Soft
Playback Devices N= 1
Playback Devices Length= 11
Playback Device# 1=OpenAL Soft
UB_Playback_Device=OpenAL Soft
GOOD, Open Output Device Success
GOOD, Create Context Success
Set_Active_Context GOOD: SUCCESS
File Open done
Sound File=testsound.wav
Format= 1 PCM
WAV Data Length= 441000 Byte
Sampling Freq= 44100Hz
Channel= 1
Sample= 16bit
Generated Buffer, WAV_Length= 441000 Byte
Generate-Sources (Sound_Source_Array) GOOD: SUCCESS
1 Number of Processed buffers= 0
Number of Processed buffers Queued= 0
Is_Vlaid=True
Attached buffer to Source
2 Number of Processed buffers= 0
Number of Processed buffers Queued= 1
Is_Vlaid=True
Set Source Set_Position_Float_List GOOD: SUCCESS
Set Source Set_Velocity_Float_List GOOD: SUCCESS
Set Source Set_Direction_Float_List GOOD: SUCCESS
Set Listener Set_Position_Float_List GOOD: SUCCESS
Set Listener Set_Velocity_Float_List GOOD: SUCCESS
Set Listener Orientation Fwd/Up GOOD: SUCCESS
Play(Sound_Source)
Last TimeCnt= 45