Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Composing > Avoiding the ADSR bug in the decay phase.
2015-04-21 11:49
lft

Registered: Jul 2007
Posts: 369
Avoiding the ADSR bug in the decay phase.

Random insight of the day:

The ADSR bug is well known: When we switch from a slow to a fast envelope rate, the envelope generator sometimes gets stuck for about 33 ms (1.67 PAL frames). This tends to happen when we have a slow release, and then try to trigger a note with a fast attack. The attack gets delayed unpredictably.

Some playroutines provide a hard restart feature to work around this problem.

But here's the insight: The same thing can and does happen when we switch from a slow attack to a fast decay, or from a slow decay to a fast release. So, if we use an ADSR setting of, say, 10 aa, we get a fast attack, and then we switch to an even faster decay. This will actually trigger the bug! The volume level could remain at the maximum for up to 33 ms. Furthermore, if we try to release the note too soon (within 1-2 frames), the release could be delayed unpredictably.

To avoid this, we have to use a decay rate that is greater than or equal to the attack rate.

On the other hand, sometimes this phenomenon is useful. If we want a slow attack and a fast release, and we know that we want to hold the note for more than two frames beyond the attack period, then this is exactly what we want. For instance, if we use f0 f2, we get a slow attack, followed by the ADSR bug (random delay of up to 33 ms). Then, as soon as we release the gate, we get an immediate response, because we already have the bug behind us.

To summarise:

If you want to reach the sustain level in the same amount of time for every note, or if you want to reach it as quickly as possible, ensure that D >= A.

If you want the release to start immediately when you turn off the gate bit, ensure that R >= D.

Advanced technique:

Suppose you want to reach the sustain level as quickly as possible, but you also want the release to start immediately. And you want a slow attack and a fast release.

A > R, R >= D, D >= A, does not compute.

But you can use e.g. 77 84 when you start the note, and then, after the note has reached the sustain phase, switch to an instrument with a 70 84 envelope. Then wait two more frames to get past the bug. Then, the release will be predictable and immediate.
 
... 31 posts hidden. Click here to view all posts....
 
2015-04-30 04:17
ChristopherJam

Registered: Aug 2004
Posts: 1409
Yup, that would be the ADSR bug manifesting.

To the best of my knowledge:
- it's only triggered by register writes
- it can happen any time a register write causes a transition from a slow speed to a faster one
- this happens either by changing the rate of the envelope phase that's currently running (eg changing attack from 4 to 3 during the attack time)
- or by setting or clearing the gate bit at a time there are 'dangerous' ADSR values set.

In your case, you're transitioning from a release of 2 to an attack of 1.

In general, setting gate when R>A, or clearing it when R<D (or <A if you do it during attack) will always risk locking up the envelope for a frame and a half.

There's also a slight risk setting gate when R=A, but only if D is different to them, and a clever music routine could work around this by temporarily setting D to the same as the other two (there's a single cycle bug that most emulators don't cover yet)

The usual work around is to use a hard-restart, that hides the lockup in a couple of frames of silence before the note starts. As LFT suggested above, in some instances it should be possible to hide the lockup in the sustain phase instead, but that would require more control than many players provide you with.
2015-04-30 06:51
Frantic

Registered: Mar 2003
Posts: 1648
By the way.. if someone feels like writing something up about the ADSR bug and ways to deal with it, to put on Codebase64, that would be very nice.
2015-05-05 07:54
ChristopherJam

Registered: Aug 2004
Posts: 1409
Finally had a play with Agemixer's ADSR tool last night; it's pretty neat!

I've just put a post up at SID envelope rate counter phase alignment with some optimisations to the phase wrangling; it's all getting a little off topic for actual composing, as that level of register bashing is more a thing for implementing players etc.

I will add "write a decent artist's guide to the ADSR bug for codebase" to my todo list mind, much as I feel like I'm teaching grandma to suck eggs here; Agemixer is one of the greats!
2015-05-11 11:40
Laurent

Registered: Apr 2004
Posts: 40
Quoting lft
However, we add a twist, which is to perform the hard restart with the gate enabled and ADSR = 00ee. Naturally, we also select waveform 0 to avoid audible artefacts.

I haven't tested this, but I wonder if we would hear something on the 6581 due to the DC offset that gets scaled by the envelope DAC ?
2015-05-11 12:49
Mixer

Registered: Apr 2008
Posts: 452
If the osc level at the moment of WF=0 selection is not 0, there will be a DC offset component that moves according to the env changes. This has been used to play "ADSR" samples.

But normally ENV changes so slowly that the sound is quite unhearable. Sharp fast changes frequently could be heard.
2015-07-01 22:14
Danko

Registered: Nov 2002
Posts: 19
The nifty thing with implementing a hard restart function is that you don't have much to do over, say, three frames.

So why not divide up the code and execute it over three frames instead of one, fill up a buffer and then copy buffer to D400-> at the end.

We all know this, so just a slight reminder what a "traditional" hard restart as implemented by JCH can do in order to help decreasing raster time.


The other thing, but more fuzzy as it where...

The envelopes in the SID are derived from four preset curves and all intermediate steps are merely interpolated. Having 0-F for each envelope step is merely an illusion. The big breaking point happens when D goes from 8 to 9, check it out.

You can play with that. One method is to stay below D of 9 and make very snappy nice sounds, the downside is that the song will have less loudness compared to other songs. One example of this is my cover of Erasure's Breath of Life that I made for a Fairlight demo once.
2016-02-16 20:21
lft

Registered: Jul 2007
Posts: 369
Quoting ChristopherJam
When you first set the gate bit to trigger a new note, there's a single cycle where SID is using the rate from 'decay' rather than attack - so for example if you have both attack and release set to zero, but decay set to something slower, there's a one in nine chance of triggering the bug at the very start of the note. This can be avoided by setting decay to the same value as attack until just after you set the gate bit.


Gaah, this bit me today. Song plays flawlessly in vice, but with ADSR bugs on real hardware.

And I blew up the worst case of my playroutine by 33 cycles just to get a quick fix in place. The fix is to write AD & $f0 before setting the gate bit, and then write the proper AD afterwards.
2016-02-17 10:55
ChristopherJam

Registered: Aug 2004
Posts: 1409
Quoting lft

Gaah, this bit me today. Song plays flawlessly in vice, but with ADSR bugs on real hardware....


Damn! But hurrah for catching, diagnosing, and finding a fix.

Quote:

The fix is to write AD & $f0 before setting the gate bit, and then write the proper AD afterwards.


That works unless A=R and both are >0. If A and R are both 1 then that solution will bug one time in 32 (or 1 time in 63 for A=R=2, etc). Safest just to set D equal to A (or R).
2016-02-17 11:56
chatGPZ

Registered: Dec 2001
Posts: 11386
what happened to that LFSR patch? :)
2016-02-17 13:12
ChristopherJam

Registered: Aug 2004
Posts: 1409
Perfectionism!

Still haven't managed to get it cycle exact, then got distracted by REU, video emulation, Hi5 mode, NuCrunch, Marmaload..
Previous - 1 | 2 | 3 | 4 | 5 - Next
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
Steffan/BOOM!
Unlock/Padua/Albion
St0rmfr0nt/Quantum
Paulko64
BANDIT/BANDIT-COOL-S..
Freeze/Blazon
Jericho/Draco/Tropyx..
Krill/Plush
REBEL 1/HF
Alakran_64
Brataccas/HF
algorithm
Holy Moses/Role
Guests online: 98
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Mojo  (9.7)
4 Coma Light 13  (9.6)
5 Edge of Disgrace  (9.6)
6 What Is The Matrix 2  (9.6)
7 The Demo Coder  (9.6)
8 Uncensored  (9.6)
9 Comaland 100%  (9.6)
10 Wonderland XIV  (9.6)
Top onefile Demos
1 Layers  (9.6)
2 No Listen  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Dawnfall V1.1  (9.5)
7 Rainbow Connection  (9.5)
8 Onscreen 5k  (9.5)
9 Morph  (9.5)
10 Libertongo  (9.5)
Top Groups
1 Performers  (9.3)
2 Booze Design  (9.3)
3 Oxyron  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Fullscreen Graphicians
1 Joe  (9.7)
2 Sulevi  (9.6)
3 The Sarge  (9.6)
4 Veto  (9.6)
5 Facet  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.046 sec.