Square's decay volume confusion

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Square's decay volume confusion

Post by Disch »

My implimentation of the square channels involves keeping two seperate volume levels. One is the volume which is actually output by the channel... the other is the "decay volume", which is altered by the envelope/decay unit and is reset to $0F on $4003/$4007 writes. My understanding is that the decay volume is always altered by the decay unit, regardless of whether or not decay is enabled... however if decay is disabled, the output volume is unaltered by the decay unit.

My old implimentation was like the following:

on $4003 write:
- set decay volume to $0F
- if decay is enabled, set output volume to $0F as well

Doing it this way... someone (koitsu probably) brought Shin Onigashima.nsf to my attention. Apparently the first track on this nsf gets crackly and poppy with this implimentation. So with that in mind... I removed the above portion in my new implimentation and leave the output volume unaltered on $4003 writes (only updating the output volume on decay unit clocks). This solved the NSF problems.

However, someone else has brought this problem up with a test ROM... implying that the old implimentation was correct.

Can anyone give me a definative answer on which method is correct? is the Shin Onigashima NSF supposed to be crackly?

I tried the NSF and test ROM in Nintendulator and FCEU. Nintendulator seems to do my old implimentation -- it plays the test rom fine but crackles the nsf. FCEU, oddly, plays both fine... I don't know what it's doing.

Anyway, any help appreciated.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

I can't hear the crackling you are referring to - are you using the latest version of Nintendulator?
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

He's asking this because I noticed that some games's sound is off in his emu, so I went to my beloved SNDTest rom (made by someone else. :D), and set the registers as follows:

4000 - %10001000
4001 - %00000000
4002 - %10000000
4003 - %00000000

This makes a simple beep noise. In Disch's emu, the beep has a 'fade in' type effect in it (the volume isn't full at the start... it's seemingly random, and then it goes full, as though he's not resetting the volume right away), and I don't think that's right, as Nintendulator doesn't do this, and neither does anything else I've tried.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Quietust wrote:I can't hear the crackling you are referring to - are you using the latest version of Nintendulator?
Eeep... no I wasn't. Didn't know you updated... my mistake.

Yeah the new one seems to play the NSF and test ROM fine. What method are you using?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

0.960 when?

Post by tepples »

Quietust wrote:I can't hear the crackling you are referring to - are you using the latest version of Nintendulator?
I don't see any releases newer then 0.900 in Nintendulator's file list nor newer than 0.950 on the web page.
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

"0.950" is not an official release (note the "Beta"); as such, the binary changes whenever I add a feature or fix a bug, which can be anywhere between once a week and twice an hour.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

The envelope unit section in the NES APU Reference is based on lots of hardware testing. Could it use improvement?

Here's the code I use, edited for clarity ("Shin Onigashima.nsf" sounds clean when playing with it):

Code: Select all

bool env_enabled;
bool env_loop;
int env_period;
int env_delay;
int env_vol;
int volume;

void write_4000( int n )
{
    env_loop = (n & 0x20) != 0;
    env_period = (n & 15) + 1;
    env_enabled = !(n & 0x10);
    volume = env_enabled ? env_vol : n & 15;
    // ...
}

void write_4003( int n )
{
    env_reset = true;
    // ...
}

void clock_envelope()
{
    if ( env_reset )
    {
        env_reset = false;
        env_vol = 15;
        env_delay = env_period;
    }
    else if ( --env_delay == 0 )
    {
        env_delay = env_period;
        if ( env_loop || env_vol > 0 )
            env_vol = (env_vol - 1) & 15;
    }
    
    if ( env_enabled )
        volume = env_vol;
}
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Ahh... I overlooked that part in the doc.

Thanks for the clarification.
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

I just wrote this simple test ROM which uses the volume envelope in a way that depends on some subtleties of its behavior. It also depends on some aspects of proper $4017 implementation. The archive contains the test ROM (iNES format), asm source, and a recording of output when run on a NES. It should play a sound slowly fading in then holding. I may make an NSF of it to test NSF players.

It moved! http://blargg.8bitalley.com/ripway/temp/test_apu_env.zip
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Awesome... seems to be working for me. Thanks for the test ROM... they're always a good thing =)

Btw, I've been meaning to ask you... your APU doc led me to believe that when $4017 is written to with the high bit set, the frame sequencer is clocked immediately (which this demo confirms). But when it's written to with the high bit off... it doesn't get clocked for ~7457 cycles. That's how I'm doing it anyway. Is that right? Or should I be clocking it immediately regardless of the high bit?

Thanks again blargg, you rock ;D
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Disch wrote:Your APU doc led me to believe that when $4017 is written to with the high bit set, the frame sequencer is clocked immediately (which this demo confirms). But when it's written to with the high bit off... it doesn't get clocked for ~7457 cycles.
Correct, and the test ROM above relies on this to keep the envelope unit at a constant volume during each step of the test. Below wlp keeps resetting the APU just before 1/240 second would pass, effectively suspending envelope clocks:

Code: Select all

      ldy   #16         ; y controls volume
loop:
      lda   #$08        ; schedule envelope reset on *next clock*
      sta   $4003
      lda   #$20        ; enable envelope now, with looping to expose bugs
      sta   $4000
      
                        ; Play at current envelope volume and suspend
                        ; envelope clocks to extend this for a while
                        
      ldx   #80
wlp:  lda   #$40        ; reset sequencer *without* clocking envelope
      sta   $4017
      lda   #39         ; wait until just before envelope clock
      jsr   delay_01msec ; delays a*0.1 msec
      dex
      bne   wlp
      
      lda   #$10        ; volume = 0, disable envelope
      sta   $4000
      
                        ; Now clock envelope 'y' times. First clock will
                        ; reset it to 15 (the write to $4003 at the top
                        ; will finally take effect).
      tya
      tax
rlp:  lda   #$c0        ; reset sequencer and clock envelope now
      sta   $4017
      dex
      bne   rlp
      
      dey
      bne   loop
NerveGas
Posts: 29
Joined: Sun Sep 16, 2007 10:41 am

Post by NerveGas »

I implemented this exact code and i'm just getting clicks at the beginning of punchout. How often are you calling clock_envelope? Every sample?
User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

The envelope is clocked at approximately 240 Hz or 192 Hz, as described on the NESdevWiki: http://nesdevwiki.org/wiki/index.php/APU_Frame_Counter
Post Reply