-- computerman is multiway user tools.
-- Computerman is Copyright (C) 2024 Manuel De Girardi ; 
--
--   This program is free software; you can redistribute it and/or modify
--   it under the terms of the GNU General Public License as published by
--   the Free Software Foundation; either version 2 of the License, or
--   (at your option) any later version.
--
--   This program is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--   GNU General Public License for more details.
--
--   You should have received a copy of the GNU General Public License
--   along with this program; if not, write to the Free Software
--   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
--
-- Date := "2024-05-10 09:03:04"
-- Version := "0.0.0r"
package body Computer.Midi.Portmidi is
      function Pm_Message(Status, Data1, Data2 : Interfaces.C.Long) return Interfaces.C.Long is
      
      Message : Unsigned_32 := 0;
      Low     : constant Unsigned_32 := Unsigned_32(Data2);
      Middle  : constant Unsigned_32 := Unsigned_32(Data1);
      High    : constant Unsigned_32 := Unsigned_32(status);                       
   begin      
      Message := ((Shift_Left(Low, 16) and 16#FF0000#) or
		     (Shift_Left(middle, 8) and 16#FF00#) or
		     (high and 16#FF#));
		    
      return Interfaces.C.Long(Message);
   end Pm_Message;
   
   function Status(Message : Interfaces.C.long) return Interfaces.C.long is
      Status : constant Unsigned_32 := (Unsigned_32(Message) and 16#FF#);
   begin
      return Interfaces.C.Long(Status);
   end Status;

   
   function data1(Message : Interfaces.C.long) return Interfaces.C.long is
      data1 : constant Unsigned_32 := (Shift_Right(Unsigned_32(Message), 8) and 16#FF#);
   begin
      return Interfaces.C.Long(Data1);
   end data1;

   function Channel(Message : Interfaces.C.Long) return Interfaces.C.Long is
      channel : constant Unsigned_32 := Shift_left(Unsigned_32(Message), 1);
   begin
      return Interfaces.C.Long(Channel);
   
   end Channel;

   function data2(Message : Interfaces.C.long) return Interfaces.C.Long is
      Data2 : constant Unsigned_32 := (Shift_Right(Unsigned_32(Message), 16) and 16#FF#);
   begin
      return Interfaces.C.Long(Data2);
   end data2;

   --   /* Filter bit-mask definitions */
   --/** filter active sensing messages (0xFE): */
   function PM_FILT_ACTIVE return Unsigned_32 is --(1 << 0x0E)
      Filter : Unsigned_32 := 16#0E#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
					       --/** filter system exclusive messages (0xF0): */
   function PM_FILT_SYSEX return Unsigned_32 is --(1 << 0x00)      

      Filter : Unsigned_32 := 16#00#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   						--/** filter MIDI clock message (0xF8) */
   function PM_FILT_CLOCK return Unsigned_32 is --(1 << 0x08)
						--/** filter play messages (start 0xFA, stop 0xFC, continue 0xFB) */
      Filter : Unsigned_32 := 16#08#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_PLAY return Unsigned_32 is --((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B))
					       --/** filter tick messages (0xF9) */
      Filter : Unsigned_32 := 16#0A#;
   begin
      Filter := Shift_Left(Filter, 1) or Shift_Left(16#0C#, 1) or Shift_Left(16#0B#, 1);
      return Filter;
   end;
   function PM_FILT_TICK return Unsigned_32 is --(1 << 0x09)
					       --/** filter undefined FD messages */
      Filter : Unsigned_32 := 16#09#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_FD return Unsigned_32 is --(1 << 0x0D)      
					     --/** filter undefined real-time messages */
      Filter : Unsigned_32 := 16#0D#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_UNDEFINED return Unsigned_32 is --PM_FILT_FD
						    --/** filter reset messages (0xFF) */
   begin
      return PM_FILT_FD;
   end;
   
   function PM_FILT_RESET return Unsigned_32 is --(1 << 0x0F)
						--/** filter all real-time messages */
      Filter : Unsigned_32 := 16#0F#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   
   function PM_FILT_REALTIME return Unsigned_32 is --(PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \
						 --    PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK)
						 --/** filter note-on and note-off (0x90-0x9F and 0x80-0x8F */
   begin      
      return (PM_FILT_ACTIVE or PM_FILT_SYSEX or PM_FILT_CLOCK or PM_FILT_PLAY or PM_FILT_UNDEFINED or PM_FILT_RESET or PM_FILT_TICK);
   end;
   function PM_FILT_NOTE return Unsigned_32 is --((1 << 0x19) | (1 << 0x18))
					       --/** filter channel aftertouch (most midi controllers use this) (0xD0-0xDF)*/
      Filter : Unsigned_32 := 16#19#;
   begin
      Filter := Shift_Left(Filter, 1) or Shift_Left(16#18#, 1);
      return Filter;
   end;
   function PM_FILT_CHANNEL_AFTERTOUCH return Unsigned_32 is --(1 << 0x1D)
							     --/** per-note aftertouch (0xA0-0xAF) */
      Filter : Unsigned_32 := 16#1D#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   
   function PM_FILT_POLY_AFTERTOUCH return Unsigned_32 is --(1 << 0x1A)
							  --/** filter both channel and poly aftertouch */
      Filter : Unsigned_32 := 16#1A#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_AFTERTOUCH return Unsigned_32 is --(PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH)
						     --/** Program changes (0xC0-0xCF) */
   begin
      return (PM_FILT_CHANNEL_AFTERTOUCH or PM_FILT_POLY_AFTERTOUCH);
   end;
   function PM_FILT_PROGRAM return Unsigned_32 is --(1 << 0x1C)
						  --/** Control Changes (CC's) (0xB0-0xBF)*/
      Filter : Unsigned_32 := 16#1C#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_CONTROL return Unsigned_32 is --(1 << 0x1B)
						  --/** Pitch Bender (0xE0-0xEF*/
      Filter : Unsigned_32 := 16#1B#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_PITCHBEND return Unsigned_32 is --(1 << 0x1E)
						    --/** MIDI Time Code (0xF1)*/
      Filter : Unsigned_32 := 16#1E#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_MTC return Unsigned_32 is --(1 << 0x01)
					      --/** Song Position (0xF2) */
      Filter : Unsigned_32 := 16#01#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_SONG_POSITION return Unsigned_32 is --(1 << 0x02)
							--/** Song Select (0xF3)*/
      Filter : Unsigned_32 := 16#02#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_SONG_SELECT return Unsigned_32 is --(1 << 0x03)
						      --/** Tuning request (0xF6)*/
      Filter : Unsigned_32 := 16#03#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_TUNE return Unsigned_32 is --(1 << 0x06)
					       --/** All System Common messages (mtc, song position, song select, tune request) */
      Filter : Unsigned_32 := 16#06#;
   begin
      Filter := Shift_Left(Filter, 1);
      return Filter;
   end;
   function PM_FILT_SYSTEMCOMMON return Unsigned_32 is --(PM_FILT_MTC | PM_FILT_SONG_POSITION | PM_FILT_SONG_SELECT | PM_FILT_TUNE)
      
   begin
      return (PM_FILT_MTC or PM_FILT_SONG_POSITION or PM_FILT_SONG_SELECT or PM_FILT_TUNE);
   end;      

end Computer.Midi.Portmidi ;