virtualc64 icon indicating copy to clipboard operation
virtualc64 copied to clipboard

Electronic Speech System

Open hipco opened this issue 1 year ago • 11 comments

After V4.5 Ghostbusters and Impossible Mission have a distorted Electronic Speech System output. I've tried many different settings but none of them worked for me. Is there something I'm missing in the machine configuration settings or is it a bug?

hipco avatar Feb 25 '24 09:02 hipco

Did you select the 6581 SID? The newer 8580 does not so well at speach synthesis. Commodore removed a bug in the newer SID which was exploited for speach synthesis.

mithrendal avatar Feb 25 '24 11:02 mithrendal

Confirmed. Something is broken.

dirkwhoffmann avatar Feb 25 '24 16:02 dirkwhoffmann

Yup, bug. SID 6581 doesn't make any difference.

hipco avatar Feb 25 '24 17:02 hipco

Seems to work in v4.6. First broken release is v4.7b1

Next step: Determine the faulty commit

dirkwhoffmann avatar Feb 25 '24 17:02 dirkwhoffmann

Tried V4.6 and the speech synthesis works.

hipco avatar Feb 25 '24 17:02 hipco

Did a binary search on the repo: Culprit is commit 55aadf4.

dirkwhoffmann avatar Feb 25 '24 17:02 dirkwhoffmann

Culprit is the CIA sleep logic. Here is the relevant part with an additional if-statement added for debugging:

    // Sleep if threshold is reached
    if (tiredness > 8 && !CIA_ON_STEROIDS) {
        sleep();
        scheduleWakeUp();

        // EXPERIMENTAL TO HUNT DOWN #785
        if (wakeUpCycle <= sleepCycle) {

            printf("Alert: %lld %lld\n", wakeUpCycle, sleepCycle);
            wakeUp();
        }

    } else {
        scheduleNextExecution();
    }

During speech synthesis, the following output is produced:

Alert: 60326377 60326377
Alert: 60331070 60331070
Alert: 60338006 60338006
...

The CIA puts itself to sleep with a wake-up cycle that matches the current clock. In the old code, events were processed after each half-cycle which woke the CIA in the same cycle it fell asleep. In the optimized code (with events only processed once per cycle), the wakeup comes one CPU cycle too late, resulting in a stuttered sound.

Clean fix: Alter the sleep logic such the CIA is only put to rest if it sleeps for at least 'n' cycles (with a suitable 'n').

dirkwhoffmann avatar Feb 25 '24 18:02 dirkwhoffmann

Here is a small speed-improvement idea. Current code:

void
CIA::serviceEvent(EventID id)
{
    switch(id) {

        case CIA_EXECUTE:

            executeOneCycle();
            break;

        case CIA_WAKEUP:

            wakeUp();
            break;

        default:
            fatalError;
    }
}

Idea: Since CIA_WAKEUP is a rare event, emulation can be sped up by adding a separate CIA_WAKEUP_SLOT in the secondary event table. By doing so, the CIA_EVENT slot would only be responsible for CIA execution. The dispatch function above could be eliminated, and executeOneCycle() could be called directly whenever a CIA event fires.

dirkwhoffmann avatar Feb 25 '24 18:02 dirkwhoffmann

I'm impressed.

hipco avatar Feb 25 '24 18:02 hipco

Any news about V4.8?

hipco avatar Apr 18 '24 08:04 hipco

I'm currently working on v5.0, which will feature run-ahead. It'll still take some time because I've refactored large parts of the code (which broke various stuff), and I am also busy with other projects.

dirkwhoffmann avatar Apr 18 '24 08:04 dirkwhoffmann

Fixed in v5.0b1

dirkwhoffmann avatar May 30 '24 09:05 dirkwhoffmann