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 > SID Envelope delay question
2020-01-31 08:42
Mr. Mouse

Registered: Dec 2001
Posts: 235
SID Envelope delay question

Hi folks, I've a question.
While studying the information on the ADSR circuitry through various in-depth sites and DIEs I thought I had pretty much nailed the details.
Yet, I still come across this typical behaviour that I couldn't find explained anywhere in detail, or I'm just too stupid to see.
So let's do this with a simple example that shows what I mean.
On a PAL machine, I change the gate on/off bit every other frame. I set ADSR to F00F.

Frame 1: Gate on
Frame 2: Do nothing
Frame 3: Gate off
Frame 4: Do nothing
REPEAT.

So technically, each frame would take ~20 ms, so the gate on/off frequency would be ~40 ms, ~80 ms for full cycle.

With and Attack rate of F and a Release rate of F, both rate periods for those will be 31251 cycles, or 31,251 ms. Now I know the Attack rate simply makes the Envelope counter go up in linear steps, while the Release rate will implement on top of the rate period the rate counter period delays at fixed envelope counter numbers to approximate an exponential decay.
If I would do the math, and taking into account the ADSR bug, by looping when Attack or Release is set at a value below the current rate counter, the program would simply be silent, with Envelope counter just going up to max 3 or 4, and then go down again, and just fluctuate around those numbers a bit. Attack cycle would start, push it up, but release cycle would push it down again.
This is not what happens on a real C64. On a real C64 the Release part is somehow delayed, giving more time to the Attack cycle, causing the sound amplitude to slowly go up.

I tried looking at the envelope code from Resid, and run that, but also that doesn't show that behaviour. It remains silent. For that code I run the Clock() function continously and change the gate every 40.000 ticks.

What am I missing? I think the behaviour has been reasonably implemented in for example Goattracker (that uses Resid as far as I know) and also Sidplay.
Is it still simply the ADSR bug? From what I can see, the behaviour is overall reproducible, though sometimes it may take a little bit longer before the Attack cycle wins it from the Release cycle and the amplitude goes up. That of course being influenced by the current state of the rate counter when the program starts.

I feel it may be obvious, but perhaps I've invested too much time that I cannot see what is right before me.
 
... 4 posts hidden. Click here to view all posts....
 
2020-01-31 12:38
Mixer

Registered: Apr 2008
Posts: 452
Ideas: Consider doing the hard restart or getting the sid envelope counter to known state(LFT method) before starting the on/off sequence to see if that is the cause. Also, dumping the data from $d41c and making a graph might help everyone to understand what is happening.
2020-01-31 17:48
Mr. Mouse

Registered: Dec 2001
Posts: 235
Okay, I output ENV3 every frame and this is the chart that comes with it.



Before the run, I reset the SID by writing 0's to the registers, then setting gate on, wait 60 ms, close gate, 60 ms, in order to make sure the release cycle is 0 and hold-zero is true (which, as I read, can only be reset by starting an Attack cycle).

The arrows in the chart show the envelope rate where the exponential counter period should change. Attack goes up from env=0. In the code, when env = 0, the expcntperiod should be set to 1. If attack set the expcounter to 0, the release should trigger the code as mentioned above and decrease env. Theoretically, env should not increase at all, because the attack rate = release rate = 31251.
Yet it does.
When env hits 6, the increase is steeper, probably because the expcntperiod is now 30 (so basically no release, according to the code).
Then env hits 14, expcntperiod should turn to 16.
Etc.

Geir just reached out to me as I wrote this just now, and he says the folling: the exponential counter does not reset during attack.
2020-02-04 09:28
Mr. Mouse

Registered: Dec 2001
Posts: 235
Well, I still don't get what is happening exactly.

For example, at env =6 , exp-period = 30. This would amount to 30 x 31,251 ms before a release (value 0xf) would kick in. In the graph this is ok, since attack rises with no apparent delay from that point onwards.

In the beginning however (between env = 0 and 6), it looks like exp-period =1, since release is working to counter the attack.

It isn't until env =93, when exp-period should be set to 2 when release is working again to counter the rise in attack.

What strikes me from the graph is the "background rhythm" of release being active to counter the rise in env. The zig-zag in the curve is indicative of this. This is quite clear from env=93 upwards, but you can also see this in the earlier time frame, but less obvious.

The period of this "background rhythm" is around 64 frames on average, according to my rough calculation. 64 frames of 20 ms (PAL 50 Hz) = around 1280 ms, or 1,28 seconds. The rise in attack from env=93 onwards is slow, fast, slow, fast etc, as you can see. Please not that the fast period there is exactly as fast as the time from env 6 to env 14, when exp-period would be set to 30 (basically no release possible in this set up).

Now why would there be a "cycle" of around 1280 ms of release (with exp-period of 2) being active, and then deactive (as if exp-period was set to 30) alternating?

What is causing this? I simply cannot explain this from any code or DIE analysis I have seen. But I might need to grow a brain.

Is it a sync between rate counter, exp counter and the gate on/off sequence every other frame? It can't be the exp counter, I think, since the "rhythm" is seen more or less the whole time.
2020-02-04 10:11
ChristopherJam

Registered: Aug 2004
Posts: 1409
Hi Mr. Mouse.

I've not gotten round to looking closely at the other details yet (and I really need to get some real hardware working again so I can test Geir's assertion about the exponential counter), but the oscillation at least makes sense to me.

You're seeing the rate counter underflows drift in and out of phase with your raster interrupts. Sometimes it underflows twice, sometimes once. Every third frame the first underflow happens (31251*2-19656*3)=3534 cycles later into the frame,

Try the following python snippet:
cycles_per_frame = 19656
rate_period = 31251

rc=0
for frame in range(40):

    gate_on_ticks = 0
    for i in range(cycles_per_frame*2):
        rc+=1
        if rc==rate_period:
            rc=0
            gate_on_ticks+=1

    gate_off_ticks = 0
    for i in range(cycles_per_frame*2):
        rc+=1
        if rc==rate_period:
            rc=0
            gate_off_ticks+=1

    print("frame {:3d}: {} attack ticks,  {} decay ticks".format (frame*4, gate_on_ticks, gate_off_ticks))
2020-02-04 11:37
ChristopherJam

Registered: Aug 2004
Posts: 1409
Or alternately, this might be easier to follow.

Graph shows value of rate counter over time, colour indicates whether gate is on or off.

Time period selected to show the transition from
- every second gate-on period contains two rc-resets (yellow downstrokes)
to
- every second gate-off period contains two rc-resets (purple downstrokes)



The envelope value will increase every yellow downstroke, and decrease for every Nth purple downstroke.
2020-02-04 13:07
Mr. Mouse

Registered: Dec 2001
Posts: 235
Thanks for your suggestion, and I did indeed look into that from that perspective, and did also the math. However, as in your chart, you will find that attack and release will cancel eachother out when it comes to env. In your chart there are about as many release as attack rate counter moments, leading to env to fluctuate between 0 to 3, but never reaching 6. Would you agree?

Also, the "rhythm" I mentioned in my previous post is 64 frames long, where every other ~64 frames (from env=93 onwards most clear) there is NO effect of release at all for ~64 frames.
2020-02-04 13:53
ChristopherJam

Registered: Aug 2004
Posts: 1409
Yes, the behaviour I was describing gives about 64 frames of AADAD followed by around 64 frames of ADDAD.

It explains the later portions of your graph, but you're right, it doesn't explain how the envelope gets off the ground in the first place.
2020-02-04 14:06
ChristopherJam

Registered: Aug 2004
Posts: 1409
Wait, yes it does. The imbalance lasts long enough to reach a value of 9 - more than high enough to trigger dropping the exponential_counter_period to 30.
2020-02-04 22:56
Mr. Mouse

Registered: Dec 2001
Posts: 235
Indeed! I confirm that this matches the early stage of the build up as well.

Modified the Python a bit and added env output in the routine. env is kept at 0 when it hits zero. Technically, I believe no release tick would even be possible in the hold zero state, but I didn't emulate that.

cycles_per_frame = 19656
rate_period = 31251
env=0
rc=0
for frame in range(120):
    
    gate_on_ticks = 0
    for i in range(cycles_per_frame*2):
        rc+=1
        if rc==rate_period:
            rc=0
            gate_on_ticks+=1 
            env+=1

    gate_off_ticks = 0
    for i in range(cycles_per_frame*2):
        rc+=1
        if rc==rate_period:
            rc=0
            gate_off_ticks+=1
            env-=1
            if env<0: 
                env=0			
			
    print("frame {:3d}: {} attack ticks,  {} decay ticks,  {} env".format (frame*4, gate_on_ticks, gate_off_ticks, env))


The underflow cycle is 60 frames, I get from the output.
I'd have to run some tests on real hardware to further confirm, since I am able to replicate the output quite easily, but I expect some delay in the build up, depending on the state of the rate counter when the routine starts. But I guess that delay can be max 60 frames (1200 ms), when the underflow cycle for release would just start.

This is excellent! Thanks so much !
2020-02-04 23:12
ChristopherJam

Registered: Aug 2004
Posts: 1409
Happy to help! Going to have to check out VICE’s behaviour now..
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
krissz
Guests online: 92
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 Party Elk 2  (9.6)
4 Cubic Dream  (9.6)
5 Copper Booze  (9.6)
6 Rainbow Connection  (9.5)
7 Dawnfall V1.1  (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 Original Suppliers
1 Derbyshire Ram  (9.7)
2 Fungus  (9.3)
3 Black Beard  (9.2)
4 Baracuda  (9.2)
5 hedning  (9.1)

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