feat(audio): non-linear APU mixing and mapper expansion audio (VRC6, FME-7, Namco163)
This commit is contained in:
@@ -56,11 +56,27 @@ impl AudioMixer {
|
||||
let samples = self.sample_accumulator.floor() as usize;
|
||||
self.sample_accumulator -= samples as f64;
|
||||
|
||||
let pulse_out = 0.00752 * (f32::from(channels.pulse1) + f32::from(channels.pulse2));
|
||||
let tnd_out = 0.00851 * f32::from(channels.triangle)
|
||||
+ 0.00494 * f32::from(channels.noise)
|
||||
+ 0.00335 * f32::from(channels.dmc);
|
||||
let sample = pulse_out + tnd_out;
|
||||
// NES non-linear APU mixing (Blargg's reference formulas).
|
||||
// Pulse channels use a shared lookup:
|
||||
// pulse_out = 95.88 / (8128 / (p1 + p2) + 100)
|
||||
// TND channels use a separate lookup:
|
||||
// tnd_out = 159.79 / (1 / (tri/8227 + noise/12241 + dmc/22638) + 100)
|
||||
// Both formulas produce 0.0 when all contributing channels are silent.
|
||||
let p_sum = f32::from(channels.pulse1) + f32::from(channels.pulse2);
|
||||
let pulse_out = if p_sum == 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
95.88 / (8128.0 / p_sum + 100.0)
|
||||
};
|
||||
let tnd_sum = f32::from(channels.triangle) / 8227.0
|
||||
+ f32::from(channels.noise) / 12241.0
|
||||
+ f32::from(channels.dmc) / 22638.0;
|
||||
let tnd_out = if tnd_sum == 0.0 {
|
||||
0.0
|
||||
} else {
|
||||
159.79 / (1.0 / tnd_sum + 100.0)
|
||||
};
|
||||
let sample = pulse_out + tnd_out + channels.expansion;
|
||||
|
||||
if samples == 0 {
|
||||
return;
|
||||
@@ -118,6 +134,7 @@ mod tests {
|
||||
triangle: 15,
|
||||
noise: 15,
|
||||
dmc: 127,
|
||||
expansion: 0.0,
|
||||
};
|
||||
let mut out = Vec::new();
|
||||
mixer.push_cycles(50, channels, &mut out);
|
||||
@@ -143,6 +160,7 @@ mod tests {
|
||||
triangle: 15,
|
||||
noise: 15,
|
||||
dmc: 127,
|
||||
expansion: 0.0,
|
||||
},
|
||||
&mut out,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user