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}