SPDIF Volume

From Hamsterworks Wiki!

Jump to: navigation, search

By extending the SPDIF_Thru project this FPGA project is a very, very simple Audio DSP algorithm - it just divides the sample's value by 4 if a button is pressed.

Because a frame comes through every 1/44100th of a second, and the project clocks at 100MHz, you have over 2,000 clock cycles to process each frame.

How it works

By wedging a component between the SPDIF_in and sample_store FIFO you can manipulate the samples as they pass through into the FIFO.

The samples from a CD are 16 bit signed numbers, held in bits 23 downto 8 (for 16 bit samples) or 32 downto 4 (for 20 bit samples).

Each bit shift reduces the volume by 3db, so a shift of 2 bits lowers volume by 3db.

Source

----------------------------------------------------------------------------------
-- Engineer: Mike Field (hamster@snap.net.nz)
-- 
-- Create Date:    21:12:25 09/15/2011 
-- Module Name:    volume - Behavioral 
-- Description:    Decrease the volume of a S/PDIF signal by 6db when a button 
--                 is pressed.
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity volume is
    Port ( 
      clock100        : IN std_logic;
      btn             : IN std_logic;

      inStartOfFrame  : IN  std_logic;
      inChannelA      : IN  std_logic;
      inSubframe      : IN  std_logic_vector(27 downto 0);
      inNewSubframe   : IN  std_logic;

      outStartOfFrame : OUT std_logic;
      outChannelA     : OUT std_logic;
      outSubframe     : OUT std_logic_vector(27 downto 0);
      outNewSubframe  : OUT std_logic);
end volume;

architecture Behavioral of volume is
begin
   process(clock100, btn, inStartOfFrame, inChannelA, inSubframe,   inNewSubframe)
   begin
      if rising_edge(clock100) then
         outStartOfFrame <= inStartOfFrame;
         outChannelA       <= inChannelA;
         outSubframe       <= inSubframe;
         -- The sample is in bits 23 downto 4
         -- Reduce the volume by 6db
         if btn = '1' then
            outSubframe(22 downto 4) <= inSubframe(23) & inSubframe(23 downto 6);         
         end if;
         outNewSubframe    <= inNewSubframe;
      end if;
   end process;
end Behavioral;

Changes needed in SPDIF_thru.vhd:

...
   COMPONENT volume
   PORT(
      clock100       : IN std_logic;
      btn            : IN std_logic;

      inStartOfFrame : IN  std_logic;
      inChannelA     : IN  std_logic;
      inSubframe     : IN  std_logic_vector(27 downto 0);
      inNewSubframe  : IN  std_logic;

      outStartOfFrame: OUT std_logic;
      outChannelA    : OUT std_logic;
      outSubframe    : OUT std_logic_vector(27 downto 0);
      outNewSubframe : OUT std_logic
      );
   END COMPONENT;
...
   signal midSubframe      : std_logic_vector(27 downto 0);
   signal midChannelA      : std_logic;
   signal midStartOfFrame  : std_logic;
   signal midNewSubframe   : std_logic;
...
   fifoInput <= midStartOfFrame &   midChannelA & midSubframe;
...
adj_volume: volume PORT MAP(
      clock100 => clock100,
      btn      => btn,
		
      inStartOfFrame => inputStartOfFrame,
      inChannelA     => inputChannelA,
      inSubframe     => inputSubframe,
      inNewSubframe  => inputNewSubframe,
 	
      outStartOfFrame=> midStartOfFrame,
      outChannelA    => midChannelA,
      outSubframe    => midSubframe,
      outNewSubframe => midNewSubframe
   );
...

Personal tools