mizu_core/
apu.rs

1mod channel;
2mod envelope;
3mod noise_channel;
4mod pulse_channel;
5mod wave_channel;
6
7use bitflags::bitflags;
8use save_state::Savable;
9
10use crate::GameBoyConfig;
11use channel::{ApuChannel, Dac, LengthCountedChannel};
12use noise_channel::NoiseChannel;
13use pulse_channel::PulseChannel;
14use wave_channel::WaveChannel;
15
16/// Contains the flushed output buffer of the `APU`.
17/// The main buffer `all` is the summation of all of the other buffers/channels.
18/// If you want a combination of different channels, you can just add them together.
19/// All volume control is done before pushing to the buffers.
20pub struct AudioBuffers<'a> {
21    pulse1: &'a mut Vec<f32>,
22    pulse2: &'a mut Vec<f32>,
23    wave: &'a mut Vec<f32>,
24    noise: &'a mut Vec<f32>,
25
26    all: &'a mut Vec<f32>,
27}
28
29impl AudioBuffers<'_> {
30    pub fn pulse1(&self) -> &[f32] {
31        self.pulse1
32    }
33
34    pub fn pulse2(&self) -> &[f32] {
35        self.pulse2
36    }
37
38    pub fn wave(&self) -> &[f32] {
39        self.wave
40    }
41
42    pub fn noise(&self) -> &[f32] {
43        self.noise
44    }
45
46    pub fn all(&self) -> &[f32] {
47        self.all
48    }
49}
50
51impl Drop for AudioBuffers<'_> {
52    fn drop(&mut self) {
53        self.pulse1.clear();
54        self.pulse2.clear();
55        self.wave.clear();
56        self.noise.clear();
57        self.all.clear();
58    }
59}
60
61bitflags! {
62    #[derive(Savable)]
63    #[savable(bitflags)]
64    struct ChannelsControl: u8 {
65        const VIN_LEFT  = 1 << 7;
66        const VOL_LEFT  = 7 << 4;
67        const VIN_RIGHT = 1 << 3;
68        const VOL_RIGHT = 7;
69    }
70}
71
72impl ChannelsControl {
73    fn vol_left(&self) -> u8 {
74        (self.bits() >> 4) & 7
75    }
76
77    fn vol_right(&self) -> u8 {
78        self.bits() & 7
79    }
80}
81
82bitflags! {
83    #[derive(Savable)]
84    #[savable(bitflags)]
85    struct ChannelsSelection: u8 {
86        const NOISE_LEFT   = 1 << 7;
87        const WAVE_LEFT    = 1 << 6;
88        const PULSE2_LEFT  = 1 << 5;
89        const PULSE1_LEFT  = 1 << 4;
90        const NOISE_RIGHT  = 1 << 3;
91        const WAVE_RIGHT   = 1 << 2;
92        const PULSE2_RIGHT = 1 << 1;
93        const PULSE1_RIGHT = 1 << 0;
94    }
95}
96
97#[derive(Savable)]
98pub struct Apu {
99    pulse1: Dac<LengthCountedChannel<PulseChannel>>,
100    pulse2: Dac<LengthCountedChannel<PulseChannel>>,
101    wave: Dac<LengthCountedChannel<WaveChannel>>,
102    noise: Dac<LengthCountedChannel<NoiseChannel>>,
103
104    channels_control: ChannelsControl,
105    channels_selection: ChannelsSelection,
106
107    power: bool,
108
109    sample_counter: f64,
110
111    #[savable(skip)]
112    buffer: Vec<f32>,
113    #[savable(skip)]
114    pulse1_buffers: Vec<f32>,
115    #[savable(skip)]
116    pulse2_buffers: Vec<f32>,
117    #[savable(skip)]
118    wave_buffers: Vec<f32>,
119    #[savable(skip)]
120    noise_buffers: Vec<f32>,
121
122    /// Stores the value of the 4th bit (5th in double speed mode) of the divider
123    /// as sequencer clocks are controlled by the divider
124    divider_sequencer_clock_bit: bool,
125
126    /// The frame sequencer position, the frame sequencer has 8 positions
127    /// from 1 to 8 in this emulator (as it is incremented before use)
128    /// In each position some components are clocked.
129    /// Length counters are clocked in positions 1, 3, 5, 7
130    /// Volume Envelops are clocked in positions 8
131    /// Sweeps          are clocked in positions 3, 7
132    sequencer_position: i8,
133
134    // Keep track when to clock the APU, it should be clocked every 4 tcycles
135    // this is to keep working normally even in CPU double speed mode
136    clocks_counter: u8,
137
138    config: GameBoyConfig,
139}
140
141impl Apu {
142    pub fn new(config: GameBoyConfig) -> Self {
143        Self {
144            channels_control: ChannelsControl::from_bits_truncate(0),
145            channels_selection: ChannelsSelection::from_bits_truncate(0),
146            power: false,
147            buffer: Vec::new(),
148
149            pulse1_buffers: Vec::new(),
150            pulse2_buffers: Vec::new(),
151            wave_buffers: Vec::new(),
152            noise_buffers: Vec::new(),
153
154            sample_counter: 0.,
155            pulse1: Dac::new(LengthCountedChannel::new(PulseChannel::default(), 64)),
156            pulse2: Dac::new(LengthCountedChannel::new(PulseChannel::default(), 64)),
157            wave: Dac::new(LengthCountedChannel::new(WaveChannel::new(config), 256)),
158            noise: Dac::new(LengthCountedChannel::new(NoiseChannel::default(), 64)),
159            divider_sequencer_clock_bit: false,
160            sequencer_position: 0,
161            clocks_counter: 0,
162
163            config,
164        }
165    }
166
167    pub fn new_skip_boot_rom(config: GameBoyConfig) -> Self {
168        let mut apu = Self::new(config);
169
170        // after boot_rom state
171        apu.pulse1.channel_mut().write_pattern_duty(2);
172        apu.pulse1
173            .channel_mut()
174            .envelope_mut()
175            .write_envelope_register(0xF3);
176        apu.noise.write_sound_length(0x3F);
177        apu.channels_control = ChannelsControl::from_bits_truncate(0x77);
178        apu.channels_selection = ChannelsSelection::from_bits_truncate(0xF3);
179        apu.pulse1.set_enable(true);
180        apu.wave.set_dac_enable(false);
181        apu.power = true;
182
183        apu
184    }
185
186    pub fn read_register(&mut self, addr: u16) -> u8 {
187        match addr {
188            0xFF10 => 0x80 | self.pulse1.channel_mut().read_sweep_register(),
189            0xFF11 => 0x3F | (self.pulse1.channel_mut().read_pattern_duty() << 6),
190            0xFF12 => self.pulse1.channel().envelope().read_envelope_register(),
191            0xFF13 => 0xFF,
192            0xFF14 => 0xBF | ((self.pulse1.read_length_enable() as u8) << 6),
193
194            0xFF15 => 0xFF,
195            0xFF16 => 0x3F | (self.pulse2.channel_mut().read_pattern_duty() << 6),
196            0xFF17 => self.pulse2.channel().envelope().read_envelope_register(),
197            0xFF18 => 0xFF,
198            0xFF19 => 0xBF | ((self.pulse2.read_length_enable() as u8) << 6),
199
200            0xFF1A => 0x7F | ((self.wave.dac_enabled() as u8) << 7),
201            0xFF1B => 0xFF,
202            0xFF1C => 0x9F | ((self.wave.channel().read_volume()) << 5),
203            0xFF1D => 0xFF,
204            0xFF1E => 0xBF | ((self.wave.read_length_enable() as u8) << 6),
205
206            0xFF1F => 0xFF,
207            0xFF20 => 0xFF,
208            0xFF21 => self.noise.channel().envelope().read_envelope_register(),
209            0xFF22 => self.noise.channel().read_noise_register(),
210            0xFF23 => 0xBF | ((self.noise.read_length_enable() as u8) << 6),
211
212            0xFF24 => self.channels_control.bits(),
213            0xFF25 => self.channels_selection.bits(),
214            0xFF26 => {
215                0x70 | ((self.power as u8) << 7)
216                    | ((self.noise.enabled() as u8) << 3)
217                    | ((self.wave.enabled() as u8) << 2)
218                    | ((self.pulse2.enabled() as u8) << 1)
219                    | self.pulse1.enabled() as u8
220            }
221
222            0xFF27..=0xFF2F => 0xFF,
223
224            0xFF30..=0xFF3F => self.wave.channel().read_buffer((addr & 0xF) as u8),
225            _ => unreachable!(),
226        }
227    }
228
229    pub fn write_register(&mut self, addr: u16, data: u8) {
230        // `addr % 5 != 2` will be true if its not a length counter register,
231        // as these are not affected by power off, but `addr % 5 != 2` also
232        // includes `0xFF25` and we don't want to be able to write to it
233        if !self.power && addr <= 0xFF25 && (addr % 5 != 2 || addr == 0xFF25) {
234            return;
235        }
236
237        let is_length_clock_next = self.is_length_clock_next();
238
239        match addr {
240            0xFF10 => self.pulse1.channel_mut().write_sweep_register(data),
241            0xFF11 => {
242                if self.power {
243                    self.pulse1.channel_mut().write_pattern_duty(data >> 6);
244                }
245
246                self.pulse1.write_sound_length(data & 0x3F);
247            }
248            0xFF12 => {
249                self.pulse1
250                    .channel_mut()
251                    .envelope_mut()
252                    .write_envelope_register(data);
253
254                self.pulse1.set_dac_enable(data & 0xF8 != 0);
255            }
256            0xFF13 => {
257                let freq = (self.pulse1.channel().frequency() & 0xFF00) | data as u16;
258                self.pulse1.channel_mut().write_frequency(freq);
259            }
260            0xFF14 => {
261                let freq =
262                    (self.pulse1.channel().frequency() & 0xFF) | (((data as u16) & 0x7) << 8);
263                self.pulse1.channel_mut().write_frequency(freq);
264
265                Self::write_channel_length_enable_and_trigger(
266                    &mut *self.pulse1,
267                    is_length_clock_next,
268                    data,
269                );
270            }
271
272            0xFF15 => {}
273            0xFF16 => {
274                if self.power {
275                    self.pulse2.channel_mut().write_pattern_duty(data >> 6);
276                }
277
278                self.pulse2.write_sound_length(data & 0x3F);
279            }
280            0xFF17 => {
281                self.pulse2
282                    .channel_mut()
283                    .envelope_mut()
284                    .write_envelope_register(data);
285
286                self.pulse2.set_dac_enable(data & 0xF8 != 0);
287            }
288            0xFF18 => {
289                let freq = (self.pulse2.channel().frequency() & 0xFF00) | data as u16;
290                self.pulse2.channel_mut().write_frequency(freq);
291            }
292            0xFF19 => {
293                let freq =
294                    (self.pulse2.channel().frequency() & 0xFF) | (((data as u16) & 0x7) << 8);
295                self.pulse2.channel_mut().write_frequency(freq);
296
297                Self::write_channel_length_enable_and_trigger(
298                    &mut *self.pulse2,
299                    is_length_clock_next,
300                    data,
301                );
302            }
303
304            0xFF1A => {
305                self.wave.set_dac_enable(data & 0x80 != 0);
306            }
307            0xFF1B => {
308                self.wave.write_sound_length(data);
309            }
310            0xFF1C => self.wave.channel_mut().write_volume((data >> 5) & 3),
311            0xFF1D => {
312                let freq = (self.wave.channel().frequency() & 0xFF00) | data as u16;
313                self.wave.channel_mut().write_frequency(freq);
314            }
315            0xFF1E => {
316                let freq = (self.wave.channel().frequency() & 0xFF) | (((data as u16) & 0x7) << 8);
317                self.wave.channel_mut().write_frequency(freq);
318
319                Self::write_channel_length_enable_and_trigger(
320                    &mut *self.wave,
321                    is_length_clock_next,
322                    data,
323                );
324            }
325
326            0xFF1F => {}
327            0xFF20 => self.noise.write_sound_length(data & 0x3F),
328            0xFF21 => {
329                self.noise
330                    .channel_mut()
331                    .envelope_mut()
332                    .write_envelope_register(data);
333
334                self.noise.set_dac_enable(data & 0xF8 != 0);
335            }
336            0xFF22 => self.noise.channel_mut().write_noise_register(data),
337            0xFF23 => {
338                Self::write_channel_length_enable_and_trigger(
339                    &mut *self.noise,
340                    is_length_clock_next,
341                    data,
342                );
343            }
344
345            0xFF24 => self.channels_control = ChannelsControl::from_bits_truncate(data),
346            0xFF25 => self.channels_selection = ChannelsSelection::from_bits_truncate(data),
347
348            0xFF26 => {
349                let new_power = data & 0x80 != 0;
350                if self.power && !new_power {
351                    self.power_off();
352                } else if !self.power && new_power {
353                    self.power_on();
354                }
355
356                // update `self.power` after `power_off`, because we
357                // need to be able to write zeros to registers normally
358                self.power = new_power;
359            }
360
361            0xFF27..=0xFF2F => {
362                // unused
363            }
364
365            0xFF30..=0xFF3F => {
366                self.wave
367                    .channel_mut()
368                    .write_buffer((addr & 0xF) as u8, data);
369            }
370            _ => unreachable!(),
371        }
372    }
373
374    pub fn read_pcm12(&self) -> u8 {
375        let p1 = self.pulse1.output() & 0xF;
376        let p2 = self.pulse2.output() & 0xF;
377
378        (p2 << 4) | p1
379    }
380
381    pub fn read_pcm34(&self) -> u8 {
382        let p1 = self.wave.output() & 0xF;
383        let p2 = self.noise.output() & 0xF;
384
385        (p2 << 4) | p1
386    }
387
388    pub fn get_buffers(&mut self) -> AudioBuffers<'_> {
389        AudioBuffers {
390            pulse1: &mut self.pulse1_buffers,
391            pulse2: &mut self.pulse2_buffers,
392            wave: &mut self.wave_buffers,
393            noise: &mut self.noise_buffers,
394
395            all: &mut self.buffer,
396        }
397    }
398
399    /// The APU is clocked by the divider, on the falling edge of the bit 12
400    /// of the divider, this is needed since the divider can be clocked manually
401    /// by resetting it to 0 on write
402    pub fn clock(&mut self, double_speed: bool, divider: u8) {
403        // 2 in normal speed, 1 in double speed
404        let clocks = (!double_speed) as u8 + 1;
405
406        self.clocks_counter += clocks;
407        if self.clocks_counter >= 2 {
408            self.clocks_counter -= 2;
409        } else {
410            // don't do anything, wait for the next cycle
411            return;
412        }
413
414        const SAMPLE_RATE: f64 = 44100.;
415        const SAMPLE_EVERY_N_CLOCKS: f64 = (((16384 * 256) / 4) as f64) / SAMPLE_RATE;
416
417        self.sample_counter += 1.;
418        if self.sample_counter >= SAMPLE_EVERY_N_CLOCKS {
419            self.push_output();
420
421            self.sample_counter -= SAMPLE_EVERY_N_CLOCKS;
422        }
423
424        if !self.power {
425            return;
426        }
427
428        self.pulse1.channel_mut().clock();
429        self.pulse2.channel_mut().clock();
430        self.wave.channel_mut().clock();
431        self.noise.channel_mut().clock();
432
433        let old_div_sequencer_bit = self.divider_sequencer_clock_bit;
434        let bit = if double_speed { 5 } else { 4 };
435        let new_div_sequencer_bit = (divider >> bit) & 1 == 1;
436
437        self.divider_sequencer_clock_bit = new_div_sequencer_bit;
438
439        if old_div_sequencer_bit && !new_div_sequencer_bit {
440            self.sequencer_position += 1;
441
442            match self.sequencer_position {
443                1 | 5 => {
444                    self.pulse1.clock_length_counter();
445                    self.pulse2.clock_length_counter();
446                    self.wave.clock_length_counter();
447                    self.noise.clock_length_counter();
448                }
449                3 | 7 => {
450                    self.pulse1.channel_mut().clock_sweeper();
451                    self.pulse1.clock_length_counter();
452                    self.pulse2.clock_length_counter();
453                    self.wave.clock_length_counter();
454                    self.noise.clock_length_counter();
455                }
456                8 => {
457                    self.pulse1.channel_mut().envelope_mut().clock();
458                    self.pulse2.channel_mut().envelope_mut().clock();
459                    self.noise.channel_mut().envelope_mut().clock();
460                    self.sequencer_position = 0;
461                }
462                0 | 2 | 4 | 6 => {}
463                _ => unreachable!(),
464            }
465        }
466    }
467}
468
469impl Apu {
470    fn push_output(&mut self) {
471        let right_vol = self.channels_control.vol_right() as f32 + 1.;
472        let left_vol = self.channels_control.vol_left() as f32 + 1.;
473
474        let pulse1 = self.pulse1.dac_output() / 8.;
475        let pulse2 = self.pulse2.dac_output() / 8.;
476        let wave = self.wave.dac_output() / 8.;
477        let noise = self.noise.dac_output() / 8.;
478
479        let right_pulse1 = if self
480            .channels_selection
481            .contains(ChannelsSelection::PULSE1_RIGHT)
482        {
483            pulse1 * right_vol
484        } else {
485            0.
486        };
487
488        let right_pulse2 = if self
489            .channels_selection
490            .contains(ChannelsSelection::PULSE2_RIGHT)
491        {
492            pulse2 * right_vol
493        } else {
494            0.
495        };
496
497        let right_wave = if self
498            .channels_selection
499            .contains(ChannelsSelection::WAVE_RIGHT)
500        {
501            wave * right_vol
502        } else {
503            0.
504        };
505
506        let right_noise = if self
507            .channels_selection
508            .contains(ChannelsSelection::NOISE_RIGHT)
509        {
510            noise * right_vol
511        } else {
512            0.
513        };
514
515        let left_pulse1 = if self
516            .channels_selection
517            .contains(ChannelsSelection::PULSE1_LEFT)
518        {
519            pulse1 * left_vol
520        } else {
521            0.
522        };
523
524        let left_pulse2 = if self
525            .channels_selection
526            .contains(ChannelsSelection::PULSE2_LEFT)
527        {
528            pulse2 * left_vol
529        } else {
530            0.
531        };
532
533        let left_wave = if self
534            .channels_selection
535            .contains(ChannelsSelection::WAVE_LEFT)
536        {
537            wave * left_vol
538        } else {
539            0.
540        };
541
542        let left_noise = if self
543            .channels_selection
544            .contains(ChannelsSelection::NOISE_LEFT)
545        {
546            noise * left_vol
547        } else {
548            0.
549        };
550
551        // one sample for the right, one for the left
552
553        let right_pulse1 = right_pulse1 / 5.0;
554        let left_pulse1 = left_pulse1 / 5.0;
555        let right_pulse2 = right_pulse2 / 5.0;
556        let left_pulse2 = left_pulse2 / 5.0;
557        let right_wave = right_wave / 5.0;
558        let left_wave = left_wave / 5.0;
559        let right_noise = right_noise / 5.0;
560        let left_noise = left_noise / 5.0;
561
562        self.pulse1_buffers.push(right_pulse1);
563        self.pulse1_buffers.push(left_pulse1);
564
565        self.pulse2_buffers.push(right_pulse2);
566        self.pulse2_buffers.push(left_pulse2);
567
568        self.wave_buffers.push(right_wave);
569        self.wave_buffers.push(left_wave);
570
571        self.noise_buffers.push(right_noise);
572        self.noise_buffers.push(left_noise);
573
574        let right_sample = right_pulse1 + right_pulse2 + right_wave + right_noise;
575        let left_sample = left_pulse1 + left_pulse2 + left_wave + left_noise;
576        self.buffer.push(right_sample);
577        self.buffer.push(left_sample);
578    }
579
580    fn power_off(&mut self) {
581        for i in 0xFF10..=0xFF25 {
582            self.write_register(i, 0);
583        }
584
585        self.pulse1.set_enable(false);
586        self.pulse2.set_enable(false);
587        self.wave.set_enable(false);
588        self.noise.set_enable(false);
589    }
590
591    fn power_on(&mut self) {
592        self.sequencer_position = 0;
593
594        // Special case where if the APU is turned on and bit 4 (5 in double speed)
595        // of the divider is set, the APU will delay the next clock, so it will take
596        // 2 clocks to reach the first event in the sequencer instead of 1
597        //
598        // See: SameSuite test apu/div_write_trigger_10, Note: In the test it describes
599        // that the APU `skips` the first event and not delay it which is wrong
600        if self.divider_sequencer_clock_bit {
601            self.sequencer_position = -1;
602        }
603
604        self.pulse1.channel_mut().reset_sequencer();
605        self.pulse2.channel_mut().reset_sequencer();
606        self.wave.channel_mut().reset_buffer_index();
607
608        if !self.config.is_dmg {
609            // reset length counters in CGB
610            self.pulse1.reset_length_counter();
611            self.pulse2.reset_length_counter();
612            self.wave.reset_length_counter();
613            self.noise.reset_length_counter();
614        }
615    }
616
617    /// determines if the next frame sequencer clock is going to include
618    /// clocking the length counter
619    fn is_length_clock_next(&self) -> bool {
620        (self.sequencer_position + 1) % 2 != 0
621    }
622
623    /// write the top 2 bits of NRx4 registers and runs the obsecure
624    /// behaviour of clocking the length counter
625    fn write_channel_length_enable_and_trigger<C: ApuChannel>(
626        channel: &mut LengthCountedChannel<C>,
627        is_length_clock_next: bool,
628        data: u8,
629    ) {
630        let old_length_enable = channel.read_length_enable();
631        let new_length_enable = (data >> 6) & 1 == 1;
632        channel.write_length_enable(new_length_enable);
633
634        // obsecure behaviour: if the length decrement is enabled now (was not),
635        // and the sequencer will not clock length, then clock it now
636        if !is_length_clock_next && !old_length_enable && new_length_enable {
637            channel.clock_length_counter();
638        }
639
640        if data & 0x80 != 0 {
641            // trigger length, which would trigger the channel inside
642            channel.trigger_length(!is_length_clock_next);
643        }
644    }
645}