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.
 
... 10 posts hidden. Click here to view all posts....
 
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
Flashback
Mibri/ATL^MSL^PRX
diabolus
Guests online: 123
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 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 Diskmag Editors
1 Magic  (9.8)
2 hedning  (9.6)
3 Jazzcat  (9.5)
4 Elwix  (9.1)
5 Remix  (9.1)

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