DSP envelopes: Difference between revisions

From SNESdev Wiki
Jump to navigationJump to search
(→‎Period Table: note about values being larger than their period)
(→‎ADSR Envelope: Add ADSR envelope diagram)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
The envelope value ('''ENVX''') of each [[S-SMP]] DSP voice is driven by either an ADSR envelope, or a gain control. This gives an additional way to automatically shape the volume of the voice over time, aside from its '''VOL''' registers.
The envelope value of each [[S-DSP]] voice is driven by either an ADSR envelope, or a gain control. This gives an additional way to automatically shape the volume of the voice over time, aside from its '''VOL''' registers.
 
The ADSR describes a 4 stage envelope:
* '''Attack''' begins at key-on, rising from 0 to full over a chosen amount of time.
* '''Decay''' lowers from full to a chosen sustain level.
* '''Sustain''' is the volume level reached after the decay concludes.
* '''Release''' begins at key-off, lowering to 0 with an exponential decay.


Internally the envelope is an 11-bit value multiplied by by the voice output. The '''ENVX''' value that can be read from the DSP contains only the high 7 bits.
Internally the envelope is an 11-bit value multiplied by by the voice output. The '''ENVX''' value that can be read from the DSP contains only the high 7 bits.
Line 13: Line 7:
* [[S-SMP#GAIN|GAIN]]
* [[S-SMP#GAIN|GAIN]]


== ADSR Envelope Timings ==
== ADSR Envelope ==
 
The ADSR describes a 4 stage envelope:
* '''Attack''' begins at key-on, rising from 0 to full over a chosen amount of time.
* '''Decay''' lowers from full to a chosen Sustain Level.
* '''Sustain''' exponential decay from Sustain Level to 0 (if the Sustain Rate is non-zero).
* '''Release''' begins at key-off, lowering to 0 with an fixed decay.
 
[[File:Adsr_envelope.svg]]
 


See: [[S-SMP#ADSR|S-SMP ADSR]]
See: [[S-SMP#ADSR|S-SMP ADSR]]
Line 30: Line 33:
! ADSR (2)
! ADSR (2)
! $X6
! $X6
| style="text-align: right" | <tt style="white-space: nowrap">SSSR RRRR</tt>
| style="text-align: right" | <tt style="white-space: nowrap">LLLR RRRR</tt>
| Sustain level (S), release rate (R).
| Sustain level (SL), sustain rate (SR).
|}
|}


At a rate according to the [[#Period Table|period table]] the following action is performed, and the envelope is clamped to 0-2047 ($7FF):
At a rate according to the [[#Period Table|period table]] the following action is performed, and the envelope is clamped to 0-2047 ($7FF):
* Attack at period[A*2+1]: adds 32, or if A=$F adds 1024 ($400).
* Attack at period[A*2+1]: adds 32, or if A=$F adds 1024 ($400).
* Decay at period[D*2+16]: <tt>envelope -= 1</tt>, then <tt>envelope -= envelope >> 8</tt>.
* Decay at period[D*2+16]: <tt>envelope -= 1</tt>, then <tt>envelope -= envelope >> 8</tt>.
* Release at period[R]: <tt>envelope -= 1</tt>, then <tt>envelope -= envelope >> 8</tt>.
* Sustain at period[SR]: <tt>envelope -= 1</tt>, then <tt>envelope -= envelope >> 8</tt>.
* Release: <tt>envelope -= 8</tt> every sample.


This table of timings gives the resulting time taken by the above operations:
This table of timings gives the resulting time taken by the above operations:
* Attack is the time from 0 to full.
* Attack is the time from 0 to full.
* Decay is the time from full to sustain level.
* Decay is the time from full to sustain level.
* Release is the time from full to 0.
* Sustain is the time from full to 0.


{|
{|
Line 112: Line 117:


{| class="wikitable"
{| class="wikitable"
! colspan=4 | ADSR Release
! colspan=4 | ADSR Sustain
|-
|-
! R !! Time (ms) !! R !! Time (ms)
! R !! Time (ms) !! R !! Time (ms)
Line 475: Line 480:
The rate of DSP envelope events are controlled by a common table of 32 periods. Each entry is how many S-SMP clocks elapse per envelope operation. The table is arranged in groups of 3.
The rate of DSP envelope events are controlled by a common table of 32 periods. Each entry is how many S-SMP clocks elapse per envelope operation. The table is arranged in groups of 3.


Additionally, each column of periods appears to have a delay offset applied to it, affecting when the operation occurs. If <tt>counter</tt> is the number of S-SMP clocks elapsed, the envelope operation is applied when the following is true:
Additionally, each column of periods appears to have a delay offset applied to it, affecting when the operation occurs. If <tt>counter</tt> is counting down the number of S-SMP clocks elapsed since reset, the envelope operation is applied when the following is true:
* <tt>0 == (counter + offset[rate]) % period[rate]</tt>
* <tt>0 == (counter + offset[rate]) % period[rate]</tt>
The counter begins at 0 after reset, and decrements on each S-SMP clock, wrapping to $77FF (30,720) when it would go below 0<ref>[https://www.romhacking.net/documents/191/ apudsp_jwdonal.txt] - Anomie's S-DSP document.</ref>. (The first clock after reset will wrap.)


{|
{|
Line 563: Line 570:
|}
|}


Note that most of the offsets given above are effectively much smaller, given that they are modulo (%) with their associated period, but this equivalent larger value demonstrates the symmetry between columns.
Note that most of the offsets given above are effectively much smaller, given that they are modulo (%) with their associated period, but the modulo-equivalent larger values shown here demonstrate the symmetry between columns.
 
== References ==
<References/>


[[Category:Sound]]
[[Category:Sound]]

Latest revision as of 12:21, 10 May 2024

The envelope value of each S-DSP voice is driven by either an ADSR envelope, or a gain control. This gives an additional way to automatically shape the volume of the voice over time, aside from its VOL registers.

Internally the envelope is an 11-bit value multiplied by by the voice output. The ENVX value that can be read from the DSP contains only the high 7 bits.

See:

ADSR Envelope

The ADSR describes a 4 stage envelope:

  • Attack begins at key-on, rising from 0 to full over a chosen amount of time.
  • Decay lowers from full to a chosen Sustain Level.
  • Sustain exponential decay from Sustain Level to 0 (if the Sustain Rate is non-zero).
  • Release begins at key-off, lowering to 0 with an fixed decay.

Adsr envelope.svg


See: S-SMP ADSR

Name Address Bits Notes
ADSR (1) $X5 EDDD AAAA ADSR enable (E), decay rate (D), attack rate (A).
ADSR (2) $X6 LLLR RRRR Sustain level (SL), sustain rate (SR).


At a rate according to the period table the following action is performed, and the envelope is clamped to 0-2047 ($7FF):

  • Attack at period[A*2+1]: adds 32, or if A=$F adds 1024 ($400).
  • Decay at period[D*2+16]: envelope -= 1, then envelope -= envelope >> 8.
  • Sustain at period[SR]: envelope -= 1, then envelope -= envelope >> 8.
  • Release: envelope -= 8 every sample.

This table of timings gives the resulting time taken by the above operations:

  • Attack is the time from 0 to full.
  • Decay is the time from full to sustain level.
  • Sustain is the time from full to 0.
ADSR Attack
A Time (ms)
$0 4100
$1 2600
$2 1500
$3 1000
$4 640
$5 380
$6 260
$7 160
$8 96
$9 64
$A 40
$B 24
$C 16
$D 10
$E 6
$F 0
ADSR Decay
D Time (ms)
0 1200
1 740
2 440
3 290
4 180
5 110
6 74
7 37
ADSR Sustain
R Time (ms) R Time (ms)
$00 Infinite $10 1200
$01 38000 $11 880
$02 28000 $12 740
$03 24000 $13 590
$04 19000 $14 440
$05 14000 $15 370
$06 12000 $16 290
$07 9400 $17 220
$08 7100 $18 180
$09 5900 $19 150
$0A 4700 $1A 110
$0B 3500 $1B 92
$0C 2900 $1C 74
$0D 2400 $1D 55
$0E 1800 $1E 37
$0F 1500 $1F 18

Gain Timings

See: S-SMP GAIN

Name Address Bits Notes
GAIN $X7 0VVV VVVV
1MMV VVVV
Mode (M), value (V).

At a rate according to the period table the following action is performed, and the envelope is clamped to 0-2047 ($7FF):

  • Linear gain adds or subtracts 32.
  • Bent gain adds 32 if below 1536 ($600), or 8 if above.
  • Exponential is two steps: envelope -= 1, then: envelope -= envelope >> 8.

This table gives times taken between 0 volume and full volume (or the reverse):

GAIN
Decrease Linear Decrease Exponential Increase Linear Increase Bent
V Time (ms) V Time (ms) V Time (ms) V Time (ms)
$80 Infinite $A0 Infinite $C0 Infinite $E0 Infinite
$81 4100 $A1 38000 $C1 4100 $E1 7200
$82 3100 $A2 28000 $C2 3100 $E2 5400
$83 2600 $A3 24000 $C3 2600 $E3 4600
$84 2000 $A4 19000 $C4 2000 $E4 3500
$85 1500 $A5 14000 $C5 1500 $E5 2600
$86 1300 $A6 12000 $C6 1300 $E6 2300
$87 1000 $A7 9400 $C7 1000 $E7 1800
$88 770 $A8 7100 $C8 770 $E8 1300
$89 640 $A9 5900 $C9 640 $E9 1100
$8A 510 $AA 4700 $CA 510 $EA 900
$8B 380 $AB 3500 $CB 380 $EB 670
$8C 320 $AC 2900 $CC 320 $EC 560
$8D 260 $AD 2400 $CD 260 $ED 450
$8E 190 $AE 1800 $CE 190 $EE 340
$8F 160 $AF 1500 $CF 160 $EF 280
$90 130 $B0 1200 $D0 130 $F0 220
$91 96 $B1 880 $D1 96 $F1 170
$92 80 $B2 740 $D2 80 $F2 140
$93 64 $B3 590 $D3 64 $F3 110
$94 48 $B4 440 $D4 48 $F4 84
$95 40 $B5 370 $D5 40 $F5 70
$96 32 $B6 290 $D6 32 $F6 56
$97 24 $B7 220 $D7 24 $F7 42
$98 20 $B8 180 $D8 20 $F8 35
$99 16 $B9 150 $D9 16 $F9 28
$9A 12 $BA 110 $DA 12 $FA 21
$9B 10 $BB 92 $DB 10 $FB 18
$9C 8 $BC 74 $DC 8 $FC 14
$9D 6 $DD 55 $BD 6 $FD 11
$9E 4 $BE 37 $DE 4 $FE 7
$9F 2 $BF 18 $DF 2 $FF 3.5

Period Table

The rate of DSP envelope events are controlled by a common table of 32 periods. Each entry is how many S-SMP clocks elapse per envelope operation. The table is arranged in groups of 3.

Additionally, each column of periods appears to have a delay offset applied to it, affecting when the operation occurs. If counter is counting down the number of S-SMP clocks elapsed since reset, the envelope operation is applied when the following is true:

  • 0 == (counter + offset[rate]) % period[rate]

The counter begins at 0 after reset, and decrements on each S-SMP clock, wrapping to $77FF (30,720) when it would go below 0[1]. (The first clock after reset will wrap.)

DSP Period Table
/ +0 +1 +2
0 Infinite 2048 1536
3 1280 1024 768
6 640 512 384
9 320 256 192
12 160 128 96
15 80 64 48
18 40 32 24
21 20 16 12
24 10 8 6
27 5 4 3
30 2 1 -
DSP Period Offset
/ +0 +1 +2
0 Never 0 1040
3 536 0 1040
6 536 0 1040
9 536 0 1040
12 536 0 1040
15 536 0 1040
18 536 0 1040
21 536 0 1040
24 536 0 1040
27 536 0 1040
30 536 0 -

Note that most of the offsets given above are effectively much smaller, given that they are modulo (%) with their associated period, but the modulo-equivalent larger values shown here demonstrate the symmetry between columns.

References

  1. apudsp_jwdonal.txt - Anomie's S-DSP document.