Easier APU documentation?

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Easier APU documentation?

Post by tokumaru »

I'm trying to learn how to use the APU and I've been trying to read the wiki pages about it, but I'm finding everything terribly confusing. The information is scattered across several pages, and they are linked in a very unintuitive manner. And the explanations are very low level, full of stuff that doesn't interest me as a NES coder (they are probably useful to emulator authors, though) and only make it harder for me to understand how to interact with the APU.

I can't avoid thinking that those pages assume that the person who is reading already knows a great deal about the APU, and just needs those pages for a quick reference of which bits go where or the order in which certain things happen. I wonder if this is how a newbie feels like when looking at PPU information, for example.

Anyway, I was wondering if anyone knows about documents where APU information is displayed in a more straightforward way, much like the PPU page is, with the complete list of registers and what results a programmer should expect when writing to or reading from them. I don't care about the mixer, the sequencer, what kind of algorithm is used to generate the noise or any of that internal information, I want a bare bones document showing that when I write X to register Y the result is Z, without telling me everything that happens behind the scenes. Is there anything like that around?

EDIT 1: Just to make it clear, I understand what the APU can do, I know what periods I should use for each note, I know what the duty cycle is, that part is fine (I learned most of it by playing with Famitracker). What I need to find out is how I can get the APU to play the notes I want, at the volume I want and with the duty cycle I want without the hardware sweeps and envelopes getting in my way, because I have those implemented in software.

EDIT 2: I just found this in the Nerdy Nights sound tutorial:

Code: Select all

SQ2_ENV ($4004)

76543210
||||||||
||||++++- Volume
|||+----- Saw Envelope Disable (0: use internal counter for volume; 1: use Volume for volume)
||+------ Length Counter Disable (0: use Length Counter; 1: disable Length Counter)
++------- Duty Cycle
Now this is perfectly easy to understand, exactly like the PPU pages in the wiki. Does anyone know if this was copied from a more complete document and where it can be found?
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

Taking one of the pulse-wave channels:

Register 0 ($4000)
----------------------
Controls amplitude, duty, envelope/length counter.

%DDxxxxx = duty
%xxxxAAAA = amplitude

but you need to set bit 5 and 4 to stop the envelope/length counter. So;

lda amplitude ($00-$0F)
ora duty
ora #$30
sta $4000


Register 1 ($4001)
----------------------

To turn off the hardware pitch sweep;

lda #$08
sta $4001
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

So once I turn those things off I don't have to worry about them again? I mean, the envelope and length counter I'll probably disable whenever I rewrite the volume and duty cycle, but what about the sweeps? Can I just disable them once and forget about it?

I still would like to have more information about the other channels (triangle and noise), so if there is a document out there that doesn't use the cryptic names used in the wiki (why would it call the volume "envelope"? that's just misleading...), please let me know.
3gengames
Formerly 65024U
Posts: 2281
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

I agree....I need/want to write a sound engine for my future complex games but the sound really really scares me since all this stuff seems just to...well....just is so un-interlaced. Nothing seems to goto together with good examples. I would love for a better description of registers and how to control them but I know that is asking alot :/


Maybe it'll get there piece by piece ^_^
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

tokumaru wrote:So once I turn those things off I don't have to worry about them again? I mean, the envelope and length counter I'll probably disable whenever I rewrite the volume and duty cycle, but what about the sweeps? Can I just disable them once and forget about it?

I still would like to have more information about the other channels (triangle and noise), so if there is a document out there that doesn't use the cryptic names used in the wiki (why would it call the volume "envelope"? that's just misleading...), please let me know.
You can just disable the sweeps once and never touch them again, yes.

I'll see if I can put something together later, just the facts that will get you going rather than a technical reference :)

Edited to add : this is where I got all my information from to write my code;

http://nesdev.com/apu_ref.txt

That and a lot of trial and error :)
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

65024U wrote:I would love for a better description of registers and how to control them but I know that is asking alot :/
From what I've read so far, the Nerdy Nights sound tutorial is pretty straightforward and tells exactly what you have to do to get things going without much trouble, along with simple register descriptions. Assuming it's accurate, I guess it's a really good intro to sound programming.

I still would like I concise register description to use as reference, but if there isn't any the tutorial itself will have to do. I have most of my sound engine done, I just have to write the final data to the registers now.

EDIT: Thanks again, Neil. I guess you are the guy to get help from when the issue is sound/music! :D

EDIT 2: That's Blargg's document, right? It looks better than the wiki (even though the wiki says its info is based on this doc), but there's still a lot of cryptic information we have to dig through in order to find the basics of interfacing with the registers.

EDIT 3: It seems to me that what makes the APU complex are the things I'm not interested in (envelopes, sweeps, etc.), and these in depth documents have a lot of information on them, which I don't need. Once you take those out, the APU seems to be pretty easy to use actually. What I find difficult to do is filtering what's relevant and what isn't from these in depth documents.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

I know what you mean. Going back a long, long time, once I'd figured out how to turn off the envelopes/length counter and hardware sweep, i never touched them again until recently when I added hardware sweep feature to NTRQ.

Yeah, the Nerdy Nights is pretty good stuff. I'd forgotten about that.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Done! APU basics on the Wiki.

I managed to greatly simplify the conceptual model without sacrificing any essential features. By not even covering the length counters/linear counter/sweep/volume envelopes, things are very simple. You can do all those things in software anyway, so you don't even need them. I believe as long as you follow the model described, you won't ever run into these other features.

Thanks for the inspiration, tokumaru. While writing this, I looked at the current triangle wave page on the Wiki to be sure I got the frequency formula correct, and saw how bad it was as a programming reference. :)
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

tokumaru wrote:The information is scattered across several pages
If three different channels have a given component, why repeat the full description of that component on the three separate pages about the three different channels? For example, the channels Pulse 1, Pulse 2, and Noise have the volume envelope generator.
tokumaru wrote:So once I turn those things off I don't have to worry about them again? I mean, the envelope and length counter I'll probably disable whenever I rewrite the volume and duty cycle, but what about the sweeps? Can I just disable them once and forget about it?
Yes. If you plan to do all frequency changing in software, do this to disable hardware sweep:

Code: Select all

  lda #$08
  sta $4001
  sta $4005
I still would like to have more information about the other channels (triangle and noise), so if there is a document out there that doesn't use the cryptic names used in the wiki (why would it call the volume "envelope"?
The volume section has two modes: decay mode and constant mode. Decay mode acts like the decay phase in an ADSR envelope.
Last edited by tepples on Thu Jul 29, 2010 6:18 am, edited 1 time in total.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

The main point is that you have two audiences with different needs. Emulator authors need to know every detail. Duplicating information in this detailed description is a violation of the DRY principle, and leads to inconsistencies. Programmers generally only need to know how to make the desired sounds, so a different format is called for. The new page hopefully serves many programmers.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Thanks for the new page, blargg, it's much appreciated.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

I think I'm going a bit mental. It's not like I haven't programmed NES audio before but if I do this;

Code: Select all

lda #$0F
sta $4015
lda #%00111111
sta $400c
lda #$00
sta $400e
I get nothing. But if I do;

Code: Select all

lda #$0F
sta $4015
lda #%00111111
sta $400c
lda #$00
sta $400e
sta $400f
I get noise, as expected.

I'm pretty sure in the past I've always just wrote the noise pitch to $400e and $400f but I can't remember why.
User avatar
Memblers
Site Admin
Posts: 3901
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

There is also Brad Taylor's 2A03 reference, which covers the sound aspects of it as well.
http://nesdev.com/2A03%20technical%20reference.txt
neilbaldwin wrote: I'm pretty sure in the past I've always just wrote the noise pitch to $400e and $400f but I can't remember why.
Because $400F (same as $4003/$4007/$400B) contains the length counter, IIRC setting D3 enables it, but with a stopped counter or infinite length. Writing there also re-triggers hardware volume envelopes. I treat it like a "note on" register, but I think with the noise channel you would only have to write to it once.

Some sound engines used D3 of those registers to stop the sound (or they set the frequency to zeros, or they set the volume to zero, lots choices if the length counter isn't being used, heheh).
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

Here's a big APU gotcha: Even if you're not using the sweep unit, you must still write 0x08 to the sweep register, otherwise it won't play the lowest notes.

There are features in the APU that stop a note when the current period + "whatever sweep would add" becomes too high, and writing that value to the sweep register stops that.
Last edited by Dwedit on Thu Nov 18, 2010 11:38 am, edited 1 time in total.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

Dwedit wrote:Here's a big APU gotcha: Even if you're not using the sweep unit, you must still write 0x08 to the sweep register, otherwise it won't play the lowest notes.
Yep, nasty one for the beginner that.

Re. the noise thing. I need to do another test (just about to run out the door) but if you copy the apu init routine from the wiki, you won't get any noise. But if you just tack an extra lda #0, sta $400F on the end it works. Is there something in the order that you write the registers?
Post Reply