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.
2016-03-17 09:39
ChristopherJam

Registered: Aug 2004
Posts: 1378
Sweet!

Not sure about your characterisation of such notes having a 30ms longer attack time though; it's more that because the envelope start is delayed 30ms, all the wave/frequency/etc updates happen 1.5 frames earlier relative to the actual note start.

I think ideally I'd want to move a frame of that into the end of the previous note, so the delay's only 10ms. As it is, the player I'm working on places the two frames for HR into the tail end of the previous note (iff HR is required). Might have to try to incorporate something similar for this..
2016-03-17 10:13
lft

Registered: Jul 2007
Posts: 369
To clarify: It is the peaks of the envelopes that will line up for rates 4 and 1. The onsets of the notes will differ by 30 ms.

If I understood your suggestion correctly, that would involve starting the entire procedure three frames ahead of time when a hard-restart instrument with attack rate 0 or 1 is due. In my player right now, that information is not available at that time, although with a different architecture it could certainly be done. It's the usual tradeoff between rastertime, code size and features.
2016-03-17 11:20
ChristopherJam

Registered: Aug 2004
Posts: 1378
Yes, fair point about the peak alignment.

Quote:
If I understood your suggestion correctly, that would involve starting the entire procedure three frames ahead of time when a hard-restart instrument with attack rate 0 or 1 is due.

Not necessarily. If we use your suggestion from Avoiding the ADSR bug in the decay phase. to hide the bug in the sustain phase, then one can use the second last frame of the previous note to initiate a 6ms release, then in the final frame one can use your suggestion above to kick off a delayed attack :D
2016-03-17 11:47
cadaver

Registered: Feb 2002
Posts: 1153
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.
2016-03-17 13:29
lft

Registered: Jul 2007
Posts: 369
Quoting ChristopherJam
If we use your suggestion from Avoiding the ADSR bug in the decay phase. to hide the bug in the sustain phase, then one can use the second last frame of the previous note to initiate a 6ms release, then in the final frame one can use your suggestion above to kick off a delayed attack :D


Ah, I see. But then you'd rely on the composer manually ensuring that the first hard-restart won't be necessary, so that it's possible to perform only the second. To me, that defeats the purpose of having hard-restart in the first place.
2016-03-17 13:41
lft

Registered: Jul 2007
Posts: 369
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.
2016-03-17 13:44
ChristopherJam

Registered: Aug 2004
Posts: 1378
My plan is to have the editor software (rather than the composer) ensure every note ends with env=0, and the rate counter safely trapped in the 0-8 loop. But this is getting a fair way off topic now.

Nice cycle counting on the sprite DMA uncertainty, btw :)
2016-03-18 03:01
Agemixer

Registered: Dec 2002
Posts: 38
Does this all assume that sustain value should be dropped completely down to $00 before restart? Or by (level-1)..0?

Now this is why i never understood why a hard restart should be done in the way you expect:

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?

I'd say the release would be only used for HR then. Decay is identical to HR, so why not simulate the release with lowering Sustain level instead. 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)
2016-03-18 08:00
Jammer

Registered: Nov 2002
Posts: 1289
To add my three cents, I've practically stopped using Sustain/Release in instruments at 2x/4x speed if instrument is supposed to fade out at any time - I set SR to 0F and operate on AD entirely. It allowed me to use hardrestart time in Goat Tracker reduced from 8 player calls to 1 or 2 at 4x speed:

http://f.jammerstudio.pl/RealClap_4x.sid

Besides it's definitely more stable that my previous unstable Attack set to 1 that imposed earlier sound and I can use really quick retriggers ;)
2016-03-18 08:14
lft

Registered: Jul 2007
Posts: 369
Agemixer, I think there are two motivations for the traditional approach: Simplicity (and thus code size), and consistency of note starts. It's important to have precise control over the attack of notes, and that becomes difficult if the initial volume is varying.

When I want to do legato notes, I make some copies of the current instrument, disable hard-restart and fix the ADSR values to prevent the bug. Or I just change the pitch without retriggering the envelope.

But it's certainly possible to do what you suggest under the right circumstances, and I think that it overlaps with what ChristopherJam is attempting as well. If a note is currently being sustained (gate = on), we can do the hard-restart by writing 00 to AD two frames before the next note. To trigger the new note, we clear SR and the control register, set up the new AD, turn gate on, and finally set up SR. On the other hand, if no note is playing, we can do hard-restart the normal way. Or, like you suggest, we always stop notes by dropping S to 0 and leaving gate on.

The problem is when there's a note playing in the attack or decay phases. Clearing AD would produce an audible blip that would be out of time with the music. The only way to be safe would be to ensure, while composing, that there's enough time for every note to reach the sustain phase.
 
... 8 posts hidden. Click here to view all posts....
 
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
Krill/Plush
Thierry
Codey/Second Dimension
Guests online: 119
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 Wonderland XIV  (9.6)
9 Memento Mori  (9.6)
10 Bromance  (9.5)
Top onefile Demos
1 It's More Fun to Com..  (9.7)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 TRSAC, Gabber & Pebe..  (9.5)
6 Rainbow Connection  (9.5)
7 Wafer Demo  (9.5)
8 Dawnfall V1.1  (9.5)
9 Quadrants  (9.5)
10 Daah, Those Acid Pil..  (9.5)
Top Groups
1 Nostalgia  (9.3)
2 Oxyron  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Coders
1 Axis  (9.8)
2 Graham  (9.8)
3 Lft  (9.8)
4 Crossbow  (9.8)
5 HCL  (9.8)

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