jsmolka / eggvance

A Game Boy Advance emulator.
https://smolka.dev/tags/eggvance
GNU General Public License v3.0
65 stars 1 forks source link

Golden Sun: Intro sound is worse compared to sequel #14

Closed jsmolka closed 3 years ago

jsmolka commented 3 years ago

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.

jsmolka commented 3 years ago

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