nes-fix #12 "Strange "White noise" sound during 1943 (USA) intro" as well as a boatload of aesthetic improvements to make the sound output not so embarassing. no speedups whatsoever though.
This commit is contained in:
parent
1f588c451f
commit
a47c70d0ef
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
//TODO - so many integers in the square wave output keep us from exactly unbiasing the waveform. also other waves probably
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ using BizHawk.Emulation.Sound;
|
||||||
|
|
||||||
//TODO - refactor length counter to be separate component
|
//TODO - refactor length counter to be separate component
|
||||||
|
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -233,19 +236,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
//reload timer
|
//reload timer
|
||||||
timer_counter = timer_raw_reload_value;
|
timer_counter = timer_raw_reload_value;
|
||||||
}
|
}
|
||||||
if (duty_value) //we are outputting something
|
|
||||||
|
if (duty_value) //high state of duty cycle
|
||||||
{
|
{
|
||||||
sample = env_output;
|
sample = env_output;
|
||||||
|
|
||||||
if (swp_silence)
|
if (swp_silence)
|
||||||
sample = 0;
|
sample = env_output / 2; //(a little biasing hack here)
|
||||||
|
|
||||||
if (len_cnt == 0) //length counter is 0
|
if (len_cnt == 0) //length counter is 0
|
||||||
sample = 0; //silenced
|
sample = env_output / 2; //silenced (a little biasing hack here)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sample = 0; //duty cycle is 0, silenced.
|
sample = env_output / 2; //duty cycle is 0, silenced.
|
||||||
|
|
||||||
|
sample -= env_output / 2; //unbias
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,9 +388,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
noise_bit = (shift_register & 1) != 0;
|
noise_bit = (shift_register & 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noise_bit || len_cnt == 0) sample = 0;
|
//unbiasing is rolled in here
|
||||||
else
|
if (len_cnt == 0) sample = 0;
|
||||||
sample = env_output;
|
else if (noise_bit) sample = -env_output;
|
||||||
|
else sample = env_output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,10 +482,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
seq = (seq + 1) & 0x1F;
|
seq = (seq + 1) & 0x1F;
|
||||||
timer = timer_cnt_reload;
|
timer = timer_cnt_reload;
|
||||||
}
|
}
|
||||||
//if(CFG_DECLICK)
|
if(CFG_DECLICK)
|
||||||
//sample = TRIANGLE_TABLE[(seq+8)&0x1F];
|
sample = TRIANGLE_TABLE[(seq+8)&0x1F];
|
||||||
//else
|
else
|
||||||
sample = TRIANGLE_TABLE[seq];
|
sample = TRIANGLE_TABLE[seq];
|
||||||
|
|
||||||
|
//special hack: frequently, games will use the maximum frequency triangle in order to mute it
|
||||||
|
//apparently this results in the DAC for the triangle wave outputting a steady level at about 7.5
|
||||||
|
//so we'll emulate it at the digital level
|
||||||
|
if (timer_cnt_reload == 1) sample = 8;
|
||||||
|
|
||||||
|
sample -= 8; //unbias
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -576,12 +589,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
timer = timer_reload;
|
timer = timer_reload;
|
||||||
Clock();
|
Clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (out_silence)
|
||||||
|
sample = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = out_deltacounter;
|
||||||
|
sample -= 64; //unbias;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncSample()
|
void SyncSample()
|
||||||
{
|
{
|
||||||
sample = (out_deltacounter - 64) / 4;
|
//sample = (out_deltacounter - 64) / 4;
|
||||||
//Console.WriteLine("dmc sample: {0}", sample);
|
//Console.WriteLine("dmc sample: {0}", sample);
|
||||||
|
//sample -= 64; //unbias
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clock()
|
void Clock()
|
||||||
|
@ -844,54 +866,47 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
void _WriteReg(int addr, byte val)
|
void _WriteReg(int addr, byte val)
|
||||||
{
|
{
|
||||||
//Console.WriteLine("{0:X4} = {1:X2}", addr, val);
|
//Console.WriteLine("{0:X4} = {1:X2}", addr, val);
|
||||||
switch (addr)
|
int index = addr - 0x4000;
|
||||||
|
int reg = index & 3;
|
||||||
|
int channel = index >> 2;
|
||||||
|
switch (channel)
|
||||||
{
|
{
|
||||||
case 0x4000:
|
case 0:
|
||||||
case 0x4001:
|
pulse[0].WriteReg(reg, val);
|
||||||
case 0x4002:
|
|
||||||
case 0x4003:
|
|
||||||
pulse[0].WriteReg(addr - 0x4000, val);
|
|
||||||
break;
|
break;
|
||||||
case 0x4004:
|
case 1:
|
||||||
case 0x4005:
|
pulse[1].WriteReg(reg, val);
|
||||||
case 0x4006:
|
|
||||||
case 0x4007:
|
|
||||||
pulse[1].WriteReg(addr - 0x4004, val);
|
|
||||||
break;
|
break;
|
||||||
case 0x4008:
|
case 2:
|
||||||
case 0x4009:
|
triangle.WriteReg(reg, val);
|
||||||
case 0x400A:
|
|
||||||
case 0x400B:
|
|
||||||
triangle.WriteReg(addr - 0x4008, val);
|
|
||||||
break;
|
break;
|
||||||
case 0x400C:
|
case 3:
|
||||||
case 0x400D:
|
noise.WriteReg(reg, val);
|
||||||
case 0x400E:
|
|
||||||
case 0x400F:
|
|
||||||
noise.WriteReg(addr - 0x400C, val);
|
|
||||||
break;
|
break;
|
||||||
case 0x4010:
|
case 4:
|
||||||
case 0x4011:
|
dmc.WriteReg(reg, val);
|
||||||
case 0x4012:
|
|
||||||
case 0x4013:
|
|
||||||
dmc.WriteReg(addr - 0x4010, val);
|
|
||||||
break;
|
break;
|
||||||
case 0x4015:
|
case 5:
|
||||||
pulse[0].set_lenctr_en(val & 1);
|
if (addr == 0x4015)
|
||||||
pulse[1].set_lenctr_en((val >> 1) & 1);
|
|
||||||
triangle.set_lenctr_en((val >> 2) & 1);
|
|
||||||
noise.set_lenctr_en((val >> 3) & 1);
|
|
||||||
dmc.set_lenctr_en(val.Bit(4));
|
|
||||||
break;
|
|
||||||
case 0x4017:
|
|
||||||
//Console.WriteLine("apu 4017 = {0:X2}", val);
|
|
||||||
sequencer_mode = (val >> 7) & 1;
|
|
||||||
sequencer_irq_inhibit = (val >> 6) & 1;
|
|
||||||
if (sequencer_irq_inhibit == 1)
|
|
||||||
{
|
{
|
||||||
sequencer_irq_clear_pending = true;
|
pulse[0].set_lenctr_en(val & 1);
|
||||||
|
pulse[1].set_lenctr_en((val >> 1) & 1);
|
||||||
|
triangle.set_lenctr_en((val >> 2) & 1);
|
||||||
|
noise.set_lenctr_en((val >> 3) & 1);
|
||||||
|
dmc.set_lenctr_en(val.Bit(4));
|
||||||
|
}
|
||||||
|
else if (addr == 0x4017)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("apu 4017 = {0:X2}", val);
|
||||||
|
sequencer_mode = (val >> 7) & 1;
|
||||||
|
sequencer_irq_inhibit = (val >> 6) & 1;
|
||||||
|
if (sequencer_irq_inhibit == 1)
|
||||||
|
{
|
||||||
|
sequencer_irq_clear_pending = true;
|
||||||
|
}
|
||||||
|
sequence_reset_pending = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sequence_reset_pending = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -935,12 +950,31 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
noise.Run();
|
noise.Run();
|
||||||
dmc.Run();
|
dmc.Run();
|
||||||
|
|
||||||
int mix = 0;
|
int s_pulse0 = pulse[0].sample;
|
||||||
if (EnableSquare1) mix += pulse[0].sample;
|
int s_pulse1 = pulse[1].sample;
|
||||||
if (EnableSquare2) mix += pulse[1].sample;
|
int s_tri = triangle.sample;
|
||||||
if (EnableTriangle) mix += triangle.sample;
|
int s_noise = noise.sample;
|
||||||
if (EnableNoise) mix += noise.sample >> 1;
|
int s_dmc = dmc.sample;
|
||||||
if (EnableDMC) mix += dmc.sample;
|
//int s_ext = 0; //gamepak
|
||||||
|
|
||||||
|
if (!EnableSquare1) s_pulse0 = 0;
|
||||||
|
if (!EnableSquare2) s_pulse1 = 0;
|
||||||
|
if (!EnableTriangle) s_tri = 0;
|
||||||
|
if (!EnableNoise) s_noise = 0;
|
||||||
|
if (!EnableDMC) s_dmc = 0;
|
||||||
|
|
||||||
|
//s_pulse0 = 0;
|
||||||
|
//s_pulse1 = 0;
|
||||||
|
//s_tri = 0;
|
||||||
|
//s_noise = 0;
|
||||||
|
//s_dmc = 0;
|
||||||
|
|
||||||
|
const float NOISEADJUST = 0.5f;
|
||||||
|
float pulse_out = 0.00752f * (s_pulse0 + s_pulse1);
|
||||||
|
float tnd_out = 0.00851f * s_tri + 0.00494f * NOISEADJUST * s_noise + 0.00335f * s_dmc;
|
||||||
|
float output = pulse_out + tnd_out;
|
||||||
|
|
||||||
|
int mix = (int)(50000 * output);
|
||||||
|
|
||||||
EmitSample(mix);
|
EmitSample(mix);
|
||||||
|
|
||||||
|
@ -1011,7 +1045,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
double factional_remainder = (this_samp - last_hwsamp) * (1 - ratio);
|
double factional_remainder = (this_samp - last_hwsamp) * (1 - ratio);
|
||||||
accumulate += fractional;
|
accumulate += fractional;
|
||||||
|
|
||||||
accumulate *= 436; //32768/(15*4) -- adjust later for other sound channels
|
//accumulate *= 436; //32768/(15*4) -- adjust later for other sound channels
|
||||||
int outsamp = (int)(accumulate / kInvMixRate);
|
int outsamp = (int)(accumulate / kInvMixRate);
|
||||||
if (CFG_USE_METASPU)
|
if (CFG_USE_METASPU)
|
||||||
metaspu.buffer.enqueue_sample((short)outsamp, (short)outsamp);
|
metaspu.buffer.enqueue_sample((short)outsamp, (short)outsamp);
|
||||||
|
|
Loading…
Reference in New Issue