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 Coding > Neat way to implement single/double hard-restart
2016-03-17 06:29
lft

Registered: Jul 2007
Posts: 369
Neat way to implement single/double hard-restart

In SID envelope rate counter phase alignment, Laurent6581 off-topicly wrote:

Quoting Laurent6581
I have seen many players that seemed to voluntarily triggered a second delay bug before attack restart.


Thanks a lot for this! I was unaware of the technique, but it is very useful. Here's how I implemented it in my current playroutine:

Two frames before a hard-restart instrument is about to be triggered, clear SR and Gate. On the target frame---again, only for hard-restart instruments---first write 0f to SR. The counter escapes from the 9-cycle bottle. Now do other stuff (including setting up AD), counting the CPU cycles. When the envelope counter is known to be in the range 33..61, set Gate. Finally write the correct SR.

In this way, hard-restart instruments with attack rate 0 or 1 will have the extra 30 ms delay, for snappy percussion sounds. Attack rate 2 or higher will behave normally. And the bug where the decay rate is used for one cycle is circumvented automatically.

The total attack rate becomes:

Rate   Normal   Extra   Total
0        2 ms   30 ms   32 ms
1        8 ms   30 ms   38 ms
2       16 ms           16 ms
3       24 ms           24 ms
4       38 ms           38 ms
...


So, for instance, instruments with attack rate 4 will line up with (hard-restart) instruments having attack rate 1.

Since the extra "delay" is just the envelope being stuck at zero, the first frame of wavetable/filtertable has to contain a dummy value. A corresponding delay of one frame could be programmed into the playroutine, or the dummy value could be hidden in the tracker UI.
 
... 10 posts hidden. Click here to view all posts....
 
2016-03-18 15:46
ChristopherJam

Registered: Aug 2004
Posts: 1409
Quoting Agemixer
Does this all assume that sustain value should be dropped completely down to $00 before restart? Or by (level-1)..0?

Level (amplitude), not sustain.

Quote:
What if i wanted to leave at previous sustain level (read: reverb) until just the next tone Attack cycle starts?
..Without any delay, how would you deal with that?

Force a bug at start of second last frame of previous note, clear gate, and set S=R=0. This way the sustain continues until halfway through the last frame (as the envelope is frozen), then the level drops to zero in at most 6ms, leaving less than 10ms silence before the start of the next note.

Quote:
why not simulate the release with lowering Sustain level instead.

Internally, that's what I'll probably do, whenever there's a rest between that note and the next. But that's just an implementation detail; the editor should show a standard ADSR waveform.

Quote:
But how would you do a HR then, let's say when the remaining amplitude would be anything between $00..$ff? (And i don't mean the $d406 sustain setting)

See above - freeze env for 30ms, at the end of which it'll take at most 6ms to drop down from any amplitude. (edited now I read the question properly)
2016-03-18 20:24
lft

Registered: Jul 2007
Posts: 369
Quoting ChristopherJam
Force a bug at start of second last frame of previous note, clear gate, and set S=R=0. This way the sustain continues until halfway through the last frame (as the envelope is frozen), then the level drops to zero in at most 6ms, leaving less than 10ms silence before the start of the next note.


How would you force the bug at that precise moment unless you know the value of the counter? For long notes, you could rely on a hard-restart hidden in the sustain phase, but again, what if the new note is interrupting an ongoing attack or decay?
2016-03-18 20:33
lft

Registered: Jul 2007
Posts: 369
Quoting lft
Quoting cadaver
Requiring a semi-precise window of timing practically means you'll have to run the player in the border, otherwise the variable time of execution on other channels may lead the time-critical execution of e.g. the last channel to happen during a badline.


Correct!

For what it's worth, I believe that sprite DMA is safe. Nine cycles of phase uncertainty plus 0..19 stolen cycles, that's a jitter of 9 + 20 - 1 = 28 cycles, and we need to be within a 31-cycle range. So ghost sprites in the border shouldn't be a problem as long as the playroutine is tightly coded.


Some further thoughts: The worst that could happen is eight sprites, badline, eight sprites. That's going to push the counter beyond 63, but it's still well below 149. For the musician, this means that hard-restart instruments with attack rate 2 or 3 are unsafe (i.e. the note start could randomly be delayed by 30 ms) if the playroutine executes in the normal display area. Any other attack rate is going to behave properly. Rates 0 and 1 will always have the extra delay, and rates 4 and above will never have it. So this technique would still be usable in e.g. CIA-tempo tunes if you just avoid those two attack rates.
2016-03-18 22:13
ChristopherJam

Registered: Aug 2004
Posts: 1409
Quote: Quoting ChristopherJam
Force a bug at start of second last frame of previous note, clear gate, and set S=R=0. This way the sustain continues until halfway through the last frame (as the envelope is frozen), then the level drops to zero in at most 6ms, leaving less than 10ms silence before the start of the next note.


How would you force the bug at that precise moment unless you know the value of the counter? For long notes, you could rely on a hard-restart hidden in the sustain phase, but again, what if the new note is interrupting an ongoing attack or decay?


Editor should know what the rate limit is at that point, from the duration of the note. If the rate limit index is less than $f,then increase to $f for at least nine cycles, then drop rate limit index to $0

If rate limit index is equal to $f then it's a bit messier; easy way out would be to lower that for any notes short enough to be interrupted..

Of course, if it's a fairly fast attack or decay, then freezing the envelope level for 30ms might not be appropriate..
2016-03-19 20:24
lft

Registered: Jul 2007
Posts: 369
Quoting ChristopherJam
Editor should know what the rate limit is at that point, from the duration of the note. If the rate limit index is less than $f,then increase to $f for at least nine cycles, then drop rate limit index to $0


Suppose that rate $d is in use, perhaps during a note release. When it is time for hard-restart, the player switches to $f, then to $0. This will indeed trigger a wraparound. If the counter happened to be at a low value, you'll get the 30 ms delay, and "less than 10ms silence before the start of the next note". But if the counter was at 10000, you'll only get a 20 ms delay, and thus 20 ms of silence.
2016-03-20 03:55
ChristopherJam

Registered: Aug 2004
Posts: 1409
Quote: Quoting ChristopherJam
Editor should know what the rate limit is at that point, from the duration of the note. If the rate limit index is less than $f,then increase to $f for at least nine cycles, then drop rate limit index to $0


Suppose that rate $d is in use, perhaps during a note release. When it is time for hard-restart, the player switches to $f, then to $0. This will indeed trigger a wraparound. If the counter happened to be at a low value, you'll get the 30 ms delay, and "less than 10ms silence before the start of the next note". But if the counter was at 10000, you'll only get a 20 ms delay, and thus 20 ms of silence.


Good point. I guess anything from $d to $f would need dropping down to $c a frame or two in advance; if the decay is that slow then halting the fall for a few frames should be inaudible.
2016-03-20 03:57
ChristopherJam

Registered: Aug 2004
Posts: 1409
Jammer, those claps are excellent! I'm going to have to take a closer look at your register bashing..
2016-08-07 21:18
lft

Registered: Jul 2007
Posts: 369
Quoting lft
Quoting lft
Quoting cadaver
Requiring a semi-precise window of timing practically means you'll have to run the player in the border, otherwise the variable time of execution on other channels may lead the time-critical execution of e.g. the last channel to happen during a badline.


Correct!

For what it's worth, I believe that sprite DMA is safe. Nine cycles of phase uncertainty plus 0..19 stolen cycles, that's a jitter of 9 + 20 - 1 = 28 cycles, and we need to be within a 31-cycle range. So ghost sprites in the border shouldn't be a problem as long as the playroutine is tightly coded.


Some further thoughts: The worst that could happen is eight sprites, badline, eight sprites. That's going to push the counter beyond 63, but it's still well below 149. For the musician, this means that hard-restart instruments with attack rate 2 or 3 are unsafe (i.e. the note start could randomly be delayed by 30 ms) if the playroutine executes in the normal display area. Any other attack rate is going to behave properly. Rates 0 and 1 will always have the extra delay, and rates 4 and above will never have it. So this technique would still be usable in e.g. CIA-tempo tunes if you just avoid those two attack rates.


Based on a true story: If you use this technique, and you have sprite DMA interfering with the playroutine, then you should avoid decay rate 2 in double-hard-restart instruments (e.g. with attack 0 or 1).

Normally, my routine above will nicely avoid the bug where the decay rate is used for the first cycle of attack. However, at least in my current playroutine, if eight sprites are active and the envelope counter is at 8 when the bottle is opened, the counter will be at 62 just when the gate bit is set. Then the counter will wrap around to zero, preventing the second hard-restart and messing up the note attack. This only happens on real hardware, and it goes away if I change the decay rate to 1.
Previous - 1 | 2 - 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
blitzed
Guests online: 80
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Coma Light 13  (9.6)
4 Edge of Disgrace  (9.6)
5 Mojo  (9.6)
6 Uncensored  (9.6)
7 The Demo Coder  (9.6)
8 Comaland 100%  (9.6)
9 What Is The Matrix 2  (9.6)
10 Wonderland XIV  (9.5)
Top onefile Demos
1 Layers  (9.7)
2 Cubic Dream  (9.6)
3 Party Elk 2  (9.6)
4 Copper Booze  (9.6)
5 Dawnfall V1.1  (9.5)
6 Rainbow Connection  (9.5)
7 Morph  (9.5)
8 Libertongo  (9.5)
9 Onscreen 5k  (9.5)
10 It's More Fun to Com..  (9.5)
Top Groups
1 Booze Design  (9.3)
2 Oxyron  (9.3)
3 Performers  (9.3)
4 Triad  (9.3)
5 Censor Design  (9.3)
Top Musicians
1 Mutetus  (9.7)
2 Jeroen Tel  (9.6)
3 Rob Hubbard  (9.6)
4 Linus  (9.6)
5 Jammer  (9.6)

Home - Disclaimer
Copyright © No Name 2001-2025
Page generated in: 0.069 sec.