APU Envelope: Difference between revisions
(Clarify when the envelope counter decrement occurs) |
Rainwarrior (talk | contribs) (Volume values aren't exactly linear (adding reference link) but I agree it's worth saying since a lot of PSGs are logarithmic.) |
||
(5 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:APU]] | [[Category:APU]] | ||
In a synthesizer, an [[wikipedia:ADSR_envelope|envelope]] is the way a sound's parameter changes over time. | In a synthesizer, an [[wikipedia:ADSR_envelope|envelope]] is the way a sound's parameter changes over time. | ||
The NES [[APU]] has an envelope generator that controls the volume in one of two ways: it can generate a decreasing saw envelope (like a decay phase of an [http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope ADSR]) with optional looping, or it can generate a constant volume that a more sophisticated software envelope generator can manipulate. | The NES [[APU]] has an envelope generator that controls the volume in one of two ways: it can generate a decreasing saw envelope (like a decay phase of an [http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope ADSR]) with optional looping, or it can generate a constant volume that a more sophisticated software envelope generator can manipulate. Volume values are practically linear (see: [[APU Mixer]]). | ||
Each volume envelope unit contains the following: start flag, [[APU Misc|divider]], and counter. | Each volume envelope unit contains the following: start flag, [[APU Misc|divider]], and decay level counter. | ||
<pre> | |||
{| | Loop flag | ||
| | |||
Start flag +--------. | Constant volume | |||
| | | flag | |||
v v v | | |||
Quarter frame clock --> Divider --> Decay --> | | | |||
^ level | v | |||
| | Select --> Envelope output | |||
| | | |||
Envelope parameter +----------------> | | |||
</pre> | |||
{| class="wikitable" | |||
! Address || Bitfield || Description | |||
|- | |||
| '''$4000''' || <tt>ddLC.VVVV</tt> || '''[[APU Pulse|Pulse channel 1]]''' duty and volume/envelope (write) | | '''$4000''' || <tt>ddLC.VVVV</tt> || '''[[APU Pulse|Pulse channel 1]]''' duty and volume/envelope (write) | ||
|- | |- | ||
Line 16: | Line 29: | ||
| bit 4 || <tt>---C ----</tt> || Constant volume flag (0: use volume from envelope; 1: use constant volume) | | bit 4 || <tt>---C ----</tt> || Constant volume flag (0: use volume from envelope; 1: use constant volume) | ||
|- | |- | ||
| bits 3-0 || <tt>---- VVVV</tt> || Used as the volume in constant volume (C set) mode. Also used as the reload value for the envelope's divider (the period becomes V + 1). | | bits 3-0 || <tt>---- VVVV</tt> || Used as the volume in constant volume (C set) mode. Also used as the reload value for the envelope's divider (the period becomes V + 1 quarter frames). | ||
|- | |- | ||
|colspan=3| | |colspan=3| | ||
Line 29: | Line 42: | ||
|} | |} | ||
When clocked by the [[APU Frame Counter|frame counter]], one of two actions occurs: if the start flag is clear, the divider is clocked, otherwise the start flag is cleared, the counter is loaded with 15, and the divider's period is immediately reloaded. | When clocked by the [[APU Frame Counter|frame counter]], one of two actions occurs: if the start flag is clear, the divider is clocked, otherwise the start flag is cleared, the decay level counter is loaded with 15, and the divider's period is immediately reloaded. | ||
When the divider is clocked while at 0, it is loaded with V and clocks the decay level counter. Then one of two actions occurs: If the counter is non-zero, it is decremented, otherwise if the loop flag is set, the decay level counter is loaded with 15. | |||
The envelope unit's volume output depends on the constant volume flag: if set, the envelope parameter directly sets the volume, otherwise the decay level is the current volume. The constant volume flag has no effect besides selecting the volume source; the decay level will still be updated when constant volume is selected. | |||
Each of the three envelope units' output is fed through additional gates at the [[APU Sweep|sweep unit]] (pulse only), waveform generator ([[APU#Glossary|sequencer]] or LFSR), and [[APU Length Counter|length counter]]. |
Latest revision as of 19:04, 23 September 2020
In a synthesizer, an envelope is the way a sound's parameter changes over time. The NES APU has an envelope generator that controls the volume in one of two ways: it can generate a decreasing saw envelope (like a decay phase of an ADSR) with optional looping, or it can generate a constant volume that a more sophisticated software envelope generator can manipulate. Volume values are practically linear (see: APU Mixer).
Each volume envelope unit contains the following: start flag, divider, and decay level counter.
Loop flag | Start flag +--------. | Constant volume | | | flag v v v | Quarter frame clock --> Divider --> Decay --> | | ^ level | v | | Select --> Envelope output | | Envelope parameter +----------------> |
Address | Bitfield | Description |
---|---|---|
$4000 | ddLC.VVVV | Pulse channel 1 duty and volume/envelope (write) |
$4004 | ddLC.VVVV | Pulse channel 2 duty and volume/envelope (write) |
$400C | --LC.VVVV | Noise channel volume/envelope (write) |
bit 5 | --L- ---- | APU Length Counter halt flag/envelope loop flag |
bit 4 | ---C ---- | Constant volume flag (0: use volume from envelope; 1: use constant volume) |
bits 3-0 | ---- VVVV | Used as the volume in constant volume (C set) mode. Also used as the reload value for the envelope's divider (the period becomes V + 1 quarter frames). |
$4003 | LLLL.Lttt | Pulse channel 1 length counter load and timer (write) |
$4007 | LLLL.Lttt | Pulse channel 2 length counter load and timer (write) |
$400F | LLLL.L--- | Noise channel length counter load (write) |
Side effects | Sets start flag |
When clocked by the frame counter, one of two actions occurs: if the start flag is clear, the divider is clocked, otherwise the start flag is cleared, the decay level counter is loaded with 15, and the divider's period is immediately reloaded.
When the divider is clocked while at 0, it is loaded with V and clocks the decay level counter. Then one of two actions occurs: If the counter is non-zero, it is decremented, otherwise if the loop flag is set, the decay level counter is loaded with 15.
The envelope unit's volume output depends on the constant volume flag: if set, the envelope parameter directly sets the volume, otherwise the decay level is the current volume. The constant volume flag has no effect besides selecting the volume source; the decay level will still be updated when constant volume is selected.
Each of the three envelope units' output is fed through additional gates at the sweep unit (pulse only), waveform generator (sequencer or LFSR), and length counter.