-
-
Notifications
You must be signed in to change notification settings - Fork 110
Overhaul audio section #350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Audio Overview | ||
|
||
Game Boy audio is sometimes called "8-bit". | ||
This does not refer to the bit depth of the sound generated, but rather that it has sound capabilities typical of 8-bit consoles. | ||
Like much of its contemporary hardware, the Game Boy produces sound generated by simple digital circuits. | ||
|
||
## Architecture | ||
|
||
{{#include imgs/apu_overview.svg:2:}} | ||
|
||
The Game Boy has four sound generation units, called **channels** 1 through 4, notated "CH1", "CH2", etc. | ||
Unlike some other sound chips, such as the C64's SID or the Atari 5200's POKEY, each sound channel is specialized in a way largely different from the other channels. | ||
|
||
Each channel generates an electronic signal; these signals are then mixed into two new channels (for stereo: one for the left ear, one for the right ear), which are then individually amplified, and then output either to the headphone jack, or the speaker[^speaker_mono]. | ||
|
||
Channels 1 and 2, the "pulse channels", produce [pulse width modulated waves](https://en.wikipedia.org/wiki/Pulse-width_modulation) with 4 fixed pulse width settings. | ||
Channel 3, the "wave" channel, produces arbitrary user-supplied waves. | ||
Channel 4 is the "[noise](https://en.wikipedia.org/wiki/Noise_in_music)" channel, producing a pseudo-random wave. | ||
|
||
The VIN channel is an analog signal received directly from the cartridge, allowing external hardware to supply a fifth sound channel. | ||
No licensed games used this feature, and it was omitted from the Game Boy Advance. | ||
|
||
::: tip POCKET MUSIC | ||
|
||
Despite some online claims, *Pocket Music* does not use VIN. | ||
It refuses to run on the GBA for a different reason: the developer couldn't figure out how to silence buzzing associated with sample playback on the wave channel. | ||
|
||
::: | ||
|
||
[^speaker_mono]: | ||
The speaker merges back the two channels, losing the stereo aspect entirely. | ||
|
||
## Common concepts | ||
|
||
### APU | ||
|
||
The Game Boy's sound chip is called the <abbr title="Audio Processing Unit">APU</abbr>. | ||
|
||
The APU runs off the same master clock as the rest of the Game Boy, which is to say, it is fully synced with the CPU and [PPU](<#Rendering Overview>). | ||
This also means that the APU runs about 2.4% faster on the SGB1, increasing frequencies by as much and thus sounding slightly higher-pitched. | ||
The SGB2 rectifies this issue. | ||
|
||
All interfaces to the APU use **durations** instead of frequencies, which may be confusing as signal theory and music are more typically based on the latter. | ||
Thus, durations will be expressed from their frequencies: for example, a "256 Hz tick" means "1 ∕ 256th of a second". | ||
ISSOtm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The length of APU ticks is not affected by [CGB double speed](<#FF4D — KEY1 (CGB Mode only): Prepare speed switch>), so the APU works just the same regardless of CPU speed. | ||
|
||
::: warning | ||
|
||
The Game Boy's APU is actually full of tricky details; this chapter will mostly describe the intended / common behavior, and often paper over bugs & quirks. | ||
Readers wishing to learn more should read the [APU details](<#Audio Details>) chapter. | ||
|
||
::: | ||
|
||
### Triggering | ||
|
||
**Triggering** a channel causes it to turn on if it wasn't[^trig_dac_off], and to start playing its wave from the beginning[^pulse_restart]. | ||
Most changes to a channel's parameters take effect immediately, but some require re-triggering the channel. | ||
|
||
### Volume & envelope | ||
|
||
The volume can be controlled in two ways: there is a "master volume" control[^vol_knob] (which has separate settings for the left and right outputs), and each channel's volume can be individually set as well (CH3's less precisely than the others). | ||
|
||
Additionally, an [**envelope**](https://en.wikipedia.org/wiki/Envelope_(music)) can be configured for CH1, CH2 and CH4, which allows automatically adjusting the volume over time. | ||
The parameters that can be controlled are the initial volume, the envelope's direction (but not its slope), and its duration. | ||
Internally, all envelopes are ticked at 64 Hz, and every 1–7 of those ticks, the volume will be increased or decreased. | ||
|
||
### Length timer | ||
|
||
All channels can be individually set to automatically shut themselves down after a certain amount of time. | ||
|
||
If the functionality is enabled, a channel's **length timer** ticks up[^len_cnt_dir] at 256 Hz (tied to [DIV-APU](<#DIV-APU>)) from the value it's initially set at. | ||
When the length timer reaches 64, the channel is turned off. | ||
|
||
### Frequency | ||
|
||
Music notes and audio waves are typically manipulated in terms of **frequency**[^pitch], i.e. how often the signal repeats per second. | ||
However, as explained above, the Game Boy APU primarily works with durations; thus, **wavelengths** will be used instead of frequency.[^len_raw] | ||
|
||
::: warning | ||
|
||
The term "wavelength" throughout this document does *not* designate the inverse of the frequency, but instead a quantity akin to it. | ||
See the description of each NRx3 register for more information. | ||
|
||
::: | ||
|
||
--- | ||
|
||
[^trig_dac_off]: | ||
If [the channel's DAC](#DACs) is off, the channel will not turn on. | ||
avivace marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
[^pulse_restart]: | ||
Except for pulse channels, whose phase position is only ever reset by turning the APU off. | ||
This is usually not noticeable unless changing the duty cycle mid-note. | ||
|
||
[^vol_knob]: | ||
This is separate from the physical volume knob located on the side of the console. | ||
|
||
[^len_cnt_dir]: | ||
Internally, the length timer is inverted when written, and *that* ticks down until it reaches 0. | ||
But the effect is as if the counter ticked up. | ||
|
||
[^pitch]: | ||
There is also **pitch**, which is merely a measure of how we perceive frequency. | ||
The higher the frequency, the higher the pitch; therefore, pitch will be omitted from the rest of the document. | ||
avivace marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
[^len_raw]: | ||
Actually, the APU interfaces don't work with any wavelengths either, but with values that are more akin to wavelengths than frequencies. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.