with Ada.Numerics.Discrete_Random;

with Text_Io;                           use Text_Io;

package body Libsens.Data.BassDrum is
   
   package Bool_Rand is new Ada.Numerics.Discrete_Random(Boolean);   
   
   Bool_Gen : Bool_Rand.Generator;
   
   
   
   function Tribe(Den : in Den_Type) return Word16_Type is
      
      Resolution : Positive := 2**Den;
      Word16     : Word16_Type := 0;
   begin
      
      for I in 0..(Word16_Type'Size-1) loop
	 if I mod Resolution = 0 then
	    Word16 := Word16 + 2**I;
	 end if;
      end loop;
      return Word16;
   end Tribe;
   
   
   function Rand(Den : in Den_Type; Length : in Positive) return Word16_Type is
      
      Resolution : Positive := 2**Den;
      Word16     : Word16_Type := 0;
   begin
      
      for I in (Word16_Type'Size-1)-Length..Word16_Type'Size-1 loop
	 if I mod (64/Resolution) = 0 then
	    if Bool_Rand.Random(Bool_Gen) then
	       Word16 := Word16 + 2**I;
	       
	    end if;
	 end if;
      end loop;         
      return Word16;
   end Rand;
   
   task body BassDrum_Gen is
      End_Of_Task : Boolean := False;
      

      
      
      BassDrum_sentence : BassDrum_Sentence_Type;
      
      Foot : constant bassdrum_Value_type := 36;

      
      Power_count : Natural := 0;
   begin
      
      Bassdrum_sentence(foot).Key := Foot;
      BassDrum_sentence(foot).Sens := 100;
      
      
      while not End_Of_Task loop

	 
	 select	       

	       
	    accept Halt do
	       End_Of_Task := True;
	    end Halt;
	    exit;

	 or
	    
	    accept Respond(Filename : in String; Channel : in Channel_Type; Seq : in out Seq_Vectors.Vector) do
	       
	       
	       if Power_count = 3 then		  

		  BassDrum_sentence(foot).Sentence := Tribe(4) or Rand(4, 2**4);
		  Power_Count := 0;
	       else

		  BassDrum_sentence(foot).Sentence := Tribe(4);			
		  Power_Count := Power_Count + 1;
	       end if;	    
	       
	       
	       Pattern(From => BassDrum_sentence, Channel => channel, Seq => Seq);		  
	       
	    end Respond;
	 end select;

      end loop;
   end BassDrum_Gen;   
end Libsens.Data.BassDrum;