library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity de2_audio_select is
  
  port (
    clk        : in  std_logic;
    reset_n    : in  std_logic;
	audio_ini  : in  std_logic;
	audio_sel  : in  unsigned (1 downto 0);
	audio_vol  : in  unsigned (1 downto 0);

	AUD_ADCLRCK  : out std_logic;       --    Audio CODEC ADC LR Clock
    AUD_ADCDAT   : in  std_logic;       --    Audio CODEC ADC Data
    AUD_DACLRCK  : out std_logic;       --    Audio CODEC DAC LR Clock
    AUD_DACDAT   : out std_logic;       --    Audio CODEC DAC Data
    AUD_BCLK     : inout std_logic      --    Audio CODEC Bit-Stream Clock
    );
  
end de2_audio_select;

architecture rtl of de2_audio_select is

  component de2_wm8731_audio is
  port (
    clk : in std_logic;                 --    Audio CODEC Chip Clock AUD_XCK
    reset_n : in std_logic;
    test_mode : in std_logic;           --    Audio CODEC controller test mode
    audio_request : out std_logic;      --    Audio controller request new data
    data : in std_logic_vector(15 downto 0);
	frq_divider1 : in unsigned(15 downto 0);
	frq_divider2 : in unsigned(15 downto 0);
	audio_volume1: in unsigned(1 downto 0);
	audio_volume2: in unsigned(1 downto 0);
	audio_track1 : in unsigned(1 downto 0);
	audio_track2 : in unsigned(1 downto 0);
	audio_vol	 : in unsigned(1 downto 0);
--	press_delay  : integer;

--	cycle_divider : in unsigned(9 downto 0); 

    -- Audio interface signals
    AUD_ADCLRCK  : out std_logic;       --    Audio CODEC ADC LR Clock
    AUD_ADCDAT   : in  std_logic;       --    Audio CODEC ADC Data
    AUD_DACLRCK  : out std_logic;       --    Audio CODEC DAC LR Clock
    AUD_DACDAT   : out std_logic;       --    Audio CODEC DAC Data
    AUD_BCLK     : inout std_logic      --    Audio CODEC Bit-Stream Clock
  );
  end component;

  type ram1_type is array(integer range 0 to 150 - 1) of unsigned(15 downto 0);
  type ram2_type is array(integer range 0 to 2,integer range 0 to 1) of unsigned(15 downto 0);

  signal RAM1 : ram1_type :=   (X"2015", X"2203", X"2065", X"2203", X"2065", X"2203", X"2064", X"2202",
								X"2084", X"2202", X"2095", X"2203", X"2065", X"2203", X"2065", X"2203",
								X"2084", X"2202", X"2094", X"2202", X"2085", X"2203", X"2045", X"2203",
								X"2045", X"2203", X"2204", X"2202", X"2084", X"2202", X"2095", X"2203",
								X"2065", X"2203", X"2065", X"2203", X"2205", X"2203", 
								X"2015", X"2203", X"2065", X"2203", X"2065", X"2203", X"2064", X"2202",
								X"2084", X"2202", X"2095", X"2203", X"2065", X"2203", X"2065", X"2203",
								X"2064", X"2202", X"2094", X"2202", X"20D4", X"2202", X"20D4", X"2202",
								X"20D4", X"2202", X"20B4", X"2202", X"2095", X"2203", X"2085", X"2203",
								X"2095", X"2203", X"2065", X"2203", X"2065", X"2203", X"2064", X"2202",
								X"2094", X"2202", 
								X"20D5", X"2203", X"20D5", X"2203", X"20B5", X"2203", X"2095", X"2203",
								X"2085", X"2203", X"2045", X"2203", X"2045", X"2203", X"2044", X"2202",
								X"2084", X"2202", X"20B5", X"2203", X"20B5", X"2203", X"2095", X"2203",
								X"2085", X"2203", X"2095", X"2203", X"2065", X"2203", X"2065", X"2203",
								X"2064", X"2202", X"2094", X"2202", 
								X"20D5", X"2203", X"20D5", X"2203", X"20B5", X"2203", X"2095", X"2203",
								X"2085", X"2203", X"2045", X"2203", X"2045", X"2203", X"2044", X"2202",
								X"2084", X"2202", X"20B5", X"2203", X"20B5", X"2203", X"2095", X"2203",
								X"2085", X"2203", X"2095", X"2203", X"2065", X"2203", X"2065", X"2203",
								X"2205", X"2203");

  signal RAM2 : ram2_type := ((X"11A5", X"1201"),
							  (X"15B6", X"1201"),
							  (X"1201", X"1201"));

  signal audio_ctrl		: unsigned (15 downto 0);
  signal audio_ctrl1	: unsigned (15 downto 0);
  signal audio_ctrl2	: unsigned (15 downto 0);
  signal audio_set		: std_logic;
  signal audio_request	: std_logic;
  signal audio_lat		: std_logic;
  signal nrow			: integer	:= 0;
  signal ncol			: integer	:= 3;
  signal ram_address	: integer	:= 0;
  signal delay_cnt1		: integer	:= 0;
  signal delay_cnt2		: integer	:= 0;

  signal freq_divider1	: unsigned (15 downto 0);
  signal audio_track1	: unsigned (1 downto 0);
  signal audio_pitch1	: unsigned (5 downto 0);
  signal audio_length1	: unsigned (3 downto 0);
  signal audio_volume1	: unsigned (1 downto 0);
  signal DELAY1			: integer := 0;

  signal freq_divider2	: unsigned (15 downto 0);
  signal audio_track2	: unsigned (1 downto 0);
  signal audio_pitch2	: unsigned (5 downto 0);
  signal audio_length2	: unsigned (3 downto 0);
  signal audio_volume2	: unsigned (1 downto 0);
  signal DELAY2			: integer := 0;

  signal press			: std_logic;
  signal press_delay	: integer;
  constant PRESS_DELAY_MAX	: integer := 8000000;

--
begin

  audio_volume1		<= audio_ctrl1(13 downto 12);
  audio_track1		<= audio_ctrl1(11 downto 10);
  audio_pitch1		<= audio_ctrl1(9 downto 4);
  audio_length1		<= audio_ctrl1(3 downto 0);

  audio_volume2		<= audio_ctrl2(13 downto 12);
  audio_track2		<= audio_ctrl2(11 downto 10);
  audio_pitch2		<= audio_ctrl2(9 downto 4);
  audio_length2		<= audio_ctrl2(3 downto 0);

  process (clk)
  begin
	if rising_edge(clk) then
      if reset_n = '0' then 
          delay_cnt1 <= 0;
      elsif delay_cnt1 = DELAY1 - 1 then
          delay_cnt1 <= 0;
      else 
          delay_cnt1 <= delay_cnt1 + 1;
      end if;
    end if;   
  end process;

  process (clk)
  begin
	if rising_edge(clk) then
      if reset_n = '0' then 
        delay_cnt2 <= 0;
	  elsif audio_lat = '0' and audio_ini = '1' then
		delay_cnt2 <= 0;
--	  elsif nrow = 0 and press_delay > PRESS_DELAY_MAX - 1 then
--		delay_cnt2 <= 0;
      elsif delay_cnt2 = DELAY2 - 1 then
		delay_cnt2 <= 0;
      else 
        delay_cnt2 <= delay_cnt2 + 1;
      end if;
    end if;   
  end process;
  
  process (clk)
  begin
	if rising_edge(clk) then
		audio_lat <= audio_ini;
	end if;
  end process;

  process (clk)
  begin
    if rising_edge(clk) then
	  if reset_n = '0' then
		ram_address <= 0;
	  else
		audio_ctrl1 <= RAM1(ram_address);
		if delay_cnt1 = 0 then
			if ram_address = 150 - 1 then
				ram_address <= 0;
			else
				ram_address <= ram_address + 1;
			end if;
		end if;
	  end if; 
	end if;
  end process;

--  process (clk)
--  begin
--	if rising_edge(clk) then
--		if audio_lat = '0' and audio_ini = '1' then
--			press <= '1';
--		elsif audio_lat = '1' and audio_ini = '0' then
--			press <= '0';
--		end if;
--	end if;
--  end process;

--  process (clk)
--  begin
--	if rising_edge(clk) then
--		if press = '0' then
--			press_delay <= 0;
--		elsif press_delay > PRESS_DELAY_MAX - 1 then
--			press_delay <= 0;
--		else
--			press_delay <= press_delay + 1;
--		end if;
--	end if;
--  end process;

  process (clk)
  begin
    if rising_edge(clk) then
		if reset_n = '0' then
			nrow <= 0;
			ncol <= 0;
		else
			if audio_lat = '0' and audio_ini = '1' then
				nrow		<= to_integer(audio_sel);
				ncol		<= 0;
			end if;
			audio_ctrl2 <= RAM2(nrow, ncol);
			if delay_cnt2 = DELAY2 - 1 then
				if ncol < 1 then
					ncol <= ncol + 1;
				end if;
			end if;

		end if; 
	end if;
  end process;

  V1: de2_wm8731_audio port map (
	clk => clk,
	reset_n => reset_n,
	test_mode => '1',                   -- Output a sine wave
	audio_request => audio_request,
	data => "0000000000000000",
	frq_divider1 => freq_divider1,
	frq_divider2 => freq_divider2,
	audio_volume1	=> audio_volume1,
	audio_volume2	=> audio_volume2,
	audio_track1	=> audio_track1,
	audio_track2	=> audio_track2,
	audio_vol		=> audio_vol,
--	press_delay		=> press_delay,
	--	cycle_divider	=> cycle_divider,
  
	-- Audio interface signals
	AUD_ADCLRCK  => AUD_ADCLRCK,
	AUD_ADCDAT   => AUD_ADCDAT,
	AUD_DACLRCK  => AUD_DACLRCK,
	AUD_DACDAT   => AUD_DACDAT,
	AUD_BCLK     => AUD_BCLK
	  );

  with audio_pitch1 select freq_divider1 <=
	X"0245" when "000001",
	X"0225" when "000010",
	X"0206" when "000011",
	X"01E9" when "000100",
	X"01CD" when "000101",
	X"01B3" when "000110",
	X"019B" when "000111",
	X"0184" when "001000",
	X"016E" when "001001",
	X"0159" when "001010",
	X"0146" when "001011",
	X"0134" when "001100",
	X"0122" when "001101",
	X"0112" when "001110",
	X"0103" when "001111",
	X"00F4" when "010000",
	X"00E6" when "010001",
	X"00D9" when "010010",
	X"00CD" when "010011",
	X"00C2" when "010100",
	X"00B7" when "010101",
	X"00AC" when "010110",
	X"00A3" when "010111",
	X"009A" when "011000",
	X"0091" when "011001",
	X"0000" when others;

  with audio_pitch2 select freq_divider2 <=
	X"0900" when "011010",
	X"1200" when "011011",
	X"0000" when others;

  with audio_length1 select DELAY1 <=
   100000 when X"0",
   625000 when X"1",
  1250000 when X"2",
  2500000 when X"3",
  5000000 when X"4",
 10000000 when X"5",
 20000000 when X"6",
 40000000 when X"7",
    10000 when others;

  with audio_length2 select DELAY2 <=
   100000 when X"0",
   625000 when X"1",
  1250000 when X"2",
  2500000 when X"3",
  5000000 when X"4",
 10000000 when X"5",
 20000000 when X"6",
 40000000 when X"7",
    10000 when others;

end rtl;
