Skip to main content

gb/
apu.rs

1//! The four sound channels and the mixer.
2//!
3//! Each channel has a configuration type: [`Pulse`] for channels 1 and 2,
4//! [`Wave`] for channel 3, [`Noise`] for channel 4. Building one is a chain of
5//! const methods, and `play` writes it out and starts the channel.
6//!
7//! ```ignore
8//! const JUMP: Pulse = Pulse::new(12).note(Note::C, 5).length(8);
9//!
10//! JUMP.play_ch2();
11//! ```
12//!
13//! A sound played from one place belongs in a constant. A set of them played
14//! from the same place belongs in a table.
15//!
16//! See <https://gbdev.io/pandocs/Audio.html>.
17//!
18//! # Power
19//!
20//! The boot ROM leaves the APU on at full volume. A program that only wants
21//! sound has nothing to set up. It does leave channels 3 and 4 reaching the
22//! left output alone, which [`set_panning`] settles.
23//!
24//! [`power_off`] draws less current and is worth having on a pause screen;
25//! [`power_on`] comes back from it.
26//!
27//! # Writing to `DIV`
28//!
29//! Envelopes, length timers and the channel 1 sweep are all counted off `DIV`,
30//! so [`timer::reset_divider`](crate::timer::reset_divider) steps them early.
31//! Resetting it while sound is playing is audible.
32
33#[cfg(feature = "cgb")]
34use crate::mmio::cgb::{PCM12, PCM34};
35use crate::mmio::{
36    AudioCtrl, Duty, Envelope, MasterVolume, NR10, NR11, NR12, NR13, NR14, NR21, NR22, NR23, NR24,
37    NR30, NR31, NR32, NR33, NR34, NR41, NR42, NR43, NR44, NR50, NR51, NR52, NoiseCtrl, NoiseFreq,
38    Panning, PeriodCtrl, PulseLengthDuty, Sweep, WAVE_RAM, WaveDac, WaveLevel, WaveOutput,
39};
40
41/// Power the APU on.
42///
43/// [`power_off`] took the master volume and the panning down with everything
44/// else, so [`set_master`] and [`set_panning`] have to follow this or nothing
45/// reaches the output.
46#[inline]
47pub fn power_on() {
48    NR52.write(AudioCtrl::new().with_audio_on(true));
49}
50
51/// Power the APU off.
52///
53/// Every audio register is cleared and stays read-only until [`power_on`]. Wave
54/// RAM survives. All four DACs go off together, so this clicks unless the
55/// channels were quiet already.
56#[inline]
57pub fn power_off() {
58    NR52.write(AudioCtrl::new());
59}
60
61/// Set the master volume.
62///
63/// The output moves as the volume does, so this clicks unless everything is
64/// already quiet. Fading a tune out with it is audible on top of the fade.
65#[inline]
66pub fn set_master(master: MasterVolume) {
67    NR50.write(master);
68}
69
70/// Set which channels reach which output.
71///
72/// Taking a channel whose DAC is on off an output, or putting it back, moves
73/// that output and clicks. Panning a channel that is playing is heard.
74#[inline]
75pub fn set_panning(panning: Panning) {
76    NR51.write(panning);
77}
78
79/// One of the twelve semitones.
80#[derive(Clone, Copy, Debug, PartialEq, Eq)]
81#[repr(u8)]
82pub enum Note {
83    C,
84    Cs,
85    D,
86    Ds,
87    E,
88    F,
89    Fs,
90    G,
91    Gs,
92    A,
93    As,
94    B,
95}
96
97/// The eighth octave in millihertz. Lower ones come from shifting this down,
98/// which keeps the division that follows precise.
99const OCTAVE_8: [u32; 12] = [
100    4_186_009, 4_434_922, 4_698_636, 4_978_032, 5_274_041, 5_587_652, 5_919_911, 6_271_927,
101    6_644_875, 7_040_000, 7_458_620, 7_902_133,
102];
103
104/// The period value that comes nearest `note` at `octave`, for a channel whose
105/// waveform repeats `clock` times a second at a period value of one.
106const fn period(note: Note, octave: u8, clock: u32) -> u16 {
107    let octave = if octave > 8 { 8 } else { octave };
108    let millihertz = OCTAVE_8[note as usize] >> (8 - octave);
109    let divider = (clock + millihertz / 2) / millihertz;
110    if divider >= 2048 {
111        0
112    } else {
113        (2048 - divider) as u16
114    }
115}
116
117/// Turn `ticks` of a length timer into the value the register takes, which
118/// counts up to `limit` from what is written.
119const fn length_from(ticks: u16, limit: u16) -> u8 {
120    let ticks = if ticks == 0 {
121        1
122    } else if ticks > limit {
123        limit
124    } else {
125        ticks
126    };
127    (limit - ticks) as u8
128}
129
130/// A pulse channel's settings.
131///
132/// Channels 1 and 2 differ only in that 1 has a frequency sweep, so one of
133/// these plays on either.
134#[derive(Clone, Copy, PartialEq, Eq)]
135pub struct Pulse {
136    length_duty: PulseLengthDuty,
137    envelope: Envelope,
138    period_low: u8,
139    period_ctrl: PeriodCtrl,
140}
141
142impl Pulse {
143    /// A 50% square wave at `volume`, out of 15, and the lowest period.
144    ///
145    /// A volume of 0 is not a quiet sound but a stopped channel: it turns the
146    /// DAC off, and a channel whose DAC is off will not start.
147    #[inline]
148    pub const fn new(volume: u8) -> Self {
149        Pulse {
150            length_duty: PulseLengthDuty::new().with_duty(Duty::Half),
151            envelope: Envelope::new().with_volume(if volume > 15 { 15 } else { volume }),
152            period_low: 0,
153            period_ctrl: PeriodCtrl::new().with_trigger(true),
154        }
155    }
156
157    /// Tune to `note` at `octave`.
158    ///
159    /// C2 through B5 comes out within about five cents. There is nothing below
160    /// C2 to reach and the pitch stops there; above B5 the period value runs
161    /// out of resolution and drifts, a quarter tone off by the eighth octave.
162    #[inline]
163    pub const fn note(self, note: Note, octave: u8) -> Self {
164        self.at_period(period(note, octave, 131_072_000))
165    }
166
167    /// Tune to a period value, which counts up rather than down: the larger it
168    /// is, the higher the pitch. At most `$7FF`.
169    #[inline]
170    pub const fn at_period(self, period: u16) -> Self {
171        let period = if period > 0x7FF { 0x7FF } else { period };
172        Pulse {
173            period_low: period as u8,
174            period_ctrl: self.period_ctrl.with_period_high((period >> 8) as u8 & 7),
175            ..self
176        }
177    }
178
179    /// Set the fraction of each cycle the wave spends high.
180    #[inline]
181    pub const fn duty(self, duty: Duty) -> Self {
182        Pulse {
183            length_duty: self.length_duty.with_duty(duty),
184            ..self
185        }
186    }
187
188    /// Step the volume every `pace` ticks of a 64 Hz count, up or down.
189    ///
190    /// A pace of 0 holds the volume where [`Pulse::new`] put it.
191    #[inline]
192    pub const fn envelope(self, pace: u8, increase: bool) -> Self {
193        Pulse {
194            envelope: self
195                .envelope
196                .with_pace(if pace > 7 { 7 } else { pace })
197                .with_increase(increase),
198            ..self
199        }
200    }
201
202    /// Stop the channel after `ticks` of a 256 Hz count, at most 64.
203    #[inline]
204    pub const fn length(self, ticks: u8) -> Self {
205        Pulse {
206            length_duty: self.length_duty.with_length(length_from(ticks as u16, 64)),
207            period_ctrl: self.period_ctrl.with_length_enable(true),
208            ..self
209        }
210    }
211
212    /// Play on channel 1, with `sweep` bending the pitch as it goes.
213    ///
214    /// The sweep is asked for because it belongs to the channel rather than to
215    /// these settings, and one left over from an earlier sound would bend this
216    /// one. [`Sweep::new`] leaves the pitch alone.
217    ///
218    /// The trigger decides whether a sweep runs at all, so a note started
219    /// without one cannot be given one part way through.
220    ///
221    /// A rising sweep is checked against the top as the note is triggered: a
222    /// step that would carry a high note past `$7FF` in one move cuts it before
223    /// anything is heard. The smaller the step number, the larger the move. A
224    /// falling sweep cannot reach the top and is never cut.
225    #[inline]
226    pub fn play_ch1(&self, sweep: Sweep) {
227        NR10.write(sweep);
228        NR11.write(self.length_duty);
229        NR12.write(self.envelope);
230        NR13.write(self.period_low);
231        NR14.write(self.period_ctrl);
232    }
233
234    /// Play on channel 2.
235    #[inline]
236    pub fn play_ch2(&self) {
237        NR21.write(self.length_duty);
238        NR22.write(self.envelope);
239        NR23.write(self.period_low);
240        NR24.write(self.period_ctrl);
241    }
242
243    /// Change the pitch on channel 1 without starting the note over.
244    ///
245    /// A running sweep holds its own copy of the pitch and writes that back at
246    /// its next step, so this reaches a channel playing without one.
247    #[inline]
248    pub fn retune_ch1(&self) {
249        NR13.write(self.period_low);
250        NR14.write(self.period_ctrl.with_trigger(false));
251    }
252
253    /// Change the pitch on channel 2 without starting the note over.
254    ///
255    /// The envelope and the waveform carry on from where they are, as a slide
256    /// or a vibrato needs. [`Pulse::play_ch2`] restarts both.
257    #[inline]
258    pub fn retune_ch2(&self) {
259        NR23.write(self.period_low);
260        NR24.write(self.period_ctrl.with_trigger(false));
261    }
262
263    /// Change the duty on channel 1 without starting the note over.
264    ///
265    /// The length timer shares the register and starts over with it.
266    #[inline]
267    pub fn set_duty_ch1(&self) {
268        NR11.write(self.length_duty);
269    }
270
271    /// Change the duty on channel 2 without starting the note over.
272    ///
273    /// The length timer shares the register and starts over with it.
274    #[inline]
275    pub fn set_duty_ch2(&self) {
276        NR21.write(self.length_duty);
277    }
278}
279
280/// Channel 3's settings, which play whatever [`load_wave`] last put in wave RAM.
281///
282/// There is no envelope here, and the volume is the four steps of [`WaveLevel`].
283#[derive(Clone, Copy, PartialEq, Eq)]
284pub struct Wave {
285    length: u8,
286    output: WaveOutput,
287    period_low: u8,
288    period_ctrl: PeriodCtrl,
289}
290
291impl Wave {
292    /// The wave at `level`, at the lowest period.
293    #[inline]
294    pub const fn new(level: WaveLevel) -> Self {
295        Wave {
296            length: 0,
297            output: WaveOutput::new().with_level(level),
298            period_low: 0,
299            period_ctrl: PeriodCtrl::new().with_trigger(true),
300        }
301    }
302
303    /// Tune to `note` at `octave`.
304    ///
305    /// This channel reads its waveform half as fast as a pulse channel, so its
306    /// range sits an octave below theirs: C1 through B4 within about five
307    /// cents, nothing lower to reach, and the same drift above.
308    #[inline]
309    pub const fn note(self, note: Note, octave: u8) -> Self {
310        self.at_period(period(note, octave, 65_536_000))
311    }
312
313    /// Tune to a period value, which counts up rather than down: the larger it
314    /// is, the higher the pitch. At most `$7FF`.
315    #[inline]
316    pub const fn at_period(self, period: u16) -> Self {
317        let period = if period > 0x7FF { 0x7FF } else { period };
318        Wave {
319            period_low: period as u8,
320            period_ctrl: self.period_ctrl.with_period_high((period >> 8) as u8 & 7),
321            ..self
322        }
323    }
324
325    /// Stop the channel after `ticks` of a 256 Hz count, at most 256.
326    #[inline]
327    pub const fn length(self, ticks: u16) -> Self {
328        Wave {
329            length: length_from(ticks, 256),
330            period_ctrl: self.period_ctrl.with_length_enable(true),
331            ..self
332        }
333    }
334
335    /// Play on channel 3.
336    ///
337    /// Triggering the channel while it is already playing can corrupt wave RAM
338    /// on an original Game Boy. [`stop`] first avoids that and costs a click.
339    #[inline]
340    pub fn play(&self) {
341        NR30.write(WaveDac::new().with_dac_on(true));
342        NR31.write(self.length);
343        NR32.write(self.output);
344        NR33.write(self.period_low);
345        NR34.write(self.period_ctrl);
346    }
347
348    /// Change the pitch without starting the waveform over.
349    #[inline]
350    pub fn retune(&self) {
351        NR33.write(self.period_low);
352        NR34.write(self.period_ctrl.with_trigger(false));
353    }
354
355    /// Change the output level without starting the waveform over.
356    ///
357    /// Channel 3 has no envelope, so this is how its volume moves during a
358    /// note.
359    #[inline]
360    pub fn set_level(&self) {
361        NR32.write(self.output);
362    }
363}
364
365/// Load the 32 four-bit samples channel 3 plays, high nibble of each byte first.
366///
367/// Channel 3 stops first, because wave RAM reached while it is playing does not
368/// answer for the address asked for. That means a click if it was playing, so
369/// this belongs in a quiet moment. Play a [`Wave`] to start it again.
370#[inline]
371pub fn load_wave(samples: &[u8; 16]) {
372    NR30.write(WaveDac::new());
373    let mut i = 0;
374    while i < 16 {
375        WAVE_RAM.index(i).write(samples[i]);
376        i += 1;
377    }
378}
379
380/// Channel 4's settings.
381///
382/// The pitch is a clock divider and shift rather than a note, since what comes
383/// out is noise and is chosen by ear.
384#[derive(Clone, Copy, PartialEq, Eq)]
385pub struct Noise {
386    length: u8,
387    envelope: Envelope,
388    freq: NoiseFreq,
389    ctrl: NoiseCtrl,
390}
391
392impl Noise {
393    /// Noise at `volume`, out of 15, clocked at `262144 / (divider << shift)`
394    /// hertz, where a divider of 0 counts as a half.
395    ///
396    /// A volume of 0 is not a quiet sound but a stopped channel: it turns the
397    /// DAC off, and a channel whose DAC is off will not start.
398    ///
399    /// A shift of 14 or 15 stops the clock, and neither is reachable here.
400    #[inline]
401    pub const fn new(volume: u8, divider: u8, shift: u8) -> Self {
402        Noise {
403            length: 0,
404            envelope: Envelope::new().with_volume(if volume > 15 { 15 } else { volume }),
405            freq: NoiseFreq::new()
406                .with_divider(if divider > 7 { 7 } else { divider })
407                .with_shift(if shift > 13 { 13 } else { shift }),
408            ctrl: NoiseCtrl::new().with_trigger(true),
409        }
410    }
411
412    /// Run the shift register seven bits wide, which repeats often enough to
413    /// carry a pitch.
414    #[inline]
415    pub const fn short_lfsr(self) -> Self {
416        Noise {
417            freq: self.freq.with_short_lfsr(true),
418            ..self
419        }
420    }
421
422    /// Step the volume every `pace` ticks of a 64 Hz count, up or down.
423    ///
424    /// A pace of 0 holds the volume where [`Noise::new`] put it.
425    #[inline]
426    pub const fn envelope(self, pace: u8, increase: bool) -> Self {
427        Noise {
428            envelope: self
429                .envelope
430                .with_pace(if pace > 7 { 7 } else { pace })
431                .with_increase(increase),
432            ..self
433        }
434    }
435
436    /// Stop the channel after `ticks` of a 256 Hz count, at most 64.
437    #[inline]
438    pub const fn length(self, ticks: u8) -> Self {
439        Noise {
440            length: length_from(ticks as u16, 64),
441            ctrl: self.ctrl.with_length_enable(true),
442            ..self
443        }
444    }
445
446    /// Play on channel 4.
447    #[inline]
448    pub fn play(&self) {
449        NR41.write(self.length);
450        NR42.write(self.envelope);
451        NR43.write(self.freq);
452        NR44.write(self.ctrl);
453    }
454}
455
456/// One of the four sound channels.
457#[derive(Clone, Copy, Debug, PartialEq, Eq)]
458pub enum Channel {
459    /// Pulse, with a frequency sweep.
460    One,
461    /// Pulse.
462    Two,
463    /// Wave.
464    Three,
465    /// Noise.
466    Four,
467}
468
469/// Take a channel down to nothing without stopping it.
470///
471/// The DAC stays on, which is the difference from [`stop`]: switching one off
472/// moves the output enough to click.
473///
474/// On channels 1 and 2 the pitch goes down with the volume, so playing again is
475/// how one of those comes back.
476#[inline]
477pub fn silence(ch: Channel) {
478    // A plain 0 would take the DAC down with it; volume 0 rising leaves it up.
479    // The channel then has to be triggered for the new volume to reach it.
480    const QUIET: Envelope = Envelope::new().with_increase(true);
481    const RETRIGGER: PeriodCtrl = PeriodCtrl::new().with_trigger(true);
482    match ch {
483        Channel::One => {
484            NR12.write(QUIET);
485            NR14.write(RETRIGGER);
486        }
487        Channel::Two => {
488            NR22.write(QUIET);
489            NR24.write(RETRIGGER);
490        }
491        // Channel 3 has an output level instead of an envelope, and it takes
492        // effect where it is written.
493        Channel::Three => NR32.write(WaveOutput::new().with_level(WaveLevel::Mute)),
494        Channel::Four => {
495            NR42.write(QUIET);
496            NR44.write(NoiseCtrl::new().with_trigger(true));
497        }
498    }
499}
500
501/// Stop a channel by turning its DAC off.
502///
503/// Clicks. Between notes, prefer [`silence`].
504#[inline]
505pub fn stop(ch: Channel) {
506    match ch {
507        Channel::One => NR12.write(Envelope::new()),
508        Channel::Two => NR22.write(Envelope::new()),
509        Channel::Three => NR30.write(WaveDac::new()),
510        Channel::Four => NR42.write(Envelope::new()),
511    }
512}
513
514/// Whether a channel is still running.
515///
516/// A channel stops when a length timer set by [`Pulse::length`] and its
517/// counterparts expires, when its DAC goes off, or, on channel 1, when the
518/// sweep carries the pitch past the top.
519#[inline]
520pub fn playing(ch: Channel) -> bool {
521    let status = NR52.read();
522    match ch {
523        Channel::One => status.ch1_on(),
524        Channel::Two => status.ch2_on(),
525        Channel::Three => status.ch3_on(),
526        Channel::Four => status.ch4_on(),
527    }
528}
529
530/// What a channel is putting out, from 0 to 15.
531///
532/// This is the digital value on its way to the DAC, so it moves with the
533/// envelope and the waveform rather than with the volume the mixer applies. A
534/// program drawing its own sound reads it here.
535#[cfg(feature = "cgb")]
536#[cfg_attr(docsrs, doc(cfg(feature = "cgb")))]
537#[inline]
538pub fn output(ch: Channel) -> u8 {
539    match ch {
540        Channel::One => PCM12.read().low(),
541        Channel::Two => PCM12.read().high(),
542        Channel::Three => PCM34.read().low(),
543        Channel::Four => PCM34.read().high(),
544    }
545}