nba-emu / NanoBoyAdvance

A cycle-accurate Nintendo Game Boy Advance emulator.
GNU General Public License v3.0
971 stars 56 forks source link

DMG envelop change without retriggering sounds wrong #335

Closed copyrat90 closed 10 months ago

copyrat90 commented 10 months ago

In the hardware, the envelop goes as expected, but in NBA it stops the sound immediately.

Hardware -> NBA recording

https://github.com/nba-emu/NanoBoyAdvance/assets/34793045/7341a28e-f89e-4710-9dc1-1a639bf18e74

Test ROM

F0_F7_no_retrig.zip

Code

#include <tonc.h>

int main(void) {
    irq_init(NULL);
    irq_enable(II_VBLANK);

    REG_SNDSTAT = SSTAT_ENABLE;
    REG_SNDDSCNT = SDS_DMG100;
    REG_SNDDMGCNT = SDMG_LVOL(7) | SDMG_RVOL(7) | SDMG_LSQR1 | SDMG_RSQR1;

    REG_SND1CNT = SSQR_IVOL(15) | SSQR_TIME(0);
    REG_SND1FREQ = SFREQ_RESET | SFREQ_RATE(416);

    int wait = 45;
    while (1) {
        if (--wait == 0)
            REG_SND1CNT = SSQR_IVOL(15) | SSQR_TIME(7);
        VBlankIntrWait();
    }
}
copyrat90 commented 10 months ago

Setting the sound length while playing is also behaves differently.

Hardware -> NBA recording

https://github.com/nba-emu/NanoBoyAdvance/assets/34793045/9fa9469a-d166-4e0e-b12d-73e16a7039c4

Test ROM

length_repeat.zip

Code

#include <tonc.h>

int main(void) {
    irq_init(NULL);
    irq_enable(II_VBLANK);

    REG_SNDSTAT = SSTAT_ENABLE;
    REG_SNDDSCNT = SDS_DMG100;
    REG_SNDDMGCNT = SDMG_LVOL(7) | SDMG_RVOL(7) | SDMG_LSQR1 | SDMG_RSQR1;

    REG_SND1CNT = SSQR_IVOL(15) | SSQR_TIME(7) | SSQR_LEN(0);
    REG_SND1FREQ = SFREQ_RESET | SFREQ_RATE(416) | SFREQ_TIMED;

    int wait = 5;
    while (1) {
        if (--wait == 0) {
            REG_SND1CNT = SSQR_IVOL(15) | SSQR_TIME(7) | SSQR_LEN(0);
            wait = 5;
        }
        VBlankIntrWait();
    }
}
copyrat90 commented 10 months ago

Also, setting the initial envelop volume while playing shouldn't cut the note away.

Recordings

Hardware

https://github.com/nba-emu/NanoBoyAdvance/assets/34793045/48a8b338-8a3b-40dc-a3ae-2b7496a6b753

NBA

https://github.com/nba-emu/NanoBoyAdvance/assets/34793045/57ba6505-0cf8-4934-9844-934ec3267b08

Test ROM

volume_set_midplay.zip

Code

#include <tonc.h>

int main(void) {
    irq_init(NULL);
    irq_enable(II_VBLANK);

    REG_SNDSTAT = SSTAT_ENABLE;
    REG_SNDDSCNT = SDS_DMG100;
    REG_SNDDMGCNT = SDMG_LVOL(7) | SDMG_RVOL(7) | SDMG_LSQR1 | SDMG_RSQR1;

    REG_SND1CNT = SSQR_IVOL(15) | SSQR_TIME(0);
    REG_SND1FREQ = SFREQ_RESET | SFREQ_RATE(416);

    int wait = 45;
    while (1) {
        if (--wait == 0) {
            REG_SND1CNT = SSQR_IVOL(7) | SSQR_TIME(0);
        }
        VBlankIntrWait();
    }
}
fleroviux commented 10 months ago

Thanks for all these tests. I will take a look at this asap!

fleroviux commented 10 months ago

All three tests should be fixed with commit https://github.com/nba-emu/NanoBoyAdvance/commit/ba587e4ee063226ab6712746fc100273ff65103a. Most of these issues were caused by implementing the bugged envelope "Zombie" mode described to exist in GB sound documentation. However it turns out that the "Zombie" mode may have been fixed on GBA systems.

This change can be tested with the latest development build.