-----------------------------------------------------
-- portmidi is Ada binding to C library "portmidi".
-----------------------------------------------------
--  Copyright (C) 2010 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 3 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, see <http://www.gnu.org/licenses/>.

-- French translation --

-----------------------------------------------------
-- porttime is Ada binding to C library "porttime".
-----------------------------------------------------
--  Copyright (C) 2010 Manuel De Girardi.

--  Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le
--  modifier suivant les termes de la ?GNU General Public License? telle que
--  publiée par la Free Software Foundation : soit la version 3 de cette
--  licence, soit (à votre gré) toute version ultérieure.

--  Ce programme est distribué dans l?espoir qu?il vous sera utile, mais SANS
--  AUCUNE GARANTIE : sans même la garantie implicite de COMMERCIALISABILITÉ
--  ni d?ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez la Licence Générale
--  Publique GNU pour plus de détails.

--  Vous devriez avoir reçu une copie de la Licence Générale Publique GNU avec
--  ce programme ; si ce n?est pas le cas, consultez :
--  <http://www.gnu.org/licenses/>.

-----------------------------------------------------
-- Author      : Manuel De Girardi
-- Date        : 2012/07/14
-- Version     : 0.0.2
-- unit type   : specification
-- Description : Ada binding to C library "portmidi".
-----------------------------------------------------

package body Libsens.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 Libsens.MIDI.PortMIDI;