A few specific APU questions

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
A few specific APU questions
by on (#108308)
I'm trying to get a better handle on the APU and a few specific questions have popped up.

1. Does the 32,767-bit sequence generated by the noise channel's RNG always output the same bit order? Or is its length the only constant? Perhaps a more practical rephrasing of this question: if game X and Y both use a 30-frame burst of noise at period index 5 for a drum hit, will the drum sound identical in both games (assuming all else is equal)?

2. At sufficient speeds, rapid duty cycle changes and C64-style one-channel 'chords' sound similar to me. Any game examples that exclusively use one or the other so I can hear the difference?

3. Ditto for the sweep unit. What are some good game examples that used the effect for music and/or effects?

4. Unlike the SID, the APU has no per-channel hardware filters, correct? (Beyond the low-pass filter of the RF mentioned in the wiki?)
Re: A few specific APU questions
by on (#108316)
Noise is continuous. It starts out the same from power on, but never resets itself back to its initial state unless you run it exactly for its full period. The noise channel even runs while the volume is at zero, but the channel is still enabled and running.

You can hear rapid duty cycle changes when you use a spell in Dragon Warrior 2, 3, and 4. Kings Quest V uses rapid duty cycle changes for music. You can hear rapid note changes in games that use arpeggios, like Codemasters games or games by Software Creations (solstice, silver surfer, etc..).

Dr. Mario is a good test case for disabling the sound channel when the period sweeps too low. If you forget to disable the channel, the sound effects will run too long. If you don't get have it, grab the Sound Test program from the nesdev main page, it lets you set the sound registers to whatever you want, and you can compare it against another working emulator. The newly released homebrew game Streemerz also uses the sweep unit to change the high byte of the sound period.

Yep, no filters.
Re: A few specific APU questions
by on (#108332)
1. Unlike the Game Boy, the noise LFSR never resets, so each drum hit sounds unique, rather than like a sample as you get on the Game Boy. The LFSR's period is 32767, which is just how long the sequence is until it loops back around. You can play continuous noise at a lower frequency and hear the repeating pattern. The particular bit sequence is fixed, based on the LFSR width and tap locations, so if you managed to synchronize your code to the LFSR using cycle timing, you'd get the same particular noise sound each time.
Re: A few specific APU questions
by on (#110127)
Bumping my topic because I have a few more questions:

- I'm still looking for games that use the hardware sweep in music or sound effects. I've been crawling through some early Nintendo-produced titles and I'm finding most disable the effect (usually writing #$7F or #$00 to $4001/$4005). I understand that the sweep creates a vibrato effect, but I really want to hear what this sounds like in context.

- Part of my search problem is that I'm not great with FCEUX's debugger. Is there a way to monitor writes to bit 7 of $4001/$4005 instead of all writes? Or, is there a way to check for a hardware effect in NSFplay?

- I'm also looking for in-game examples of the envelope decay loop.
Re: A few specific APU questions
by on (#110129)
Original questions:

1. As far as noise predictability, it's supposed to reset to 1 on power-on I believe, but it'd be very difficult to time it to be at a specific point in the sequence when you want to play your first sound (and impossible on reset). At the high speeds you can clearly hear the looping period of the noise generator.

2. If you want to hear the difference between duty cycle macros and arpeggio macros, I suggest you try playing with Famitracker. It's very easy to create those things with it.

3. For me, the game that allowed me to tune the hardware sweep functionality of my NSF emulator was Zelda 2. A lot of its SFX use sweep heavily, and in a way that will sound incorrect if you're even slightly off.

4. Right, no filters. Some people have done interesting things by making filtered noises and turning them into DPCM samples though.

New questions:

- Zelda 2, as mentioned above. That was the best test case I found.

- Yes, FCEUX has a thing called "conditional breakpoints", read about them here: http://www.fceux.com/web/help/fceux.html?Debugger.html

- Bomberman and Metroid use the envelope for decay. NSFPlay's keyboard view will show an E when the envelope is in use. If you're looking specifically for looping envelopes, Adventure Island 3 uses the loop in NSF track 16 for a little double hi-hat sound (kinda subtle). It's pretty rarely used feature. (I think I will make NSFPlay show "L" if loop is on, in the future.)
Re: A few specific APU questions
by on (#110131)
Does jumping, landing on an enemy, swimming, or entering a pipe in Super Mario Bros., or line clearing in Tetris use sweep? Does the music in Vice: Project Doom or Klax use sweep? Do the sound effects in the Action 52 menu use sweep? I seem to remember so.
Re: A few specific APU questions
by on (#110134)
Oh, also Streemerz uses (/abuses) the sweep in a very particular way that is critical to the music's playback. It's not a typical use of sweep (it's not making sweepy sounds), but it's a good test.
Re: A few specific APU questions
by on (#110165)
This is all helpful.

So I did some scouring around in Zelda II. If I'm using the debugger properly, what I'm seeing is that the hardware sweep is used constantly on both pulses, whether for music or sound effects. Setting breakpoints on $4001/$4005 shows that they're fed #$FF every frame. Setting a conditional watch (e.g., $4001 != #FF) shows that this condition never happens (at least in the intro and doing a little bit of wandering in the overworld).

This seems consistent with the sound of the pulses in the NSF, which have a constant vibrato. What I'm unclear about is the vibrato distance. In NSFplay when I slow the tracks down, I see the sweep always shifts up four bits (e.g., A2 to A6). But if the shift count in $4001 is %111, shouldn't it shift seven bits? I also listened to Punch-Out!! and Golf U.S. Course (FDS), two of Nakatsuka's other Fami soundtracks, and they have the same sweep leads. Golf has the same four bit upward sweep, but Punch-Out!!'s appear to be two bits, despite sharing the same shift count.

So perhaps I'm either using the debugger wrong or I'm misunderstanding how the sweep register functions. Any idea where I'm going wrong?

[ It's also interesting to hear the sound similarities between games. Link's sword hitting a shield sounds like selecting the practice swing in Golf, for instance. ]
Re: A few specific APU questions
by on (#110170)
Quote:
In NSFplay when I slow the tracks down, I see the sweep always shifts up four bits (e.g., A2 to A6). But if the shift count in $4001 is %111, shouldn't it shift seven bits?

Can you be clearer on this observation? When you say the sweep shifts up four bits, what do you mean? If the shift count is 7, it adds/subtracts roughly 1/128 of the raw period on each sweep clock.
Re: A few specific APU questions
by on (#110171)
blargg wrote:
Quote:
In NSFplay when I slow the tracks down, I see the sweep always shifts up four bits (e.g., A2 to A6). But if the shift count in $4001 is %111, shouldn't it shift seven bits?

Can you be clearer on this observation? When you say the sweep shifts up four bits, what do you mean? If the shift count is 7, it adds/subtracts roughly 1/128 of the raw period on each sweep clock.


In NSF track 2 in Zelda II, the pulses' frequency field in NSFplay appear to add/subtract (sorry, didn't mean bitwise shift) four bits during sweeps. A few example notes:

Code:
2A4 -> 2A8 -> 2A4
1A9 -> 1AD -> 1A9
FB -> FF -> FB
D2 -> D6 -> D2


Every track/sound effect I've checked makes this same 'move.' So I'm asking how the %111 value in the shift count corresponds to a 4-bit add/subtract in the frequency. And why the same shift count seems to create a different frequency sweep in Punch-Out.
Re: A few specific APU questions
by on (#110183)
The "4 bits" part was throwing me off. It sounds like you mean 4 units. A bit is like a digit in decimal; if something has 4 added to it, "4 digits" doesn't make sense.

Explanations I have: I'm not grasping the sweep unit at the moment, the game is changing the channels manually and the sweep isn't doing anything, the sweep shift is not configured as you say, NSFPlay is showing the wrong channel values, NSFPlay has a bug in its sweep.
...
I ran a trace and I'm seeing 7F written to the sweep registers. I also see the game code writing these vibrato values to the channel's period, toggling it by 4. Have you tried breakpoints on other registers to see whether it's showing the right value? Or maybe it's resetting the sweep constantly so that it never actually fires.
Re: A few specific APU questions
by on (#110188)
Ok, then I am misinterpreting the debugger because I see what you're saying. I am reading the realtime disassembly:

Code:
06:8112:8C 01 40  STY $4001 = #$FF


for the value in $4001 rather than the contents of Y that it's actually storing ($7F), displayed in the box to the right.

So that leads me to ask why the line above says = #$FF and why my breakpoint condition of WRITE -> $4001 != #FF is never firing?

It's funny that it's taking this much work to hear what the hardware sweep sounds like. Didn't think it'd be so elusive...
Re: A few specific APU questions
by on (#110192)
I wonder whether the breakpoint condition is being interpreted as "break when there's a write to $4011 and $4011 contains $FF".

The hardware sweep sounds no different than manually setting the channel period, aside from it not resetting the phase when the high byte is modified. If you want to hear sweeps, just listen to sound effects.
Re: A few specific APU questions
by on (#110201)
If you're using FCEUX, the display there "helpfully" indicates the value read from memory at that location (which is open bus), not the value you will write, the value in apu register, or anything else more useful.

So when you set a breakpoint of "$4001 != $FF", you get what blargg said. You'll want something more like "break on writes of $4001 where A != $FF" and then you get to hope that they used STA to write to the register instead of STX or STY.
Re: A few specific APU questions
by on (#110211)
The displayed APU pitch register values in NSFPlay 2.2 are actually incorrect (of by one, I think). If you want a more accurate display use the NSFPlay 2.3 beta. Also the correct behaviour of $4017 was not emulated at all until the 2.3 beta. The actually sweep function I think was correct in 2.2, if I recall, but the lack of $4017 control means Zelda II still had some timing errors and might sound incorrect as well. (TLDR: Get the 2.3 beta if you're not using it already.)

At any rate, the APU info on the wiki should be correct at this point. If you find it doesn't explain how the sweep works with enough detail, I'd like some feedback on that so I can revise it to be clearer.