Skip to content

Commit 3a23996

Browse files
authored
audio: change "wavelength" nomenclature to "period value" (#486)
1 parent cc0d133 commit 3a23996

File tree

5 files changed

+87
-53
lines changed

5 files changed

+87
-53
lines changed

src/Audio.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ When the length timer reaches 64, the channel is turned off.
7575
### Frequency
7676

7777
Music notes and audio waves are typically manipulated in terms of **frequency**[^pitch], i.e. how often the signal repeats per second.
78-
However, as explained above, the Game Boy APU primarily works with durations; thus, **wavelengths** will be used instead of frequency.[^len_raw]
78+
However, as explained above, the Game Boy APU primarily works with durations; thus, **periods** will be used instead of frequency.[^len_raw]
7979

8080
::: warning
8181

82-
The term "wavelength" throughout this document does *not* designate the inverse of the frequency, but instead a quantity akin to it.
82+
The terms "period" and "period value" throughout this document refer to a parameter that has a somewhat nonintuitive relationship with frequency.
8383
See the description of each NRx3 register for more information.
8484

8585
:::
@@ -105,4 +105,4 @@ There is also **pitch**, which is merely a measure of how we perceive frequency.
105105
The higher the frequency, the higher the pitch; therefore, pitch will be omitted from the rest of the document.
106106

107107
[^len_raw]:
108-
Actually, the APU interfaces don't work with any wavelengths either, but with values that are more akin to wavelengths than frequencies.
108+
Actually, the APU interfaces don't work strictly with periods, but with values that can be thought of as *negative* periods.

src/Audio_Registers.md

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ As a rule of thumb, for any `x` in `1`, `2`, `3`, `4`:
77
- `NRx0` is some channel-specific feature (if present),
88
- `NRx1` controls the length timer,
99
- `NRx2` controls the volume and envelope,
10-
- `NRx3` controls the wavelength (maybe only partially),
11-
- `NRx4` has the channel's trigger and length timer enable bits;
10+
- `NRx3` controls the period (maybe only partially),
11+
- `NRx4` has the channel's trigger and length timer enable bits, as well as any leftover bits of period;
1212

1313
...but there are some exceptions.
1414

@@ -35,7 +35,7 @@ Writing to those does NOT enable or disable the channels, despite many emulators
3535
A channel is turned on by triggering it (i.e. setting bit 7 of `NRx4`)[^dac_off].
3636
A channel is turned off when any of the following occurs:
3737
- The channel's length timer, if enabled in `NRx4`, expires
38-
- For CH1: when the wavelength sweep overflows[^freq_sweep_underflow]
38+
- For CH1: when the period sweep overflows[^freq_sweep_underflow]
3939
- [The channel's DAC](#DACs) is turned off
4040

4141
The envelope reaching a volume of 0 does NOT turn the channel off!
@@ -50,7 +50,7 @@ Actually, the low nibble of NR52 only reports whether the channels' *generation*
5050
If [the DAC](#DACs) is off, then the write to NRx4 will be ineffective and won't turn the channel on.
5151

5252
[^freq_sweep_underflow]:
53-
The wavelength sweep cannot normally underflow, so a "decreasing" sweep (`NR10` bit 3 set) won't turn the channel off.
53+
The period sweep cannot normally underflow, so a "decreasing" sweep (`NR10` bit 3 set) won't turn the channel off.
5454

5555
### FF25 — NR51: Sound panning
5656

@@ -82,46 +82,46 @@ Bit 3 - Mix VIN into right output (1=Enable)
8282
Bit 2-0 - Right output volume (0-7)
8383
```
8484

85-
## Sound Channel 1 — Pulse with wavelength sweep
85+
## Sound Channel 1 — Pulse with period sweep
8686

8787
### FF10 — NR10: Channel 1 sweep
8888

89-
This register controls CH1's wavelength sweep functionality.
89+
This register controls CH1's period sweep functionality.
9090

9191
```
9292
Bit 6-4 - Sweep pace
9393
Bit 3 - Sweep increase/decrease
94-
0: Addition (wavelength increases)
95-
1: Subtraction (wavelength decreases)
94+
0: Addition (period increases)
95+
1: Subtraction (period decreases)
9696
Bit 2-0 - Sweep slope control (n: 0-7)
9797
```
9898

99-
The <var>sweep pace</var> dictates how often the wavelength gets changed, in units of 128 Hz ticks[^div_apu] (7.8 ms).
99+
The <var>sweep pace</var> dictates how often the period gets changed, in units of 128 Hz ticks[^div_apu] (7.8 ms).
100100
The pace is only reloaded after the following sweep iteration, or when (re)triggering the channel.
101101
However, if bits 4–6 are all set to 0, then iterations are instantly disabled, and the pace will be reloaded immediately if it's set to something else.
102102

103-
On each sweep iteration, the wavelength in [`NR13`](<#FF13 — NR13: Channel 1 wavelength low \[write-only\]>) and [`NR14`](<#FF14 — NR14: Channel 1 wavelength high & control>) is modified and written back.
103+
On each sweep iteration, the period in [`NR13`](<#FF13 — NR13: Channel 1 period low \[write-only\]>) and [`NR14`](<#FF14 — NR14: Channel 1 period high & control>) is modified and written back.
104104
That is, unless <var>n</var> (the slope) is 0, in which case iterations do nothing (in this case, subtraction mode should be set, see below).
105105

106-
On each tick, the new wavelength <math><msub><mi>L</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> is computed from the current one <math><msub><mi>L</mi><mi>t</mi></msub></math> as follows:
106+
On each tick, the new period <math><msub><mi>L</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> is computed from the current one <math><msub><mi>L</mi><mi>t</mi></msub></math> as follows:
107107

108108
<math display="block">
109109
<msub><mi>L</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub> <mo>=</mo> <msub><mi>L</mi><mi>t</mi></msub> <mo>±</mo> <mfrac><msub><mi>L</mi><mi>t</mi></msub><msup><mn>2</mn><mi>n</mi></msup></mfrac>
110110
</math>
111111

112-
In addition mode, if the wavelength would overflow (i.e. <math><msub><mi>L</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> is strictly more than $7FF), the channel is turned off instead.
112+
In addition mode, if the period value would overflow (i.e. <math><msub><mi>L</mi><mrow><mi>t</mi><mo>+</mo><mn>1</mn></mrow></msub></math> is strictly more than $7FF), the channel is turned off instead.
113113
**This occurs even if sweep iterations are disabled** by <var>n</var> = 0.
114114

115-
Note that if the wavelength ever becomes 0, the wavelength sweep will never be able to change it.
116-
For the same reason, the wavelength sweep cannot underflow the wavelength (which would turn the channel off).
115+
Note that if the period ever becomes 0, the period sweep will never be able to change it.
116+
For the same reason, the period sweep cannot underflow the period (which would turn the channel off).
117117

118118
[^div_apu]:
119119
[As long as `DIV` is not written to](#DIV-APU).
120120

121121
### FF11 — NR11: Channel 1 length timer & duty cycle
122122

123123
This register controls both the channel's [length timer](<#Length timer>) and [duty cycle](https://en.wikipedia.org/wiki/Duty_cycle) (the ratio of the time spent low vs. high).
124-
However, the selected duty cycle also alters the phase, although the effect is hardly noticeable.
124+
The selected duty cycle also alters the phase, although the effect is hardly noticeable except in combination with other channels.
125125

126126
```
127127
Bit 7-6 - Wave duty (Read/Write)
@@ -169,21 +169,44 @@ The envelope ticks at 64 Hz, and the channel's envelope will be increased / decr
169169

170170
Writes to this register while the channel is on require retriggering it afterwards.
171171

172-
### FF13 — NR13: Channel 1 wavelength low \[write-only\]
172+
### FF13 — NR13: Channel 1 period low \[write-only\]
173173

174-
This register stores the low 8 bits of the channel's 11-bit "[wavelength](<#Frequency>)".
174+
This register stores the low 8 bits of the channel's 11-bit "[period value](<#Frequency>)".
175175
The upper 3 bits are stored in the low 3 bits of `NR14`.
176176

177-
The actual signal frequency is <math><mfrac><mn>131072</mn><mrow><mn>2048</mn><mo>-</mo><mi>wavelen</mi></mrow></mfrac></math> Hz: the higher the value, the higher the frequency.
178-
This is the whole wave's frequency; the rate at which the channel steps through the 8 "steps" in its wave form is 8× that, i.e. <math><mfrac><mn>1048576</mn><mrow><mn>2048</mn><mo>-</mo><mi>wavelen</mi></mrow></mfrac></math> Hz = <math><mfrac><mn>1</mn><mrow><mn>2048</mn><mo>-</mo><mn>wavelen</mn></mrow></mfrac></math> MiHz.
177+
The period divider of pulse and wave channels is an up counter.
178+
It adds one to the counter value each time it is clocked.
179+
When the value reaches the maximum (2048 or $800), it reloads the counter value from the channel's period register.
180+
This means it treats the value in the period as a *negative* number in 11-bit two's complement.
181+
The higher the period value in the register, the lower the period, and the higher the frequency.
182+
For example:
179183

180-
### FF14 — NR14: Channel 1 wavelength high & control
184+
- Period value $500 means -$300, or 1 sample per 768 input cycles
185+
- Period value $740 means -$C0, or 1 sample per 192 input cycles
186+
187+
The pulse channels' period dividers are clocked at 1048576 Hz, once per four dots, and their waveform is 8 samples long.
188+
This makes their sample rate equal to <math><mfrac><mn>1048576</mn><mrow><mn>2048</mn><mo>-</mo><mi>period_value</mi></mrow></mfrac></math> Hz.
189+
with a resulting tone frequency equal to <math><mfrac><mn>131072</mn><mrow><mn>2048</mn><mo>-</mo><mi>period_value</mi></mrow></mfrac></math> Hz.
190+
191+
- Period value $500 means -$300, or 1 sample per 768 input cycles
192+
or (1048576 ÷ 768) = 1365.3 Hz sample rate
193+
or (1048576 ÷ 768 ÷ 8) = 170.67 Hz tone frequency
194+
- Period value $740 means -$C0, or 1 sample per 192 input cycles
195+
or (1048576 ÷ 192) = 5461.3 Hz sample rate
196+
or (1048576 ÷ 192 ÷ 8) = 682.67 Hz tone frequency
197+
198+
Period value $740 produces a higher frequency than $500.
199+
Even though the period value $740 is not four times $500, $740 produces a frequency that is four times that of $500, or two octaves higher, because ($800 - $740) or 192 is one-quarter of ($800 - $500) or 768.
200+
201+
Period changes take
202+
203+
### FF14 — NR14: Channel 1 period high & control
181204

182205
```
183206
Bit 7 - Trigger (1=Restart channel) (Write Only)
184207
Bit 6 - Sound Length enable (Read/Write)
185208
(1=Stop output when length in NR11 expires)
186-
Bit 2-0 - "Wavelength"'s higher 3 bits (Write Only)
209+
Bit 2-0 - Period value's higher 3 bits (Write Only)
187210
```
188211

189212
Writing a value here with bit 7 set [triggers](<#Triggering>) the channel.
@@ -192,12 +215,12 @@ Bit 6 takes effect immediately upon writing to this register.
192215

193216
## Sound Channel 2 — Pulse
194217

195-
This sound channel works exactly like channel 1, except that it lacks a wavelength sweep (and thus an equivalent to [`NR10`](<#FF10 — NR10: Channel 1 sweep>)).
218+
This sound channel works exactly like channel 1, except that it lacks a period sweep (and thus an equivalent to [`NR10`](<#FF10 — NR10: Channel 1 sweep>)).
196219
Please refer to the corresponding CH1 register:
197220
- `NR21` (\$FF16) → [`NR11`](<#FF11 — NR11: Channel 1 length timer & duty cycle>)
198221
- `NR22` (\$FF17) → [`NR12`](<#FF12 — NR12: Channel 1 volume & envelope>)
199-
- `NR23` (\$FF18) → [`NR13`](<#FF13 — NR13: Channel 1 wavelength low \[write-only\]>)
200-
- `NR24` (\$FF19) → [`NR14`](<#FF14 — NR14: Channel 1 wavelength high & control>)
222+
- `NR23` (\$FF18) → [`NR13`](<#FF13 — NR13: Channel 1 period low \[write-only\]>)
223+
- `NR24` (\$FF19) → [`NR14`](<#FF14 — NR14: Channel 1 period high & control>)
201224

202225
## Sound Channel 3 — Wave output
203226

@@ -246,28 +269,38 @@ Bits 6-5 (binary) | Output level
246269
%10 | 50% volume (shift samples read from Wave RAM right once)
247270
%11 | 25% volume (shift samples read from Wave RAM right twice)
248271

249-
### FF1D — NR33: Channel 3 wavelength low \[write-only\]
272+
### FF1D — NR33: Channel 3 period low \[write-only\]
250273

251-
This register stores the low 8 bits of the channel's 11-bit "[wavelength](<#Frequency>)".
274+
This register stores the low 8 bits of the channel's 11-bit "[period value](<#Frequency>)".
252275
The upper 3 bits are stored in the low 3 bits of `NR34`.
253276

254-
The actual signal frequency is <math><mfrac><mn>65536</mn><mrow><mn>2048</mn><mo>-</mo><mi>wavelen</mi></mrow></mfrac></math> Hz: the higher the value, the higher the frequency.
255-
This is the whole wave's frequency; the rate at which the channel steps through the 8 "indices" in its wave form is 32 times that, i.e. <math><mfrac><mn>2097152</mn><mrow><mn>2048</mn><mo>-</mo><mi>wavelen</mi></mrow></mfrac></math>) Hz = <math><mfrac><mn>2</mn><mrow><mn>2048</mn><mo>-</mo><mi>wavelen</mi></mrow></mfrac></math> MiHz.
277+
The wave channel's period divider is clocked at 2097152 Hz, once per two dots, and its waveform is 32 samples long.
278+
This makes their sample rate equal to <math><mfrac><mn>2097152</mn><mrow><mn>2048</mn><mo>-</mo><mi>period_value</mi></mrow></mfrac></math> Hz.
279+
with a resulting tone frequency equal to <math><mfrac><mn>65536</mn><mrow><mn>2048</mn><mo>-</mo><mi>period_value</mi></mrow></mfrac></math> Hz.
280+
281+
- Period value $500 means -$300, or 1 sample per 768 input cycles
282+
or (2097152 ÷ 768) = 2730.7 Hz sample rate
283+
or (2097152 ÷ 768 ÷ 32) = 85.333 Hz tone frequency
284+
- Period value $740 means -$C0, or 1 sample per 192 input cycles
285+
or (2097152 ÷ 192) = 10923 Hz sample rate
286+
or (2097152 ÷ 192 ÷ 32) = 341.33 Hz tone frequency
287+
288+
Given the same period value, the tone frequency of the wave channel is generally half that of a pulse channel, or one octave lower.
256289

257290
::: warning DELAY
258291

259-
Wavelength changes (written to `NR33` or `NR34`) only take effect after the following time wave RAM is read.
292+
Period changes (written to `NR33` or `NR34`) only take effect after the following time wave RAM is read.
260293
([Source](https://github.com/LIJI32/SameSuite/blob/master/apu/channel_3/channel_3_freq_change_delay.asm))
261294

262295
:::
263296

264-
### FF1E — NR34: Channel 3 wavelength high & control
297+
### FF1E — NR34: Channel 3 period high & control
265298

266299
```
267300
Bit 7 - Trigger (1=Restart Sound) (Write Only)
268301
Bit 6 - Sound Length enable (Read/Write)
269302
(1=Stop output when length in NR31 expires)
270-
Bit 2-0 - "Wavelength"'s higher 3 bits (Write Only)
303+
Bit 2-0 - Period value's higher 3 bits (Write Only)
271304
```
272305

273306
Writing a value here with bit 7 set [triggers](<#Triggering>) the channel.
@@ -308,7 +341,7 @@ Accessing wave RAM while CH3 is **active** (i.e. playing) causes accesses to mis
308341
- On other consoles, the byte accessed will be the one CH3 is currently reading[^wave_access]; that is, if CH3 is currently reading one of the first two samples, the CPU will really access $FF30, regardless of the address being used. ([Source](https://github.com/LIJI32/SameSuite/blob/master/apu/channel_3/channel_3_wave_ram_locked_write.asm))
309342

310343
Wave RAM *can* be accessed normally even if the DAC is on, as long as the channel is not active. ([Source](https://github.com/LIJI32/SameSuite/blob/master/apu/channel_3/channel_3_wave_ram_dac_on_rw.asm))
311-
This is especially relevant on GBA, since ["DACs" are always enabled there](<#Game Boy Advance audio>).
344+
This is especially relevant on GBA, whose [mixer behaves as if DACs are always enabled](<#Game Boy Advance audio>).
312345

313346
[^wave_access]:
314347
The way it works is that wave RAM is a 16-byte memory buffer, and while it's playing, CH3 has priority over the CPU when choosing which of those 16 bytes is accessed.

src/Audio_details.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ Note that the envelope functionality changes the volume, but not the value store
123123
If a DAC is enabled, the digital range $0 to $F is linearly translated to the analog range -1 to 1, in arbitrary units.
124124
Importantly, the slope is negative: "digital 0" maps to "analog 1", not "analog -1".
125125

126-
If a DAC is disabled, it fades to an analog value of 0.
126+
If a DAC is disabled, it fades to an analog value of 0, which corresponds to "digital 7.5".
127127
The nature of this fade is not entirely deterministic and varies between models.
128128

129129
NR52's low 4 bits report whether the channels are turned on, not their DACs.
@@ -141,7 +141,7 @@ A channel can be deactivated in one of the following ways:
141141
### Pulse channels (CH1, CH2)
142142

143143
Each pulse channel has an internal "duty step" counter, which is used to index into [the selected waveform](<#FF11 — NR11: Channel 1 length timer & duty cycle>) (each background stripe corresponds to one "duty step")[^pulse_lut].
144-
The "duty step" increments at 8 times [the channel's frequency](<#FF13 — NR13: Channel 1 wavelength low \[write-only\]>)).
144+
The "duty step" increments at the channel's sample rate, which is 8 times [the channel's frequency](<#FF13 — NR13: Channel 1 period low \[write-only\]>)).
145145

146146
The "duty step" counter cannot be reset, except by turning the APU off, which sets both back to 0.
147147
Retriggering a pulse channel causes its "duty step timer" to reset, thus retriggering a pulse channel often enough will cause its "duty step" to never advance.
@@ -154,7 +154,8 @@ Actually, there is not LUT, but the manipulations done to the counter's bits are
154154
### Wave channel (CH3)
155155

156156
CH3 has an internal "sample index" counter.
157-
Each time it is ticked (as determined by the "wavelength" in NR33/NR34), that "sample index" is incremented, and then the corresponding "sample" (nibble) is read from wave RAM.
157+
The "sample index" increments at the channel's sample rate, which is 32 times [the channel's frequency](<#FF1D — NR33: Channel 3 period low \[write-only\]>
158+
Each time it increments, the corresponding "sample" (nibble) is read from wave RAM.
158159
(This means that sample #0 is skipped when first starting up CH3.)
159160

160161
CH3 does not emit samples directly, but stores every sample read into a buffer, and emits that continuously; (re)triggering the channel does *not* clear nor refresh this buffer, so the last sample ever read will be emitted again.
@@ -169,7 +170,7 @@ This only matters when changing the setting mid-playback: the digital values bei
169170
{{#include imgs/ch4_lfsr.svg:2:}}
170171

171172
CH4 revolves around a [LFSR](https://en.wikipedia.org/wiki/Linear-feedback_shift_register), pictured above.
172-
The LFSR is 16-bit internally, but really acts as if it was 15-bit.
173+
The LFSR has 16 bits: 15 bits for its current state and 1 bit to temporarily store the next bit to shift in.
173174

174175
When CH4 is ticked (at the frequency specified via [`NR43`](<#FF22 — NR43: Channel 4 frequency & randomness>)):
175176
1. The result of <math><menclose notation="top"><msub><mi>LFSR</mi><mn>0</mn></msub> <mo>⊕</mo> <msub><mi>LFSR</mi><mn>1</mn></msub></menclose></math> (`1` if bit 0 and bit 1 are identical, `0` otherwise) is written to bit 15.

0 commit comments

Comments
 (0)