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