OpenAL with GTKAda GUI “Sample2”
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/openal-ada-doc-1.1.1/single.html
(openal-ada 1.1.1 documentation…This is OpenAL-Ada command reference)
Development and confirmed environment
PC: HP Envy-17t-S100
OS: Ubuntu 20.04.4 LTS
GTKAda: Adacore, GNAT Studio Community 2020 (20200427) hosted on x86_64-pc-linux-gnu
OpenAL: Coreland, openal-ada 1.1.1, File: OpenALaoa12nov20
File Structures
Directory: ada/Sample2/ — gnatstudio project files to control build options
Directory: ada/Sample2/src/ — source files
Directory: ada/Sample2/obj/ (File “main” is the executable file and lots of files are created in here).
A picture and a sound files are located here.
File Details
Download:
https://github.com/moriyasum/GtkAda_OpenAL_Doppler_Sample2
GtkAda_Build_Setting_File
with "gtkada";
project Default is
for Source_Dirs use ("src", "../../../../usr/local/include/coreland/openal-ada");
for Object_Dir use "obj";
for Main use ("main.adb");
package Linker is
for Switches ("ada") use ("-lopenal", "-lalut");
end Linker;
for Source_List_File use "sourcefiles.text";
end Default;
All_File_Names_to_Build_GtkAda
main.adb
tintr.ads
tintr.adb
gui.ads
gui.adb
audio.ads
audio.adb
common.ads
common.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
Main_Program
with Gtk.Box; use Gtk.Box;
with Gtk.Main; use Gtk.Main;
with Gtk.Window; use Gtk.Window;
with Gtk.Frame; use Gtk.Frame;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Progress_Bar; use Gtk.Progress_Bar; --Timer interrupt
with OpenAL.Context;
with Glib.Main; use Glib.Main; --Timer Interrupt Time_Cb.Timeout_Add
with Gdk.Event; use Gdk.Event;
with Audio;
with Gui;
with Tintr;
With Common;
procedure Main is
package Time_Cb is new Glib.Main.Generic_Sources (Gtk_Progress_Bar);
Win : Gtk_Window;
FrameM : Gtk_Frame;
BoxM : Gtk_Vbox;
begin
-- Initialize GtkAda.
Gtk.Main.Init;
-- Create a window with a size of 400x400
Gtk_New (Win);
Win.Set_Default_Size (1100, 700);
-- Create a box to organize vertically the contents of the window
Gtk_New_Vbox (BoxM);
Win.Add (BoxM);
Gtk_New (FrameM);
BoxM.Add(FrameM);
Gui.Run(FrameM);
-- Start Timer Interrupt
Tintr.Gid_dummy := Time_Cb.Timeout_Add
(Tintr.TINTR_PITCH, Tintr.Timer_Intr'Access, Tintr.Datatype_dummy);
-- End, close OpenAL device
OpenAL.Context.Close_Device (Audio.CX_Devicet); --CLOSE "OpenAL Soft"
-- Stop the Gtk process when closing the window
Win.On_Delete_Event (Common.Delete_Event_Cb'Unrestricted_Access);
-- Show the window and present it
Win.Show_All;
Win.Present;
-- Start the Gtk+ main loop
Gtk.Main.Main;
end Main;
GUI_Specification
with Gtk.Box; use Gtk.Box;
with Gtk.Label; use Gtk.Label;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Main; use Gtk.Main;
with Gtk.Window; use Gtk.Window;
with Gtk.Frame; use Gtk.Frame;
with Gtk.Button; use Gtk.Button;
with Gtk.Enums; use Gtk.Enums;
with Gtk.Handlers; use Gtk.Handlers;
with Gtk.Scrolled_Window; use Gtk.Scrolled_Window;
with Gtk.Adjustment; use Gtk.Adjustment;
with Gtk.Drawing_Area; use Gtk.Drawing_Area;
with Gtk.Spin_Button; use Gtk.Spin_Button;
with Gtkada.Canvas; use Gtkada.Canvas;
with Gtkada.Canvas_View; use Gtkada.Canvas_View;
with Gtkada.Canvas_View.Views; use Gtkada.Canvas_View.Views;
with Gtkada.Style; use Gtkada.Style;
with Ada.Numerics.Discrete_Random;
with Ada.Numerics.Elementary_Functions; --For Sin
use Ada.Numerics.Elementary_Functions; --For Sin
with Ada.Numerics; use Ada.Numerics;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
with Gdk; use Gdk;
with Gdk.Cairo; use Gdk.Cairo;
with Gdk.RGBA; use Gdk.RGBA;
with Gdk.Pixbuf; use Gdk.Pixbuf;
with Glib; use Glib;
with Glib.Error; use Glib.Error;
with Glib.Object; use Glib.Object;
with Cairo; use Cairo;
with Cairo.Pattern; use Cairo.Pattern;
with Cairo.Png; use Cairo.Png;
with Cairo.Region; use Cairo.Region;
with Cairo.Surface; use Cairo.Surface;
with OpenAL.Context; use OpenAL.Context;
with Text_IO; use Text_IO;
package Gui is
-----------------------------
-- Misc. types and variables
-----------------------------
-- package Items_Random is new Ada.Numerics.Discrete_Random (Positive);
-- use Items_Random;
Max_Size : constant := 400;
subtype Coordinate_Type is Gint range Default_Grid_Size + 1 .. Max_Size;
package Coordinate_Random is new
Ada.Numerics.Discrete_Random (Coordinate_Type);
use Coordinate_Random;
subtype Zoom_Type is Gint range 1 .. 2;
package Zoom_Random is new Ada.Numerics.Discrete_Random (Zoom_Type);
use Zoom_Random;
type FixedPoint0018 is delta 0.001 digits 8; --To display Float with FixedPoint value
FixPnt008 : FixedPoint0018;
type FixedPoint0016 is delta 0.1 digits 6; --To display Float with FixedPoint value
FixPnt006 : FixedPoint0016;
----------------------------------------------------------------
-- Redefine our own item type, since we want to provide our own
-- graphics.
----------------------------------------------------------------
type Display_Item_Record is new GtkAda.Canvas.Canvas_Item_Record with record
Canvas : Interactive_Canvas;
Color : Gdk.RGBA.Gdk_RGBA;
W, H : Gint;
Num : Positive;
end record;
type Display_Item is access all Display_Item_Record'Class;
----------------------------------------------------
-- Our own canvas, with optional background image --
----------------------------------------------------
type Image_Canvas_Record is new Interactive_Canvas_Record with record
Background : Cairo_Pattern := Null_Pattern;
Draw_Grid : Boolean := True;
end record;
type Image_Canvas is access all Image_Canvas_Record'Class;
type Image_Drawing_Record is new Gtk.Box.Gtk_Box_Record with record
Area : Gtk.Drawing_Area.Gtk_Drawing_Area;
PixG : Gdk.Pixbuf.Gdk_Pixbuf;
end record;
type Image_Drawing is access all Image_Drawing_Record'Class;
-- A special type of drawing area that can be associated with
-- an image.
package Canvas_Cb is new Gtk.Handlers.Callback
(Interactive_Canvas_Record);
package Canvas_User_Cb is new Gtk.Handlers.User_Callback
(Gtk_Widget_Record, Image_Canvas);
------------------------
-- Callbacks packages --
------------------------
package Expose_Cb is new Gtk.Handlers.Return_Callback
(Image_Drawing_Record, Boolean);
package Destroy_Cb is new Gtk.Handlers.Callback (Image_Drawing_Record);
-----------------------
-- PROTYPE
-----------------------
procedure Run (Frame : access Gtk.Frame.Gtk_Frame_Record'Class);
procedure Button_Single_Cb
(Canvas : access Interactive_Canvas_Record'Class);
procedure Button_Loop_Cb
(Canvas : access Interactive_Canvas_Record'Class);
procedure Button_Step_Cb
(Canvas : access Interactive_Canvas_Record'Class);
procedure Button_Clear_Cb
(Canvas : access Interactive_Canvas_Record'Class);
procedure Draw --Draw #1 *********
(Item : access Display_Item_Record;
Cr : Cairo_Context);
procedure Initial_Plane_Item_Setup
(Canvas : access Interactive_Canvas_Record'Class);
procedure Initialize_Listener_Image
(Draw : out Image_Drawing;
Pixbuf : Gdk.Pixbuf.Gdk_Pixbuf;
Title : String);
function On_Draw_Listener_Image
(Draw : access Image_Drawing_Record'Class;
Cr : Cairo_Context) return Boolean;
Procedure Calculate_Display_Sound
(Counter : in Integer);
Procedure Display_Plane
(Counter : in Integer);
procedure On_Listner_Loc (Spin : access Glib.Object.GObject_Record'Class);
-----------------------------
-- GLOBAL VARIABLES
-----------------------------
Button_Single : Gtk_Button;
Button_Loop : Gtk_Button;
Button_Step : Gtk_Button;
Button_Clear : Gtk_Button;
ButtonColor : Gdk_RGBA;
Dummy_Boolean : Boolean;
Label_Dummy1 : Gtk_Label; --Left pane top for clearance
Label_TCnt : Gtk_Label; --Left pane, TimeCnt
Label_S2SndPos_X : Gtk_Label; --Left pane, New postion X
Label_S2SndPos_Y : Gtk_Label; --Left pane, New postion Y
Label_SndVel_X : Gtk_Label; --Left pane, Sound Veloctiy X
Label_SndVel_Y : Gtk_Label; --Left pane, Sound Veloctiy Y
Label_Speed_Angle : Gtk_Label; --Left pane, Sound Angle
Label_Start_Flag : Gtk_Label; --Left pane, Status
OFFSET_X : Gtk_Spin_Button;
OFFSET_Y : Gtk_Spin_Button;
PIXFACTOR_X : Gtk_Spin_Button;
PIXFACTOR_Y : Gtk_Spin_Button;
SND_POS_FACTOR : Gtk_Spin_Button; --Sound Distance Factor
SND_SPD_FACTOR : Gtk_Spin_Button; --Sound SPeed Factor
TIME_CYCLE_X : Gtk_Spin_Button;
TIME_CYCLE_Y : Gtk_Spin_Button;
LPOS_X : Gtk_Spin_Button;
LPOS_Y : Gtk_Spin_Button;
Buf_LPOS_X : float;
Buf_LPOS_Y : float;
S1Pos_X : float := 99999.9; --Source X Coordinate OLD Memory, @previous Timer Interrupt Position
S1Pos_Y : float := 99999.9; --Source Y Coordinate OLD Memory, @previous Timer Interrupt Position
S2Pos_X : float := 99999.9; --Source X Coordinate NEW, Normalized value
S2Pos_Y : float := 99999.9; --Source Y Coordinate NEW, Normalized value
S2PixPos_X : float; --Source Display Pixel Absolute Position = S2Pos_X * PIXFACTOR_X
S2PixPos_Y : float; --Source Display Pixel Absolute Position = S2Pos_Y * PIXFACTOR_Y
S2SndPos_X : float; --Sound Relative Position from Listener=(S2Pos_X-Buf_LPOS_X)*SND_POS_FACTOR
S2SndPos_Y : float; --Sound Relative Position from Listener=(S2Pos_Y-Buf_LPOS_Y)*SND_POS_FACTOR
Distance_SL : float; --Distance Source-Listener * Sound_Factor
Vel_Snd_X : float; --Plane Velocity for Sound, SND_SPD_FACTOR * (X2-X1)/Intr_cycle
Vel_Snd_Y : float; --Plane Velocity for Sound, SND_SPD_FACTOR * (Y2-Y1)/Intr_cycle
Speed_Angle : float :=0.0; --Plane Angle [rad]
Speed_NOM : float; --Plane Speed Nominal Scalar
Speed_Pix : float; --Plane Speed Pixel Scalar
Time_X, Time_Y : Float; --Figure Tracing Timer counter
Draw_Listener_Counter : Integer :=0; --Counter how many times Draw_Listener called by System
Draw_Plane_Counter : Integer := 0; --Counter how many times Draw_Plane called by System
Step_Counter : Integer := 0; --Set STEP mode, how many Interrupts, downcounter, preset=STEP_NUMBER.
STEP_NUMBER : constant := 3; --How many steps for "Step". It presets Step_Counter
PLANE_BODY_COLOR : constant Gdk.RGBA.Gdk_RGBA := (0.0, 0.0, 0.8, 1.0); --RGBA (Blue)
end Gui;
GUI_Body
with Audio; use Audio;
with Tintr; use Tintr;
package body Gui is
-------------------------------
-- Valiables
------------------------------
Box : Gtk_Box;
HBox1, HBox2 : Gtk_Box;
Scrolled : Gtk_Scrolled_Window;
CanvasG : Image_Canvas;
DrawPic : Image_Drawing; --Picture
VBoxL : Gtk_Box; --Left pane
VBoxL1, VBoxL2 : Gtk_Box; --Left pane upper and lower boxes
PixG : Gdk_Pixbuf;
Item0 : Display_Item; --This is DUMMY, but it is needed to work properly.
Item1 : Display_Item; --Plane Item. Plane is drawn on this Item.
Items_List : array (1 .. 500) of Gtkada.Canvas.Canvas_Item;
Draw1_Before : Integer := 0; --for debug
Filled, Black_Filled : Drawing_Style;
Sloppy : Boolean := False;
-----------------------------------------------------------
--Button_START SINGLE Callback
------------------------------------------------------------
procedure Button_Single_Cb
(Canvas : access Interactive_Canvas_Record'Class) is
begin
Draw_Listener_Counter := 0; --Counter, how many times the photo Draw called for debug
If (Start_Flag=0) then --Normal Start turns ON
--If SINGLE button is pressed from OFF to ON then start up.
ALSound_Initialize;
S1Pos_X := 0.0; --Save for next Direction Calc
S1Pos_Y := 0.0; --Save for next Direction Calc
Start_Flag := 1;
Pause_Flag := 0;
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
elsif((Start_Flag=1) or (Start_Flag=2)) then --working or Pausing Single
If (Pause_Flag=0) then
--Switch SINGLE to PAUSE
Pause_Flag := 1; --PAUSE
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Red", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
else --Now PAUSE, then switch to continue Single again
--Switch PAUSE to SINGLE (Re-starting)
Pause_Flag := 0;
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
end if;
else --In the other modes and pressed Single button
-- Switch to SINGLE mode and go again
Pause_Flag := 0;
Start_Flag := 2; --SINGLE and CONTINUE flag
--If button is pressed from ON to OFF then stop
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
-- OpenAL.Context.Close_Device (Audio.CX_Devicet); -- CLOSE "OpenAL Soft"
end if;
-- Show_All (CanvasG);
end Button_Single_Cb;
-----------------------------------------------------------
--Button_START LOOP Callback
------------------------------------------------------------
procedure Button_Loop_Cb
(Canvas : access Interactive_Canvas_Record'Class) is
begin
Draw_Listener_Counter := 0; --Counter, how many times the photo Draw called for debug
If (Start_Flag=0) then --Normal Start turns ON
--If button is pressed from OFF to ON then start up.
ALSound_Initialize;
S1Pos_X :=0.0; --Previous locaction X = 0
S1Pos_Y :=0.0; --Previous locaction Y = 0
Start_Flag := 5;
Pause_Flag := 0;
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
elsif((Start_Flag=5) or (Start_Flag=6)) then --LOOPing or Pausing LOOP
If (Pause_Flag=0) then
--Not PAUSE, then Switch LOOP to PAUSE
Pause_Flag := 1; --PAUSE
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Red", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
else --Now PAUSE, then switch to continue Single again
--PAUSE, then Switch PAUSE to LOOP
Pause_Flag := 0;
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
end if;
else --In the other modes and pressed LOOP button
-- Switch to LOOP mode and go again
Pause_Flag := 0;
Start_Flag := 6; --LOOP and CONTINUE flag
--If button is pressed from ON to OFF then stop
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
-- OpenAL.Context.Close_Device (Audio.CX_Devicet); -- CLOSE "OpenAL Soft"
end if;
-- Show (Gval.Box);
-- Show_All (CanvasG);
end Button_Loop_Cb;
------------------------------------------------------------
--Button_STEP Callback
-- NOTE STEP cannot stop
------------------------------------------------------------
procedure Button_Step_Cb
(Canvas : access Interactive_Canvas_Record'Class) is
begin
Draw_Listener_Counter := 0; --Counter, how many times the photo Draw called for debug
If (Start_Flag=0) then --Normal Start turns ON
--If button is pressed from OFF to ON then start STEP.
ALSound_Initialize;
S1Pos_X :=0.0; --Previous locaction X = 0
S1Pos_Y :=0.0; --Previous locaction Y = 0
Step_Counter := STEP_NUMBER; --Preset down-counter
Start_Flag := 3; --Flag=3: Start STEP
Pause_Flag := 0; --Reset WAIT counter
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
else
--Pressed STEP button at Working any mode or HALT, then Re-start STEP
Start_Flag := 3; --Flag=3: Start STEP
Pause_Flag := 0; --Reset WAIT counter
Step_Counter := STEP_NUMBER; --Preset Down-counter
Set_Label (Button_Loop, "Loop");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Single, "Single");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Blue", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
end if;
end Button_Step_Cb;
--------------------------------------------------------
-- Button CLEAR Callback
--------------------------------------------------------
procedure Button_Clear_Cb
(Canvas : access Interactive_Canvas_Record'Class) is
function Remove_Internal
(Canvas : access Interactive_Canvas_Record'Class;
Item : access GtkAda.Canvas.Canvas_Item_Record'Class) return Boolean is
begin
Remove (Canvas, Item);
return True;
end Remove_Internal;
begin
Start_Flag := 0;
Pause_Flag := 0;
Step_Counter := 0;
TimeCnt :=0;
S1Pos_X :=0.0; --Previous locaction X = 0
S1Pos_Y :=0.0; --Previous locaction Y = 0
TimerIntrCounter_Before := 0; --Used in Tintr
Set_Label (Gui.Button_Single, "Single");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Gui.Button_Loop, "Loop");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
OpenAL.Context.Close_Device (Audio.CX_Devicet); -- CLOSE "OpenAL Soft" and stop sound
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Display_Plane(10);
Put_Line("TimeCnt=" & Integer'Image(TimeCnt) & " S2PixPos_X= " & float'Image(S2PixPos_X) & " S2PixPos_Y" & float'Image(S2PixPos_Y));
end Button_Clear_Cb;
------------------------------------------------------------
-- Draw_#1 To_Double_Buffer -- Regular Rectangle
-- Plane Drawing
------------------------------------------------------------
procedure Draw
(Item : access Display_Item_Record;
Cr : Cairo_Context) is
Iw, Ih, Iwc, Ihc : Gdouble;
Ang : Float;
Icolor : Gdk.RGBA.Gdk_RGBA;
begin
if(TimerIntrCounter=TimerIntrCounter_Before) then
If (TimeCnt_Draw=0) then goto END_OF_DRAW; end if; --SKIP if counter is full (protect from too much display)
TimeCnt_Draw := TimeCnt_Draw - 1;
else
TimeCnt_Draw := TIMECNT_DRAW_PRESET; --Initialize down-counter
end if;
Ang := Speed_angle; --Radian, Angle from the Origin (positive X axis=0 deg, CW=Positive, Radian)
Iw := Gdouble(Item.w); --Image Width
Ih := Gdouble(Item.h); --Image Height
Iwc := 0.5 * Iw; --Image Rotation Center=a half Width
Ihc := 0.5 * Ih; --Image Rotation Center=a half Height
Icolor := Item.Color; --Save body color, Gdk.RGBA.Gdk_RGBA
--Draw exhaust flame Lower Half
Arc (Cr, Iwc+0.325*Iw*GDouble(Cos(3.5358+Ang)), Ihc+0.325*Iw*GDouble(Sin(3.5358+Ang)), 0.25*Iw, GDouble(0.5235+Ang), GDouble(2.618+Ang));
Set_Source_Rgb (Cr, 1.0, 0.5, 0.5); --Red
Cairo.Fill (Cr); -- Fill color
--Draw exhaust flame Upper Half
Arc (Cr, Iwc+0.325*Iw*GDouble(Cos(2.7462+Ang)), Ihc+0.325*Iw*GDouble(Sin(2.7462+Ang)), 0.25*Iw, GDouble(3.663+Ang), GDouble(5.757+Ang));
Set_Source_Rgb (Cr, 1.0, 0.5, 0.5);
Cairo.Fill (Cr); -- Fill color
--Draw Jet nozzle Circle
Item.Color := (1.0, 0.0, 0.0, 1.0); --Red color
Gdk.Cairo.Set_Source_RGBA (Cr, Item.Color);
Arc (Cr, Iwc+0.2*Iw*GDouble(Cos(Pi+Ang)), Ihc+0.2*Ih*GDouble(Sin(Pi+Ang)), 0.1*Iw, 0.0, 2.0*Pi);
Cairo.Fill (Cr); --Fill without outline
--Plane body
Move_To (Cr, Iwc+0.45*Iw*GDouble(cos(Ang)), Ihc+0.45*Ih*GDouble(sin(Ang))); --#1 Move to the Top
Line_To (Cr, Iwc+0.4060*Iw*GDouble(cos(0.1732+Ang)), Ihc+0.4060*Ih*GDouble(sin(0.1732+Ang))); --#2 Draw Lower Half
Line_To (Cr, Iwc+0.3569*Iw*GDouble(cos(0.1974+Ang)), Ihc+0.3569*Ih*GDouble(sin(0.1974+Ang))); --#3
Line_To (Cr, Iwc+0.3640*Iw*GDouble(cos(0.2783+Ang)), Ihc+0.3640*Ih*GDouble(sin(0.2783+Ang))); --#4
Line_To (Cr, Iwc+0.3162*Iw*GDouble(cos(0.3218+Ang)), Ihc+0.3162*Ih*GDouble(sin(0.3218+Ang))); --#5
Line_To (Cr, Iwc+0.3162*Iw*GDouble(cos(1.2490+Ang)), Ihc+0.3162*Ih*GDouble(sin(1.2490+Ang))); --#6
Line_To (Cr, Iwc+0.3000*Iw*GDouble(cos(1.5700+Ang)), Ihc+0.3000*Ih*GDouble(sin(1.5700+Ang))); --#7 90'
Line_To (Cr, Iwc+0.1414*Iw*GDouble(cos(0.7850+Ang)), Ihc+0.1414*Ih*GDouble(sin(0.7850+Ang))); --#8
Line_To (Cr, Iwc+0.1000*Iw*GDouble(cos(1.5700+Ang)), Ihc+0.1000*Ih*GDouble(sin(1.5700+Ang))); --#9 90'
Line_To (Cr, Iwc+0.2236*Iw*GDouble(cos(2.0330+Ang)), Ihc+0.2236*Ih*GDouble(sin(2.0330+Ang))); --#10
Line_To (Cr, Iwc+0.2500*Iw*GDouble(cos(2.2120+Ang)), Ihc+0.2500*Ih*GDouble(sin(2.2120+Ang))); --#11
Line_To (Cr, Iwc+0.1581*Iw*GDouble(cos(2.8180+Ang)), Ihc+0.1581*Ih*GDouble(sin(2.8180+Ang))); --#12
Line_To (Cr, Iwc+0.1118*Iw*GDouble(cos(2.6760+Ang)), Ihc+0.1118*Ih*GDouble(sin(2.6760+Ang))); --#13
Line_To (Cr, Iwc+0.1000*Iw*GDouble(cos(3.1410+Ang)), Ihc+0.1000*Ih*GDouble(sin(3.1410+Ang))); --#14 Tail center
Move_To(Cr, Iwc, Ihc); --Move to the Center, the Center is always the same position
Move_To (Cr, Iwc+0.45*Iw*GDouble(cos(Ang)), Ihc+0.45*Ih*GDouble(sin(Ang))); --#1 Move to the Top
Line_To (Cr, Iwc+0.406*Iw*GDouble(cos(2.0*Pi-0.1732+Ang)), Ihc+0.406*Ih*GDouble(sin(2.0*Pi-0.1732+Ang))); --#2 Draw upper half
Line_To (Cr, Iwc+0.3569*Iw*GDouble(cos(2.0*Pi-0.1974+Ang)), Ihc+0.3569*Ih*GDouble(sin(2.0*Pi-0.1974+Ang))); --#3
Line_To (Cr, Iwc+0.3640*Iw*GDouble(cos(2.0*Pi-0.2783+Ang)), Ihc+0.3640*Ih*GDouble(sin(2.0*Pi-0.2783+Ang))); --#4
Line_To (Cr, Iwc+0.3162*Iw*GDouble(cos(2.0*Pi-0.3218+Ang)), Ihc+0.3162*Ih*GDouble(sin(2.0*Pi-0.3218+Ang))); --#5
Line_To (Cr, Iwc+0.3162*Iw*GDouble(cos(2.0*Pi-1.249+Ang)), Ihc+0.3162*Ih*GDouble(sin(2.0*Pi-1.249+Ang))); --#6
Line_To (Cr, Iwc+0.3000*Iw*GDouble(cos(2.0*Pi-1.5700+Ang)), Ihc+0.3000*Ih*GDouble(sin(2.0*Pi-1.5700+Ang))); --#7 270'
Line_To (Cr, Iwc+0.1414*Iw*GDouble(cos(2.0*Pi-0.785 +Ang)), Ihc+0.1414*Ih*GDouble(sin(2.0*Pi-0.7850+Ang))); --#8
Line_To (Cr, Iwc+0.1000*Iw*GDouble(cos(2.0*Pi-1.570+Ang)), Ihc+0.1000*Ih*GDouble(sin(2.0*Pi-1.5700+Ang))); --#9 270'
Line_To (Cr, Iwc+0.2236*Iw*GDouble(cos(2.0*Pi-2.033+Ang)), Ihc+0.2236*Ih*GDouble(sin(2.0*Pi-2.033+Ang))); --#10
Line_To (Cr, Iwc+0.2500*Iw*GDouble(cos(2.0*Pi-2.212+Ang)), Ihc+0.2500*Ih*GDouble(sin(2.0*Pi-2.212+Ang))); --#11
Line_To (Cr, Iwc+0.1581*Iw*GDouble(cos(2.0*Pi-2.818+Ang)), Ihc+0.1581*Ih*GDouble(sin(2.0*Pi-2.818+Ang))); --#12
Line_To (Cr, Iwc+0.1118*Iw*GDouble(cos(2.0*Pi-2.676+Ang)), Ihc+0.1118*Ih*GDouble(sin(2.0*Pi-2.676+Ang))); --#13
Line_To (Cr, Iwc+0.1000*Iw*GDouble(cos(2.0*Pi-3.141+Ang)), Ihc+0.1000*Ih*GDouble(sin(2.0*Pi-3.141+Ang))); --#14
Close_Path (Cr); --Close Polygon to fill color
Item.Color := Icolor; --Return to the saved color
Gdk.Cairo.Set_Source_RGBA (Cr, Item.Color); --Paint the plane body
-- Gdk.Cairo.Set_Source_RGBA (Cr, Icolor); --NOTE: This does not work
Cairo.Fill (Cr); -- Fill color
Draw_Plane_Counter := Draw_Plane_Counter + 1; --Just to countup calling this Draw how many times
<< END_OF_DRAW >> --GOTO Jump Flag
TimerIntrCounter_Before := TimeCnt;
end Draw;
------------------------------------------------------------------
-- On_Draw_Listener_Image -- This On_Draw_Listener_Image is coming from libart_demo.adb
-- Display Picture image in LEFT VBoxL or RIGHT Canvas
------------------------------------------------------------------
function On_Draw_Listener_Image
(Draw : access Image_Drawing_Record'Class;
Cr : Cairo_Context) return Boolean is
begin
Text_IO.Put_Line("Width=" & Gint'Image(Get_Width(Draw.PixG)) & " Height=" & Gint'Image(Get_Height(Draw.PixG)));
Set_Source_Pixbuf (Cr, Draw.PixG, 0.0, 0.0);
Cairo.Paint (Cr); --Need to display picture
Cairo.Stroke (Cr);
Draw_Listener_Counter := Draw_Listener_Counter + 1;
return False;
end On_Draw_Listener_Image;
-----------------------------------------------------------
-- Initialize_Listener_Image -- to display Picture image
-- Called from "Run"
-----------------------------------------------------------
procedure Initialize_Listener_Image
(Draw : out Image_Drawing; --DrawPic
Pixbuf : Gdk_Pixbuf; --PixG
Title : String) is --"Initial Image"
Label : Gtk_Label;
begin
Draw := new Image_Drawing_Record;
Initialize_Vbox (Draw, Homogeneous => False, Spacing => 0);
Gtk_New (Label, Title);
Pack_Start (Draw, Label, Expand => False, Fill => False);
Draw.PixG := Pixbuf; --Picture
Set_Size_Request
(Draw,
Get_Width (Draw.PixG),
Get_Height (Draw.PixG) + Get_Allocated_Height (Label));
Gtk_New (Draw.Area);
Pack_Start (Draw, Draw.Area);
Expose_Cb.Object_Connect
(Draw.Area, Signal_Draw,
Expose_Cb.To_Marshaller (On_Draw_Listener_Image'Access),
Slot_Object => Draw);
end Initialize_Listener_Image;
---------------------------------------------------------------
-- Initialize Display Plane Items
---------------------------------------------------------------
procedure Initial_Plane_Item_Setup
(Canvas : access Interactive_Canvas_Record'Class) is
begin
-- Place a Dummy Item ***************************
-- Workaround for the first location (0,0) BUG and another BUG
Item0 := new Display_Item_Record;
Item0.Canvas := Interactive_Canvas (Canvas);
Item0.Color := (1.0, 1.0, 1.0, 0.0); -- RGBA Color=White
Item0.W := 0; -- Width=0
Item0.H := 0; -- Height=0
Set_Screen_Size (Item0, Item0.W, Item0.H);
Put (Canvas, Item0, 0, 0); --Dummy PUT, Location X=0,Y=0
--***********************************************
Item1 := new Display_Item_Record; --Draw #1
Item1.Canvas := Interactive_Canvas (Canvas);
Item1.Color := PLANE_BODY_COLOR; --Color: Gdk.RGBA.Gdk_RGBA
Item1.W := 140; --Figure W size
Item1.H := 140; --Figure H size
Item1.Num := 1;
Set_Screen_Size (Item1, 150, 150); --Item drawing area, wider than figure to rotate
end Initial_Plane_Item_Setup;
--------------------------------------------------------------
-- Calculate all Parameters of Source, Move and Display
--------------------------------------------------------------
Procedure Display_Plane
(Counter : in Integer) is
Begin
Calculate_Display_Sound (Counter); -- Calculate all
Move_To (CanvasG, Item1, Glib.Gint(S2PixPos_X), Glib.Gint(S2PixPos_Y)); --Important. Don't use Put for an Item multiple times.
Show_All (CanvasG);
End Display_Plane;
--------------------------------------------------------------
-- Calculate all Plane Location and Audio Parameters
--------------------------------------------------------------
Procedure Calculate_Display_Sound
(Counter : in Integer) is --TimeCnt
Just_Begin_Flag : Boolean;
Begin
If (Pause_Flag /= 0) then Return; end if;
If(S1Pos_X=0.0 and S1Pos_Y=0.0) then --If this is the first call, then set flag to skip some calculatios
Just_Begin_Flag := True;
else
Just_Begin_Flag := False;
end if;
-- Calculate Current P2 Location
S2Pos_X := float(Get_Value(OFFSET_X)) + Sin (2.0 * Pi / float(Get_Value(TIME_CYCLE_X)) * float(TINTR_PITCH) /1000.0 * Time_X); --Normalized 1+Sin(wt)
S2PixPos_X := float(Get_Value(PIXFACTOR_X)) * S2Pos_X; --For Display Absolute
S2SndPos_X := float(Get_Value(SND_POS_FACTOR)) * (S2Pos_X - Buf_LPOS_X); --For Sound Relative S-L
S2Pos_Y := float(Get_Value(OFFSET_Y)) + Cos (2.0 * Pi / float(Get_Value(TIME_CYCLE_Y)) * float(TINTR_PITCH) / 1000.0 * Time_Y); --Normalized 2+Cos(wt)
S2PixPos_Y := float(Get_Value(PIXFACTOR_Y)) * S2Pos_Y; --For Display Absolute
--- S2SndPos_Y := float(Get_Value(SND_POS_FACTOR)) * (Buf_LPOS_Y - S2Pos_Y); --For Sound Relative S-L
S2SndPos_Y := float(Get_Value(SND_POS_FACTOR)) * (S2Pos_Y - Buf_LPOS_Y); --For Sound Relative S-L
If (Just_Begin_Flag = False) then
--Not the first time, then calculate speed and direction
Vel_Snd_X := float(Get_Value(SND_SPD_FACTOR)) * (S2Pos_X - S1Pos_X) * 1000.0 / float(TINTR_PITCH); --For Sound_SPD_Factor * (X2-X1)/Intr_cycle
Vel_Snd_Y := float(Get_Value(SND_SPD_FACTOR)) * (S2Pos_Y - S1Pos_Y) * 1000.0 / float(TINTR_PITCH); --For Sound_SPD_Factor * (Y2-Y1)/Intr_cycle
If (Abs(S2Pos_X-S1Pos_X) <= 0.0001) then --To avoid 0 division
If (S2Pos_Y > S1Pos_Y) then
Speed_Angle := 0.5*Pi; --Pi/2rad=90deg, Protect Zero division
else
Speed_Angle := 1.5*Pi; --4.712rad=270 deg, Protect Zero division
end if;
else --Not 0, then normal calculatio
Speed_Angle := Abs(Arctan ((S2Pos_Y-S1Pos_Y)/(S2Pos_X-S1Pos_X))); --Right Lower(no correction)
If ((S2Pos_Y-S1Pos_Y)<0.0 and (S2Pos_X-S1Pos_X)>0.0) then --Right upper
Speed_Angle := 2.0*Pi - Speed_Angle;
elsif ((S2Pos_Y-S1Pos_Y)>=0.0 and (S2Pos_X-S1Pos_X)<0.0) then --Left Lower
Speed_Angle := Pi - Speed_Angle;
elsif ((S2Pos_Y-S1Pos_Y)<0.0 and (S2Pos_X-S1Pos_X)<0.0) then --Left Upper
Speed_Angle := Pi + Speed_Angle;
end if;
end if;
else -- First time, INITIAL, just started
Speed_Angle := 0.0;
Vel_Snd_X := 0.0;
Vel_Snd_Y := 0.0;
end if;
Distance_SL := SQRT (S2SndPos_X**2 + S2SndPos_Y**2); --Use Sound,because Relative
S1Pos_X := S2Pos_X; --Save for next Direction Calc
S1Pos_Y := S2Pos_Y; --Save for next Direction Calc
--Display Labels
Set_Label (Gui.Label_TCnt, "TimeCnt=" & Integer'Image(TimeCnt));
FixPnt006 := FixedPoint0016(S2SndPos_X);
Set_Label (Gui.Label_S2SndPOS_X, "SndPos_X=" & FixedPoint0016'Image(FixPnt006));
FixPnt006 := FixedPoint0016(S2SndPos_Y);
Set_Label (Gui.Label_S2SndPos_Y, "SndPos_Y=" & FixedPoint0016'Image(FixPnt006));
FixPnt006 := FixedPoint0016(Vel_Snd_X);
Set_Label (Gui.Label_SndVel_X, "SndVel_X=" & FixedPoint0016'Image(FixPnt006));
FixPnt006 := FixedPoint0016(Vel_Snd_Y);
Set_Label (Gui.Label_SndVel_Y, "SndVel_Y=" & FixedPoint0016'Image(FixPnt006));
FixPnt008 := FixedPoint0018(Speed_Angle);
Set_Label (Gui.Label_Speed_Angle, "Angle=" & FixedPoint0018'Image(FixPnt008));
Set_Label (Gui.Label_Start_Flag, "Start_Flag=" & Integer'Image(Start_Flag));
--Display on Text Screen
Text_IO.Put("TimeCnt=" & Integer'Image(TimeCnt));
Text_IO.Put(" Pos_X=");
Ada.Float_Text_IO.Put(S2Pos_X, 4,2,0); --Item, Fore, Aft, Exp
Text_IO.Put(" Pos_Y=");
Ada.Float_Text_IO.Put(S2Pos_Y, 4,2,0); --Item, Fore, Aft, Exp
Text_IO.Put(" L=");
Ada.Float_Text_IO.Put(Distance_SL, 4,2,0); --Item, Fore, Aft, Exp
Put_Line(" Draw1=" & Integer'Image(Draw_Plane_Counter) & " Diff=" & Integer'Image(Draw_Plane_Counter - Draw1_Before)
& " Pause_F=" & Integer'Image(Pause_Flag));
Draw1_Before := Draw_Plane_Counter;
End Calculate_Display_Sound;
-------------------------------------------------------------------
-- Set Listner location, set Spins LPOS_X & LPOS_Y to Buffers
-------------------------------------------------------------------
procedure On_Listner_Loc (Spin : access GObject_Record'Class) is
S : constant Gtk_Spin_Button := Gtk_Spin_Button (Spin);
X, Y : Glib.Gint;
Begin
Buf_LPOS_X := float(Get_Value(LPOS_X));
X := Glib.Gint(Buf_LPOS_X * float(Get_Value(PIXFACTOR_X))); --Glib.Gint
Buf_LPOS_Y := float(Get_Value(LPOS_Y));
Y := Glib.Gint(Buf_LPOS_Y * float(Get_Value(PIXFACTOR_Y)));
Move (CanvasG, DrawPic, X, Y); --To move the picture NOT "Cairo.Move_To" , use this Move command
end On_Listner_Loc;
-------------------------------------------------------
-- Run --
-------------------------------------------------------
procedure Run (Frame : access Gtk.Frame.Gtk_Frame_Record'Class) is
Label : Gtk_Label;
Error : Glib.Error.GError;
X, Y : Glib.Gint;
TempBox : Gtk_Box; --Spin setting
TempLabel : Gtk_Label; --Spin label setting
TempAdj : Gtk_Adjustment; --Spin setting
begin
Gtk_New_Vbox (Box, Homogeneous => False); --All screen
Add (Frame, Box); --Box.Add
Gtk_New_Hbox (Hbox1, Homogeneous => False); --Top Buttons Box, if True:Wide buttons, Faluse:Narrow
Pack_Start (Box, Hbox1, Expand => False, Fill => False);
Gtk_New_Hbox (HBox2, Homogeneous => False); --L pane +R Canvas. False:narrow, True: 50%/50%
Pack_Start (Box, HBox2, Expand => True, Fill => True);
Gtk_New_Vbox (VBoxL, Homogeneous => False); --LEFT Pane Box, If True then VBoxL1/VBoxL2=50%/50%
Pack_Start (HBox2, VBoxL, False, True, 30); -- 30 is VBoxL1/VBoxL2 portion of VBox2 Width
-- Pack_Start (HBox2, VBoxL, Expand=>False, Fill=>False); --Left pane is minimum
-- Pack_Start (HBox2, VBoxL, Expand=>True, Fill=>True); --50%/50%
-- Pack_Start (HBox2, VBoxL, Expand=>True, Fill=>False); --50%/50%
Gtk_New_VBox (VBoxL1, Homogeneous => False); --LEFT Pane Upper status area Box
Pack_Start (VBoxL, VBoxL1, False, True, 0);
Gtk_New_VBox (VBoxL2, Homogeneous => False); --LEFT Pane Lower Spin area Box
Pack_Start (VBoxL, VBoxL2, False, True, 0);
Gtk_New (Scrolled); --RIGHT Canvas Box
Pack_Start (HBox2, Scrolled, True, True); --Main-RIGHT Canvas is all remained area (wide)
CanvasG := new Image_Canvas_Record;
Gtkada.Canvas.Initialize (CanvasG);
Add (Scrolled, CanvasG);
--"Single" Button
Gtk_New (Button_Single, "Single");
Pack_Start (HBox1, Button_Single, Expand => False, Fill => True);
Canvas_Cb.Object_Connect
(Button_Single, "clicked",
Canvas_Cb.To_Marshaller (Button_Single_Cb'Access), CanvasG);
--"Loop" Button
Gtk_New (Button_Loop, "Loop");
Pack_Start (HBox1, Button_Loop, Expand => False, Fill => True);
Canvas_Cb.Object_Connect
(Button_Loop, "clicked",
Canvas_Cb.To_Marshaller (Button_Loop_Cb'Access), CanvasG);
--"Step" Button
Gtk_New (Button_Step, "Step");
Pack_Start (HBox1, Button_Step, Expand => False, Fill => True);
Canvas_Cb.Object_Connect
(Button_Step, "clicked",
Canvas_Cb.To_Marshaller (Button_Step_Cb'Access), CanvasG);
--"Clear" Button
Gtk_New (Button_Clear, "Clear");
Pack_Start (HBox1, Button_Clear, Expand => False, Fill => True);
Canvas_Cb.Object_Connect
(Button_Clear, "clicked",
Canvas_Cb.To_Marshaller (Button_Clear_Cb'Access), CanvasG);
--Left Pane Labels (Upper VBoxL1)
Gtk_New (Label_Dummy1, " "); --Dummy for clearance
Pack_Start(VBoxL1, Label_Dummy1, Expand=>False, Fill=>True);
Gtk_New (Label_TCnt, "TimeCnt= ");
Pack_Start(VBoxL1, Label_TCnt, Expand=>False, Fill =>True);
Gtk_New (Label_S2SndPos_X, "SndPos_X= ");
Pack_Start(VBoxL1, Label_S2SndPos_X, Expand=>False, Fill=>True);
Gtk_New (Label_S2SndPos_Y, "SndPos_Y= ");
Pack_Start(VBoxL1, Label_S2SndPos_Y, Expand=>False, Fill=>True);
Gtk_New (Label_SndVel_X, "SndVel_X= ");
Pack_Start(VBoxL1, Label_SndVel_X, Expand=>False, Fill=>True);
Gtk_New (Label_SndVel_Y, "SndVel_Y= ");
Pack_Start(VBoxL1, Label_SndVel_Y, Expand=>False, Fill=>True);
Gtk_New (Label_Speed_Angle, "Angle= ");
Pack_Start(VBoxL1, Label_Speed_Angle, Expand=>False, Fill=>True);
Gtk_New (Label_Start_Flag, "Start_Flag= ");
Pack_Start(VBoxL1, Label_Start_Flag, Expand=>False, Fill=>True);
Gtk_New (Label_Dummy1, " "); --Dummy for clearance
Pack_Start(VBoxL1, Label_Dummy1, Expand=>False, Fill=>True);
--"OFFSET_X" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "OFFSET_X");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 1.0, 0.2, 3.0, 0.1, 0.2); --Initial, Min, Max, Step, Page (Gtk.Adjustment)
Gtk_New (OFFSET_X, TempAdj, 0.01, 2); --Spin,Adj, Step, Digits after DP (Gtk.Spin_Button)
Pack_Start (TempBox, OFFSET_X, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"OFFSET_Y" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "OFFSET_Y");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 1.0, 0.2, 5.0, 0.1, 0.2); --Initial, Min, Max, Step, Page (Gtk.Adjustment)
Gtk_New (OFFSET_Y, TempAdj, 0.01, 2);
Pack_Start (TempBox, OFFSET_Y, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"PIXFACTOR-X" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "PIXFACTOR_X");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 350.0, 200.0, 500.0, 10.0, 20.0);
Gtk_New (PIXFACTOR_X, TempAdj, 1.0, 0);
Pack_Start (TempBox, PIXFACTOR_X, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"PIXFACTOR-Y" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "PIXFACTOR_Y");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 180.0, 50.0, 300.0, 10.0, 20.0);
Gtk_New (PIXFACTOR_Y, TempAdj, 1.0, 0);
Pack_Start (TempBox, PIXFACTOR_Y, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--SON_POS_FACTOR" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "SND_POS_FACTOR");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 30.0, 1.0, 500.0, 1.0, 10.0);
Gtk_New (SND_POS_FACTOR, TempAdj, 1.0, 0);
Pack_Start (TempBox, SND_POS_FACTOR, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--SND_SPD_FACTOR" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "SND_SPD_FACTOR");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 200.0, 1.0, 500.0, 1.0, 10.0);
Gtk_New (SND_SPD_FACTOR, TempAdj, 1.0, 0);
Pack_Start (TempBox, SND_SPD_FACTOR, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"TIME_CYCLE_X" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "TIME_CYCLE_X");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 10.0, 3.0, 30.0, 1.0, 2.0);
Gtk_New (TIME_CYCLE_X, TempAdj, 1.0, 0);
Pack_Start (TempBox, TIME_CYCLE_X, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"TIME_CYCLE_Y" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "TIME_CYCLE_Y");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 10.0, 3.0, 30.0, 1.0, 2.0);
Gtk_New (TIME_CYCLE_Y, TempAdj, 1.0, 0);
Pack_Start (TempBox, TIME_CYCLE_Y, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
--"LPOS_X" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "LPOS_X");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 1.0, 0.2, 3.0, 0.01, 0.1);
Gtk_New (LPOS_X, TempAdj, 0.01, 2);
Pack_Start (TempBox, LPOS_X, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
TempAdj.On_Value_Changed(On_Listner_Loc'Access,LPOS_X);
--"LPOS_Y" Spin
Gtk_New_VBox (TempBox, Homogeneous => False); --LEFT Pane upper status area Box
Gtk_New (TempLabel, "LPOS_Y");
Pack_Start (TempBox, TempLabel, Expand => False, Fill => False);
Gtk_New (TempAdj, 2.8, 0.5, 5.0, 0.01, 0.1); --Initial, Min, Max, Step, Page (Gtk.Adjustment)
Gtk_New (LPOS_Y, TempAdj, 0.01, 2); --Spin,Adj, Step, Digits after DP (Gtk.Spin_Button)
Pack_Start (TempBox, LPOS_Y, Expand => False, Fill => False);
Pack_Start (VBoxL2, TempBox, Expand => False, Fill => False);
TempAdj.On_Value_Changed(On_Listner_Loc'Access,LPOS_Y);
--Setup Canvas background color and location
Align_On_Grid (CanvasG, False); --Locate dragged Object on the nearest grid or not.
Configure (CanvasG,
Grid_Size=>0, --Size=0 is no grid on the Canvas, 10=10dot pitch
Background=>(0.01,0.01,0.01,0.03)); --Canvas Back color: RGBA, Gdk.RGBA.Gdk_RGBA := Gdk.RGBA.White_RGBA);
--Display Listner Picture image in RIGHT CANVAS ************
Gdk_New_From_File (PixG, "./BackShot140140.png", Error);
if PixG = Null_Pixbuf then --If Error:
Gtk_New (Label, "Pixmaps #1 not found. Please run testgtk from the"
& " testgtk/ directory itself.");
Add (VBoxL, Label);
Show_All (VBoxL);
return;
end if;
Initialize_Listener_Image (DrawPic, PixG, "Listener"); --Set Picture. New Original Procedure Initialize_Listener_Image
--Display Listner Image
Buf_LPOS_X := float(Get_Value(LPOS_X));
X := Glib.Gint(Buf_LPOS_X * float(Get_Value(PIXFACTOR_X))); --Glib.Gint
Buf_LPOS_Y := float(Get_Value(LPOS_Y));
Y := Glib.Gint(Buf_LPOS_Y * float(Get_Value(PIXFACTOR_Y)));
Put (CanvasG, DrawPic, X, Y); --Display Listener Photo image
--Display Source Image
Initial_Plane_Item_Setup (CanvasG); --Setup Item1
Put (CanvasG, Item1, 2, 200); ---Gtkada.Canvas.Put(), Display Plane Graphics at the initial position
-- Refresh_Canvas (CanvasG);
-- Show_Item (CanvasG, Item1);
-- Show_All (FrameM);
end Run;
end Gui;
Audio_Specification
with Gtk.Widget; use Gtk.Widget;
with Gtk.Handlers; use Gtk.Handlers;
with Interfaces; use Interfaces;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
with Ada.Sequential_IO; --use Ada.Sequential_IO; --cannot use "use" for this generic package
with OpenAL.Context; use OpenAL.Context; --use is needed
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 OpenAL.Global; use OpenAL.Global; --for Get_Doppler_Factor
Package Audio is
package Handlers is new Gtk.Handlers.Callback --Need with Gtk.Handlers
(Widget_Type => Gtk_Widget_Record); --Need with Gtk.Widget
Function Test_Error (Display_Message : String) return Boolean;
WAVE_FILE_NAME : constant string := "testsound.wav";
Function LoadWaveFile(
WaveFile: in String; -- WAV 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;
Procedure ALSound_Initialize;
Procedure ALSound_Process;
---------------------------------------
--CONSTANT
---------------------------------------
LISTENER_GAIN : constant := 10.0;
---------------------------------------
-- GLOBAL VARIABLES
---------------------------------------
CX_Devicet : OpenAL.Context.Device_t; --Used when Open and Close Audio Context
Sound_Source : OpenAL.Source.Source_t;
Sound_Source_Array : OpenAL.Source.Source_Array_t(1..1);
end Audio;
Audio_Body
with Ada.Text_IO; use Ada.Text_IO;
with Gui; use Gui;
Package body Audio is
---------------------------------------------------------
-- Function: Display OpenAL Procedure/Function Result
-- In: OpenAL result Code number
-- Out: Boolean result. Good=True, Error=False
-- Note; Function Get_Error doesn't work perfectly
-- Note; 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 string and output valiable addresses,
-- OUT: Boolean result Good=True, Error=False
---------------------------------------------------------
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 --True=Success, False=Error
---
type Sample_16_t is range -32768 .. 32767;
for Sample_16_t'Size use 16;
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;
--"data" was found, then get next Subchunk2Size
Read(FT, K1);
WAttrb(Cnt):=K1; -- Lower 16bit of Data number of BYTE Length 32bit
Cnt := Cnt + 1;
Read(FT, K2);
WAttrb(Cnt):=K2; -- Upper 16bit
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); --Positive
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;
Put_Line("DataCnt=" & Integer'Image(DataCnt) & " Integer(Length)/2+1=" & Integer'Image(Integer(Length)/2+1));
--Result is: DataCnt= 220501 Integer(Length)/2+1= 220501
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;
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
-- Sound Initialize
-- Open Wav file and setup all parameters, but
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
Procedure ALSound_Initialize is
Bool : Boolean;
NrPlayback_Devices : Integer;
Vector_Cnt : Integer;
Playback_StrVectt : OpenAL.List.String_Vector_t;
UB_OpenAL_Version : Unbounded_String;
UB_Default_Play : Unbounded_String;
UB_Playback_Devices : Unbounded_String;
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, 2.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
SoundWaveFileName : String := WAVE_FILE_NAME; --"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;
begin
Put_Line("OpenAL Program Sample1");
--***********
--Get OpenAL Version number
--***********
-- UB_OpenAL_Version := To_Unbounded_String(OpenAL.Global.Vendor); --"Version" causes error. Not supported.
--***********
--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
-- Same the old 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 Words
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 proc is not written in the manual, it is in OpenAL.Thin source.
-- 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); --Gval.Sound_Source_Array(1..1) only one array
Sound_Source := Sound_Source_Array(1); --Sound_Source:Source_t
If (Test_Error("Generate-Sources (Gval.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 Position, Velocity, Direction
-- 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 Position, Velocity, Direction
-- 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;
---****************
--****************
-- Set Listener GAIN
--****************
OpenAL.Listener.Set_Gain(LISTENER_GAIN);
<< END_OF_PROGRAM >> -- label for goto when Error
end ALSound_Initialize;
-------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------
-- Output Audio Control Process
-- Called by Timer Interrupt when Start_Flag /= 0
-------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------
Procedure ALSound_Process is
Begin
-- Set Source, Listener Position
OpenAL.Source.Set_Position_Float(Sound_Source, OpenAL.Types.Float_t(S2SndPos_X) , OpenAL.Types.Float_t(S2SndPos_Y) , 0.0); -- Left(-) to Right(+), XYZ Float
OpenAL.Listener.Set_Position_Float(0.0 , 0.0 , 0.0); -- Listner is Origin=0,0,0. Source uses Relative distance from Listener.
-- Set Velocity
OpenAL.Source.Set_Velocity_Float(Sound_Source, OpenAL.Types.float_t(Vel_Snd_X), OpenAL.Types.float_t(Vel_Snd_Y), 0.0); -- Increase from 0, XYZ Float
end ALSound_Process;
----------------------------------------------------------------------------------------------------------
End Audio;
Timer_Interrupt_Specification
with OpenAL.Context;
with OpenAL.List;
with OpenAL.Types;
with OpenAL.Buffer;
with OpenAL.Error;
with OpenAL.Listener;
with OpenAL.Source;
with OpenAL.Thin;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Button; use Gtk.Button;
with Gtk.Enums; use Gtk.Enums;
with Gtk.Spin_Button; use Gtk.Spin_Button;
with Gtk.Progress_Bar; use Gtk.Progress_Bar; --Timer Interrupt
with Ada.Real_Time; use Ada.Real_Time; --Timer Interrupt
with Glib.Main; use Glib.Main; --Timer Interrupt Time_Cb.Timeout_Add
with Gdk.RGBA; use Gdk.RGBA;
with Text_IO; use Text_IO;
package Tintr is
function Timer_Intr (Pbar : Gtk_Progress_Bar) return Boolean;
TimerIntrDuration : Time_Span; --need with Ada.Real_Time
TimerIntrCounter : integer := 0;
TINTR_PITCH : Constant := 100; --100=100ms, 200=200ms
TIMECNT_DRAW_PRESET : Constant := 4; --In Draw, countdown TimeCnt_Draw preset value
TimeCnt : Integer := TIMECNT_DRAW_PRESET; --Playback Time/Location/Speed Counter
TimerIntrCounter_Before : Integer :=0; --In Draw, check if TimeCnt is same or changed
TimeCnt_Draw : integer :=0; --In Draw, count how many Draw is accepted in a TimeCnt
Direction : Integer := 0; --0=Positive(to right), 1=Negative (to Left)
Datatype_dummy : Gtk_Progress_Bar; --Timer interrupt
EndFlag : Integer; --Playback loop End Flag
Gid_dummy : G_Source_Id; --Timer interrupt
Start_Flag : Integer := 0; --0=stop,1=Single Start,2=Single busy, 3=Step Start, 4=Step busy,5=Loop start,6=Loop busy
Pause_Flag : Integer := 0; --default=0, Pause=1
end Tintr;
Timer_Interrupt_Body
with Gui; use Gui;
with Audio; use Audio;
Package body Tintr is
--------------------------------------------------------
--------------------------------------------------------
--TIMER INTERRUPT
--------------------------------------------------------
--------------------------------------------------------
function Timer_Intr (Pbar : Gtk_Progress_Bar) return Boolean is
begin
If(Start_Flag =0) then --Flag=0 Nothing to do
TimerIntrCounter := TimerIntrCounter + 1;
TimeCnt := 0;
Time_X := 0.0;
Time_Y := 0.0;
Return True;
end if;
--------------------
-- Display Graphics and Audio Output
--------------------
Display_Plane (TimeCnt); --Calculate and Move Plane
ALSound_Process; --Set Audio Source & Listner Position XYZ and Source Velocity XYZ
if (Pause_Flag=1) then --Pause, then do nothing (keep audio and position)
TimerIntrCounter := TimerIntrCounter + 1;
Return True;
end if;
if ((Start_Flag=1) or (Start_Flag=3) or (Start_Flag=5)) then
--Button was pressed, Begin Audio
OpenAL.Source.Set_Looping(Audio.Sound_Source, Looping => True); --Manual doc is wrong
OpenAL.Source.Play (Audio.Sound_Source_Array(1));
Put_Line("Play(Sound_Source)");
If ((Start_Flag=1) or (Start_Flag=5)) then
TimeCnt := 0; --Initialize
end if;
Start_Flag := Start_Flag + 1; --Flag 1=>2, 3=>4, 5=>6
end if;
--STEP mode and Counter is busy
If (Start_Flag=4) then --STEP mode
If (Step_Counter /= 0) then
Step_Counter := Step_Counter - 1;
If (Step_Counter = 0) then
Pause_Flag := 1;
Set_Label (Button_Step, "Step"); --Turn to stop STEP
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
end if;
end if;
end if; --End Start_Flag=1,3,5
TimerIntrCounter := TimerIntrCounter +1;
TimeCnt := TimeCnt + 1;
Time_X := Time_X +1.0;
If ((Time_X * float(TINTR_PITCH) /1000.0) >= float(Get_Value(TIME_CYCLE_X))) then
--Timer(X) is full, Plane is at the start position, then one loop was finished.
Time_X := 0.0;
If (Start_Flag=2) then --Single loop complted, then stop the process.
--Single mode and End cycle. Finish Single process
Start_Flag := 0;
Pause_Flag := 0;
Set_Label (Gui.Button_Single, "Single");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Single), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Gui.Button_Loop, "Loop");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Loop), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
Set_Label (Button_Step, "Step");
Parse (ButtonColor, "Black", Dummy_Boolean);
Gtk.Widget.Override_Color(Gtk_Widget(Button_Step), Gtk_State_Flag_Normal ,ButtonColor); --Button Character Color is switched to Red, Modify is obsolete
OpenAL.Context.Close_Device (Audio.CX_Devicet); -- CLOSE "OpenAL Soft" and stop sound
Return True;
end if;
--On the way processing
end if;
Time_Y := Time_Y +1.0;
If ((Time_Y * float(TINTR_PITCH) /1000.0) >= float(Get_Value(TIME_CYCLE_Y))) then
Time_Y := 0.0;
end if;
Return True;
end Timer_Intr;
End Tintr;
Common_Programs_Specification
with Gtk.Main; use Gtk.Main;
with Gtk; use Gtk;
with Gtk.Adjustment; use Gtk.Adjustment;
with Gtk.Button; use Gtk.Button;
with Gtk.Check_Button; use Gtk.Check_Button;
with Gtk.Dialog; use Gtk.Dialog;
with Gtk.Label; use Gtk.Label;
with Gtk.Handlers; use Gtk.Handlers;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Window; use Gtk.Window;
with Glib; use Glib;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Gdk.Event; use Gdk.Event;
package Common is
package Widget_Handler is new Handlers.Callback (Gtk_Widget_Record);
package User_Widget_Handler is new Handlers.User_Callback
(Gtk_Widget_Record, Gtk_Widget);
package Label_Handler is new Handlers.Callback (Gtk_Label_Record);
package Adj_Handler is new Handlers.Callback (Gtk_Adjustment_Record);
package Check_Handler is new Handlers.Callback (Gtk_Check_Button_Record);
package Button_Handler is new Handlers.Callback (Gtk_Button_Record);
type Gtk_Window_Access is access all Gtk_Window;
package Destroy_Handler is new Handlers.User_Callback
(Gtk_Window_Record, Gtk_Window_Access);
function Delete_Event_Cb
(Self : access Gtk_Widget_Record'Class;
Event : Gdk.Event.Gdk_Event)
return Boolean;
procedure Destroy_Window
(Win : access Gtk.Window.Gtk_Window_Record'Class;
Ptr : Gtk_Window_Access);
type Gtk_Dialog_Access is access all Gtk_Dialog;
package Destroy_Dialog_Handler is new Handlers.User_Callback
(Gtk_Dialog_Record, Gtk_Dialog_Access);
procedure Destroy_Dialog (Win : access Gtk_Dialog_Record'Class;
Ptr : Gtk_Dialog_Access);
end Common;
Common_Programs_Body
package body Common is
---------------------
-- Delete_Event_Cb --
---------------------
function Delete_Event_Cb
(Self : access Gtk_Widget_Record'Class;
Event : Gdk.Event.Gdk_Event)
return Boolean is
begin
Gtk.Main.Main_Quit;
return True;
end Delete_Event_Cb;
--------------------
-- Destroy_Window --
--------------------
procedure Destroy_Window
(Win : access Gtk.Window.Gtk_Window_Record'Class;
Ptr : Gtk_Window_Access) is
begin
Ptr.all := null;
end Destroy_Window;
--------------------
-- Destroy_Dialog --
--------------------
procedure Destroy_Dialog
(Win : access Gtk.Dialog.Gtk_Dialog_Record'Class;
Ptr : Gtk_Dialog_Access) is
begin
Ptr.all := null;
end Destroy_Dialog;
end Common;
Global_Variables_Specification
--GLOBAL VALIABLES (.ADS only)
with Gtk.Box; use Gtk.Box;
with Gtk.Label; use Gtk.Label;
with Gtk.Button; use Gtk.Button;
with Gtk.Window; use Gtk.Window;
with Gtk.Fixed; use Gtk.Fixed; --To layout Button
with Ada.Real_Time; use Ada.Real_Time;
with Gtk.Progress_Bar; use Gtk.Progress_Bar;
--with Glib; use Glib;
--with Glib.Object; use Glib.Object;
--with Gtk.Frame; use Gtk.Frame;
--with Ada.Text_IO; use Ada.Text_IO;
--with Gtk.Fixed; use Gtk.Fixed; --To layout Button
--with Gtk.Spin_Button; use Gtk.Spin_Button;
--with Gtk.Toggle_Button; use Gtk.Toggle_Button;
with Gtk.Progress_Bar; use Gtk.Progress_Bar;
--with Ada.Real_Time; use Ada.Real_Time;
with Glib.Main; use Glib.Main; --Timer Interrupt Time_Cb.Timeout_Add
with OpenAL.Source;
with OpenAL.Context; use OpenAL.Context;
with OpenAL.Types;
package Gval is
Win : Gtk_Window; --Need with Gtk.Window
Fix : Gtk_Fixed;
Box1 : Gtk_Box;
Label1 : Gtk_Label;
Label2 : Gtk_Label;
Label3 : Gtk_Label;
Button1 : Gtk_Button;
Button2 : Gtk_Button;
-- Counter : Integer := 0;
CX_Devicet : OpenAL.Context.Device_t;
TimeCnt : Integer := 0; --Playback Time/Location/Speed Counter
Direction : Integer := 0; --0=Positive(to right), 1=Negative (to Left)
SetPosF, SetVelF : OpenAL.Types.Float_t; --Vector Calculation
SourcePositionF, SourceVelocityF : Float;
Sound_Source : OpenAL.Source.Source_t;
Sound_Source_Array : OpenAL.Source.Source_Array_t(1..1);
Datatype_dummy : Gtk_Progress_Bar; --Timer interrupt
Gid_dummy : G_Source_Id; --Timer interrupt
-- TIntr_Flag : Integer := 0; --0:before start
AudioFlag : Integer := 0;
AudioLoopFlag : Integer := 0;
TimerIntrDuration : Time_Span; --need with Ada.Real_Time
TimerIntrCounter : integer := 0;
TINTR_PITCH : Constant := 50; --100=50ms, 200=100ms
EndFlag : Integer; --Playback loop End Flag
end Gval;
Picture_of_Listener_140x140pix
1kHz_Sound_File
1kHz Tone
Format: PCM, Duration:5sec, Bitrate:705.6kbps, 1channel, Sampling rate:44.1kHz, 16bit, Size:431kB