Trying to figure out how the below code works. Everything is straight forward. The code works as I ran it in qbasic in dos emulator.

But for the life of me I cannot figure out wth cap1 and cap2 are. I debugged the code and saw values being set, but I cannot figure out where the data is coming from. I assume it is somehow related to the function declarations. Been 20 years since I did anything with qbasic. Maybe some other old fogie can tell me what is going on here:

DECLARE FUNCTION integrate (sample, cap, tc)
DECLARE FUNCTION differentiate (sample, cap, tc)
COMMON SHARED accumulator
CONST pi = 3.14159

FOR timeConstant = 10 TO 600 STEP 100
accumulator = 0

FOR a = 0 TO 22 STEP .01
wave = 0
FOR h = 1 TO 10
wave = wave + SIN(a * h) / h

lopass = integrate(wave, cap1, timeConstant)

IF wave > lopass THEN
trigger = 1
trigger = 0

hipass = differentiate(trigger, cap2, 20)

PSET (a * 30, 50 - wave * 20), 15
PSET (a * 30, 50 - lopass * 20), 14
PSET (a * 30, 100 + timeConstant / 4 - trigger * 15), 2
PSET (a * 30, 270 - hipass * 20), 15

NEXT timeConstant


FUNCTION differentiate (sample, accumulator, tc) STATIC
fsample = tc
leakage = 1 - EXP(-2 * pi * 1 / fsample)
capAvg = leakage * accumulator
accumulator = accumulator - capAvg + sample
differentiate = sample - capAvg

FUNCTION integrate (sample, accumulator, tc) STATIC
fsample = tc
leakage = 1 - EXP(-2 * pi * 1 / fsample)
capAvg = leakage * accumulator
accumulator = accumulator - capAvg + sample
integrate = capAvg

The output looks like the image.

  • 1
    Okay, STATIC is the key here. It wants these functions to have their own accumulator. To me it doesn't look like its related to the global accumulator. Not sure though.

    In qbasic if a value is not defined it is assumed zero. Both functions are STATIC. So the values are retained on the next run for the parameters (I think). So in the actual call its called accumulator. So that writes to the input parameter. I guess these are references. That is why I could watch the cap1 value and see it change. So the key to rewriting these functions is to provide some sort of static accumulator.

    Interesting behavior for this code.
  • 0

    Isn't this a payload that gets passed automagically from function call to function call to generate an aggregation, e.g. total sum?
  • 0
    @IntrusionCM I think the global makes it so it resets the static accumulator in each function now that I look at it.
  • 0
    @Demolishun I'm kinda confused because qbasic has been... A long long long long long long time ago.

    Common shared accumulator...

    And cap1 / cap2 are passed on to the two functions as variables for the accumulator...

    But in the function itself only the accumulator is used.

    Are cap1 and cap2 just named differently for scoping reasons and internally / inside the function is only the variable accumulator used?
  • 0
    @IntrusionCM Empty variable is 0. The common shared allows it to reach in and change the static accumulator parameter in the function itself.
  • 1
    @Demolishun But then it makes sense.

    It gets initially set to 0 in both cases, so it is just for initialization.

    After the first run of each function, the variable accumulator is used internally and passed on.


    "Note: Values assigned to shared variables used as procedure call parameters will not be passed to other procedures! The shared variable value MUST be assigned INSIDE of the SUB or FUNCTION procedure to be passed!"

    So cap1 and cap2 are shadowed variables I guess. They exist solely for the purpose of fulfilling the function call, as then internally accumulator variable is shared between both functions
  • 1
    Here is it done with javascript and qml:
  • 1

    Oh boy.

    I finally understood that there were three graphs in the dosbox window... Oo

    I wish I could sleep more...brain is really fried the last weeks.

    Now the rest of the algorithm makes more sense to me...

    But I'm not good in mathematics, dunno how to express it in own words without being total incorrect. XD
  • 1
    And to add: Congratulations. Looks like you were able to solve your problem of understanding and port it to another language?
  • 0
    @IntrusionCM I still don't quite get how it works. But yeah, I can port it. I want to preprocess audio and see if I can make it work like the neurophone works. It is supposed to allow the skin to hear sounds. It was developed in the 50s. They made him prove it works. Then the NSA sealed the invention. He fought for years to get his invention back. Lots of circuits designed to do this. I want to solve this in code.
Add Comment