---------------------------------------------------------------------------------- -- SK-Synth - FPGA-Synthesizer -- Copyright (C) 2009-2010 Stefan Kristiansson -- -- 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 . ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.SK_Synth_pack.ALL; entity midi_ctrl is Port ( reset : in STD_LOGIC; clk : in STD_LOGIC; pitchwheel_out : out STD_LOGIC_VECTOR(13 downto 0); note_on_out : out STD_LOGIC; note_off_out : out STD_LOGIC; note_out : out STD_LOGIC_VECTOR (7 downto 0); velocity_out : out STD_LOGIC_VECTOR(7 downto 0); osc0_wave : out unsigned(7 downto 0); osc0_wave_offset : out unsigned(7 downto 0); osc0_enable : out STD_LOGIC; osc0_detune_notes : out STD_LOGIC_VECTOR(7 downto 0); osc0_detune_cents : out STD_LOGIC_VECTOR(7 downto 0); osc1_wave : out unsigned(7 downto 0); osc1_enable : out STD_LOGIC; osc1_detune_notes : out STD_LOGIC_VECTOR(7 downto 0); osc1_detune_cents : out STD_LOGIC_VECTOR(7 downto 0); osc_mix_mode : out unsigned(3 downto 0); filter_freq : out STD_LOGIC_VECTOR(7 downto 0); filter_res : out STD_LOGIC_VECTOR(7 downto 0); legato : out STD_LOGIC; sustain : out STD_LOGIC; amp_envelope_A : out STD_LOGIC_VECTOR(7 downto 0); amp_envelope_D : out STD_LOGIC_VECTOR(7 downto 0); amp_envelope_S : out STD_LOGIC_VECTOR(7 downto 0); amp_envelope_R : out STD_LOGIC_VECTOR(7 downto 0); filter_envelope_A : out STD_LOGIC_VECTOR(7 downto 0); filter_envelope_D : out STD_LOGIC_VECTOR(7 downto 0); filter_envelope_S : out STD_LOGIC_VECTOR(7 downto 0); filter_envelope_R : out STD_LOGIC_VECTOR(7 downto 0); LFO0_waveform : out waveforms; LFO0_enable : out STD_LOGIC; LFO0_rate : out STD_LOGIC_VECTOR(7 downto 0); LFO0_amount : out STD_LOGIC_VECTOR(7 downto 0); LFO0_dest : out destination; portamento : out unsigned(7 downto 0); listenchan : in STD_LOGIC_VECTOR(3 downto 0); -- this is the midi channel we listen to pitchwheel_change : in STD_LOGIC; pitchwheel_in : in STD_LOGIC_VECTOR(13 downto 0); note_on_in : in STD_LOGIC; note_off_in : in STD_LOGIC; note_in : in STD_LOGIC_VECTOR (7 downto 0); velocity_in : in STD_LOGIC_VECTOR(7 downto 0); chan : in STD_LOGIC_VECTOR(3 downto 0); control_change : in STD_LOGIC; control_change_num : in STD_LOGIC_VECTOR (7 downto 0); control_change_value : in STD_LOGIC_VECTOR (7 downto 0) ); end midi_ctrl; architecture rtl of midi_ctrl is begin process(reset,clk) begin if reset = '1' then osc0_enable <= '1'; osc0_wave <= X"01"; -- sawtooth osc0_wave_offset <= X"00"; osc0_detune_notes <= X"40"; osc0_detune_cents <= X"40"; osc1_enable <= '0'; osc1_wave <= X"01"; -- sawtooth osc1_detune_notes <= X"40"; osc1_detune_cents <= X"40"; filter_freq <= X"7F"; filter_res <= X"00"; amp_envelope_A <= X"00"; amp_envelope_D <= X"00"; amp_envelope_S <= X"7F"; amp_envelope_R <= X"00"; filter_envelope_A <= X"00"; filter_envelope_D <= X"00"; filter_envelope_S <= X"7F"; filter_envelope_R <= X"00"; LFO0_enable <= '0'; LFO0_waveform <= sawtooth; LFO0_rate <= X"00"; LFO0_amount <= X"00"; pitchwheel_out <= "10000000000000"; -- 0x2000 legato <= '0'; sustain <= '0'; portamento <= X"00"; elsif clk'event and clk = '1' then note_on_out <= '0'; note_off_out <= '0'; if listenchan = chan then if pitchwheel_change = '1' then pitchwheel_out <= pitchwheel_in; end if; if note_on_in = '1' or note_off_in = '1' then note_on_out <= note_on_in; note_out <= note_in; note_off_out <= note_off_in; velocity_out <= velocity_in; end if; if control_change = '1' then case (control_change_num) is when X"03" => -- 3: Undefined (osc0 note detune) osc0_detune_notes <= control_change_value; when X"05" => -- 5: Portamento time (Portamento time) portamento <= unsigned(control_change_value); when X"09" => -- 9: Undefined (osc1 note detune) osc1_detune_notes <= control_change_value; when X"0E" => -- 14: Undefined (osc0 cents detune) osc0_detune_cents <= control_change_value; when X"0F" => -- 15: Undefined (osc1 cents detune) osc1_detune_cents <= control_change_value; when X"10" => -- 16: General purpose controller #1 (osc0 enable/waveform) osc0_enable <= '1'; osc0_wave <= unsigned(control_change_value) - 1; if control_change_value = X"00" then osc0_enable <= '0'; end if; when X"11" => -- 17: General purpose controller #2 (osc1 enable/waveform) osc1_enable <= '1'; osc1_wave <= unsigned(control_change_value) - 1; if control_change_value = X"00" then osc1_enable <= '0'; end if; when X"12" => -- 18: General purpose controller #3 (osc1/2 mix mode) osc_mix_mode <= unsigned(control_change_value(3 downto 0)); when X"13" => -- 19: General purpose controller #4 filter_res <= control_change_value; when X"14" => -- 20: Undefined, (LFO_enable/LFO_waveform) case (control_change_value) is when X"00" => LFO0_enable <= '0'; when X"01" => LFO0_enable <= '1'; LFO0_waveform <= sawtooth; when X"02" => LFO0_enable <= '1'; LFO0_waveform <= square; when X"03" => LFO0_enable <= '1'; LFO0_waveform <= triangle; when X"04" => LFO0_enable <= '1'; LFO0_waveform <= sine; when others => NULL; end case; when X"15" => -- 21: Undefined, (LFO_rate) LFO0_rate <= control_change_value; when X"16" => -- 22: Undefined, (LFO_amount) LFO0_amount <= control_change_value; when X"17" => -- 23: Undefined, (LFO_dest) case (control_change_value) is when X"00" => LFO0_dest <= pitch_dest; when X"01" => LFO0_dest <= amp_dest; when X"02" => LFO0_dest <= filter_dest; when others => NULL; end case; when X"18" => -- 24: Undefined, (misc control flags) -- b6 b5 b4 b3 b2 b1 b0 -- | | | | | | |_ Reserved -- | | | | | |____ Reserved -- | | | | |_______ Reserved -- | | | |__________ Reserved -- | | |_____________ Reserved -- | |________________ Reserved -- |___________________ Reserved when X"40" => -- 64: Sustain sustain <= control_change_value(6); when X"44" => -- 68: Legato footswitch legato <= control_change_value(6); when X"48" => -- 72: Sound controller 3, Sound Release Time amp_envelope_R <= control_change_value; when X"49" => -- 73: Sound controller 4, Sound Attack Time amp_envelope_A <= control_change_value; when X"4A" => -- 74: Sound controller 5, Sound Brightness filter_freq <= control_change_value; when X"4B" => -- 75: Sound controller 6, Sound Decay Time amp_envelope_D <= control_change_value; when X"4F" => -- 79: Sound controller 10, (undefined) Sound Sustain Level amp_envelope_S <= control_change_value; when X"50" => -- 80: General Purpose Controller #5 filter_envelope_A <= control_change_value; when X"51" => -- 81: General Purpose Controller #6 filter_envelope_D <= control_change_value; when X"52" => -- 82: General Purpose Controller #7 filter_envelope_S <= control_change_value; when X"53" => -- 83: General Purpose Controller #8 filter_envelope_R <= control_change_value; when X"55" => -- 85: Undefined (osc0 wave offset) osc0_wave_offset <= unsigned(control_change_value); when others => NULL; end case; end if; end if; end if; end process; end rtl;