mirror of
https://github.com/MiSTer-devel/Gameboy_MiSTer.git
synced 2026-04-19 03:04:09 +00:00
Add option to remove audio pops (#257)
Some audio can be inaccurate with this option enabled.
This commit is contained in:
@@ -200,7 +200,7 @@ assign AUDIO_MIX = status[8:7];
|
||||
// 0 1 2 3 4 5 6
|
||||
// 01234567890123456789012345678901 23456789012345678901234567890123
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV
|
||||
// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX
|
||||
// XXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX
|
||||
|
||||
`include "build_id.v"
|
||||
localparam CONF_STR = {
|
||||
@@ -241,6 +241,7 @@ localparam CONF_STR = {
|
||||
"P1o2,Analog width,Narrow,Wide;",
|
||||
"P1-;",
|
||||
"P1O78,Stereo mix,none,25%,50%,100%;",
|
||||
"P1O[43],Audio mode,Accurate,No Pops;",
|
||||
|
||||
"P2,Bootroms;",
|
||||
"P2-;",
|
||||
@@ -665,6 +666,7 @@ gb gb (
|
||||
// audio
|
||||
.audio_l ( GB_AUDIO_L ),
|
||||
.audio_r ( GB_AUDIO_R ),
|
||||
.audio_no_pops (status[43]),
|
||||
|
||||
// interface to the lcd
|
||||
.lcd_clkena ( lcd_clkena ),
|
||||
|
||||
2
rtl/gb.v
2
rtl/gb.v
@@ -58,6 +58,7 @@ module gb (
|
||||
// audio
|
||||
output [15:0] audio_l,
|
||||
output [15:0] audio_r,
|
||||
input audio_no_pops,
|
||||
|
||||
// Megaduck?
|
||||
input megaduck,
|
||||
@@ -445,6 +446,7 @@ gbc_snd audio (
|
||||
.reset ( reset_ss ),
|
||||
|
||||
.is_gbc ( isGBC ),
|
||||
.remove_pops ( audio_no_pops ),
|
||||
|
||||
.s1_read ( audio_rd ),
|
||||
.s1_write ( audio_wr ),
|
||||
|
||||
@@ -19,6 +19,7 @@ entity gbc_snd is
|
||||
reset : in std_logic;
|
||||
|
||||
is_gbc : in std_logic;
|
||||
remove_pops : in std_logic; -- 0: Accurate output, 1: Toggling DACs will not cause pops but some audio can be inaccurate.
|
||||
|
||||
s1_read : in std_logic;
|
||||
s1_write : in std_logic;
|
||||
@@ -45,6 +46,7 @@ architecture SYN of gbc_snd is
|
||||
clk : in std_logic;
|
||||
ce : in std_logic;
|
||||
dac_en : in std_logic;
|
||||
dac_invert : in std_logic;
|
||||
dac_input : in std_logic_vector(3 downto 0);
|
||||
dac_output : out signed(8 downto 0)
|
||||
);
|
||||
@@ -1643,13 +1645,13 @@ begin
|
||||
|
||||
-- Analog hardware emulation
|
||||
|
||||
sq1_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>sq1_dac_en, dac_input=>sq1_wav,dac_output=>sq1_dac_out);
|
||||
sq2_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>sq2_dac_en, dac_input=>sq2_wav,dac_output=>sq2_dac_out);
|
||||
wav_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>wav_enable, dac_input=>wav_wav,dac_output=>wav_dac_out);
|
||||
noi_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>noi_dac_en, dac_input=>noi_wav,dac_output=>noi_dac_out);
|
||||
sq1_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>sq1_dac_en, dac_invert => not remove_pops, dac_input=>sq1_wav,dac_output=>sq1_dac_out);
|
||||
sq2_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>sq2_dac_en, dac_invert => not remove_pops, dac_input=>sq2_wav,dac_output=>sq2_dac_out);
|
||||
wav_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>wav_enable, dac_invert => not remove_pops, dac_input=>wav_wav,dac_output=>wav_dac_out);
|
||||
noi_dac : apu_dac port map (clk=>clk, ce=>ce, dac_en=>noi_dac_en, dac_invert => not remove_pops, dac_input=>noi_wav,dac_output=>noi_dac_out);
|
||||
|
||||
|
||||
mixer : process (sq1_dac_out, sq2_dac_out, wav_dac_out, noi_dac_out, ch_map, ch_vol)
|
||||
mixer : process (sq1_dac_out, sq2_dac_out, wav_dac_out, noi_dac_out, ch_map, ch_vol, remove_pops)
|
||||
variable snd_left_in : signed(10 downto 0);
|
||||
variable snd_right_in : signed(10 downto 0);
|
||||
variable snd_tmp : signed(15 downto 0);
|
||||
@@ -1678,12 +1680,20 @@ begin
|
||||
snd_left_in := snd_left_in + wav_analog;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
snd_tmp := snd_right_in * signed(("00" & ch_vol(2 downto 0)) + '1');
|
||||
snd_right <= std_logic_vector(snd_tmp);
|
||||
|
||||
snd_tmp := snd_left_in * signed(("00" & ch_vol(6 downto 4)) + '1');
|
||||
snd_left <= std_logic_vector(snd_tmp);
|
||||
snd_tmp := snd_right_in * signed(("00" & ch_vol(2 downto 0)) + '1');
|
||||
if (remove_pops = '1') then
|
||||
snd_right <= std_logic_vector(shift_left(snd_tmp,1)); -- Compensate lower volume
|
||||
else
|
||||
snd_right <= std_logic_vector(snd_tmp);
|
||||
end if;
|
||||
|
||||
snd_tmp := snd_left_in * signed(("00" & ch_vol(6 downto 4)) + '1');
|
||||
if (remove_pops = '1') then
|
||||
snd_left <= std_logic_vector(shift_left(snd_tmp,1));
|
||||
else
|
||||
snd_left <= std_logic_vector(snd_tmp);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end SYN;
|
||||
@@ -1697,6 +1707,7 @@ entity apu_dac is
|
||||
clk : in std_logic;
|
||||
ce : in std_logic;
|
||||
dac_en : in std_logic;
|
||||
dac_invert : in std_logic;
|
||||
dac_input : in std_logic_vector(3 downto 0);
|
||||
dac_output : out signed(8 downto 0)
|
||||
);
|
||||
@@ -1712,10 +1723,15 @@ architecture apu_dac_arch of apu_dac is
|
||||
|
||||
-- Convert a DAC input code to a pseudo-analog value
|
||||
function dac_out(
|
||||
wav : std_logic_vector(3 downto 0)
|
||||
wav : std_logic_vector(3 downto 0);
|
||||
invert : std_logic
|
||||
) return signed is
|
||||
begin
|
||||
return signed((wav xor "0111") & "00000");
|
||||
if (invert = '1') then
|
||||
return signed((wav xor "0111") & "00000"); -- 0xF = -256, 0x0 = 224.
|
||||
else
|
||||
return signed("0" & wav & "0000"); -- 0xF = 240, 0x0 = 0.
|
||||
end if;
|
||||
end function;
|
||||
begin
|
||||
dac_output <= dac_analog;
|
||||
@@ -1735,11 +1751,11 @@ begin
|
||||
end if;
|
||||
end process timers;
|
||||
|
||||
process(clk, ce, dac_en, dac_input, dac_decay_timer)
|
||||
process(clk, ce, dac_en, dac_invert, dac_input, dac_decay_timer)
|
||||
begin
|
||||
if rising_edge(clk) and ce = '1' then
|
||||
if dac_en = '1' then
|
||||
dac_analog <= dac_out(dac_input);
|
||||
dac_analog <= dac_out(dac_input, dac_invert);
|
||||
elsif dac_decay_timer = 0 then
|
||||
if dac_analog < 0 then
|
||||
dac_analog <= dac_analog + 1;
|
||||
|
||||
Reference in New Issue
Block a user