jsmolka/eggvance

Golden Sun: Intro sound is worse compared to sequel

jsmolka opened this issue · 1 comments

The Nintendo intro bleep (channel 1) is way worse compared to Golden Sun - The Lost Age.

Game A writes to channel 1:

800008000000
878244800008
87C294800008
87C224800008
80C208800008

Game B writes to channel 1:

800008000000
878254800008
87C294800008
87C224800008
80C208800008

The frequence is slightly different but the bad sound persists even when forcing the value to 0x54.


The written data results in the following sequence:

Game A:

Sq1: form 0 | frequency 0
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0
Sq1: form 2 | frequency 1922
Env: volume 4 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 3
Sq1: form 2 | frequency 1986
Env: volume 9 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 8
Env: volume 7
Env: volume 6
Env: volume 5
Env: volume 4
Env: volume 3
Env: volume 2
Sq1: form 2 | frequency 1986
Env: volume 2 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 1
Env: volume 0
Sq1: form 2 | frequency 194
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0

Game B:

Sq1: form 0 | frequency 0
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0
Sq1: form 2 | frequency 1922
Env: volume 5 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 4
Sq1: form 2 | frequency 1986
Env: volume 9 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 8
Env: volume 7
Env: volume 6
Env: volume 5
Env: volume 4
Env: volume 3
Env: volume 2
Sq1: form 2 | frequency 1986
Env: volume 2 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 1
Env: volume 0
Sq1: form 2 | frequency 194
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0

The output should be almost identical so I suspect this to be a resampling problem.


Both games still have different sound output when removing external things like BIAS and even hardcoding the frequency.


It appears that halting causes the problem. A uses halting while B doesn't. Removing the halt state in A fixes the audio problems. Halting the CPU results in single runs of 960 cycles which cause the sample function in the APU to run twice sometimes. Although this shouldn't be a problem, it is. Splitting the run function into single parts fixes the issue.

uint visible = 160;
while (visible--)
{
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run( 60);
    ppu.scanline();
    ppu.hblank();
    arm.run(100);
    arm.run(100);
    arm.run( 72);
    ppu.next();
}

Running 960 at once also ticks the sequencer 960 times. The square channel calculated it's values and this value is now samples twice with the intermediate step missing.

The bug as been reintroduced with the new scheduler. It can be fixed by checking how many cycles are left until the next event.