How to emulate the APU

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

How to emulate the APU

Post by n6 »

I need ideas of how to emulate the APU. Since i must create the mixingbuffer myself it gets much harder. When do you mix all the audio?
Ive thinked of doing it in the end of each PPU frame but this makes it hard to keep effects and status reads accurate. any ideas?

thanks
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

If you're just starting out, mix every time an audio register is written or read or whenever the APU's 240 Hz timer ticks, and decide how many samples to mix by how many CPU cycles have elapsed since the last update.
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

What about this.. The linear counter is set, I start to write until next APU tick. the next thing that happens is that it stops the channel, then ive to remove everything?

I was thinking about an action buffer that put all writes and at which CPU cycle they occur in a buffer and then in the end mix everything, but this will make it hard to fix the status reads=/
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

When a status read occurrs, emulate the APU up to that point.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

but do you think this is a good idea? whats the common number of writes to the APU each frame?
have anyone tried this technique, what do you think?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Do you have CPU emulation working apart from the APU?
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

I'vent decided yet
User avatar
Zepper
Formerly Fx3
Posts: 3264
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

There's two "basic" ways to emulate: using OR not using "timestamps". Personally, I disagree because of a couple of reasons that's useless to discuss here. But if you're already using such timestamp system in your emulator, so go ahead. -_-;;

About the APU, it's quite easy, but you might read the blargg's APU reference a couple of times before writting your first beta of the APU emulator. Basically, take care about when the APU changes the sample data, and write the samples into the buffer following the NES frequency, or in other words, write 1 sample at every CPU cycle. Bump.
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

Yeah I think i'll stick to it, mix one sample per CPU cycle would be a real performance killer
User avatar
85cocoa
Posts: 96
Joined: Sat Jul 22, 2006 12:06 pm
Location: USA

Post by 85cocoa »

n6 wrote:mix one sample per CPU cycle would be a real performance killer
IIRC, that's what FCE Ultra does in high/highest quality mode, so... well, decide for yourself how you want to balance performance and quality.
Warning: I am not a serious developer (yet), but CS and EE really interest me.
I was -_pentium5.1_- until I screwed up. This is why I screwed up. ^_^
User avatar
Zepper
Formerly Fx3
Posts: 3264
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

Nope, that's what it IS supposed to do. You can, however, change the way to RESAMPLE the buffer. ^_^;;
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

That's what every APU emulator does, it effectively generates sound at the 1.79 MHz NES clock rate then resamples it to 44.1 kHz (or 48 kHz etc.) for the PC. The only difference is how the resampling is done. Contrary to the common view, trading off quality for performance does not give a very large gain if the quality version is implemented using an efficient algorithm.
User avatar
85cocoa
Posts: 96
Joined: Sat Jul 22, 2006 12:06 pm
Location: USA

Post by 85cocoa »

Sorry if I misunderstood something, but I was referring to the following stuff from the FCE Ultra documentation:
FCE Ultra documentation wrote:Sound channels are emulated with CPU instruction granularity. There are two sound quality options. Low-quality sound, the default sound quality option, generates sound data at 16x the playback rate and averages those samples together to 1 sample. This method works fairly well and is reasonably fast, but there is still some aliasing and sound distortion. All sample rates between 8192Hz and 96000Hz are supported.

The high-quality sound emulation is much more CPU intensive, but the quality is worth it, if your machine is fast enough. Sound data is generated at the NES' CPU clock rate (...), and then resampled to the output sample rate. Custom-designed 483rd order Parks-McClellan algorithm filter coefficients are used. Supported playback rates are 44100Hz, 48000Hz, and 96000Hz. (...)

The "highest" sound quality mode is similar to the normal high-quality mode, but the filters are of a higher order(1024 coefficients). Ripple is reduced, the upper bound of the passband is higher, and the stopband attenuation is slightly higher. The highest-quality mode filter coefficients were created using "gmeteor". The parameters used to create these filters can be found in the source code distribution.
Of course, I'm ignoring the issue of FIR filters, but I was trying to contrast FCEU's low-quality sound mode (which clearly does not "mix one sample per CPU cycle") with its better modes.

EDIT - @n6 (post right below mine): I was not trying to make a suggestion; I was simply stating the facts that I knew.
Last edited by 85cocoa on Thu Sep 28, 2006 11:09 pm, edited 1 time in total.
Warning: I am not a serious developer (yet), but CS and EE really interest me.
I was -_pentium5.1_- until I screwed up. This is why I screwed up. ^_^
n6
Posts: 60
Joined: Tue Jul 11, 2006 10:12 am

Post by n6 »

But I am not going to skip samples like that. Iam going to do exactly as my PPU works. when something interesting happens update to that point.
randilyn
Posts: 16
Joined: Tue Mar 28, 2006 6:22 am

Post by randilyn »

I know I never post here, but I thought I'd respond to this since I recently finished overhauling my sound core and learned a few things that you might find useful...

Accurate sound emulation (that is, emulating sound at the APU's clock) is not as slow as you might believe, since most of the time you'll be doing little more than counting down timers for various units and whatnot. Very simple (and fast) integer operations that equate to little overhead.

For a speed comparison of the various methods used, FakeNES CVS has the following emulation modes:

Fast - Emulate and render at output sample rate. This mode uses delta timers to try and keep the APU emulation from becoming too grossly inaccurate, but it has a huge speed boost. In fact, combined with an all-integer emulation, this is probably as fast as you can emulate the NES' sound efficiently, but results vary by sample rate.
Speed on my system: ~450FPS

Accurate - Emulate at APU clock, subsample and output at sample rate. This seems to be the most common method used.
Speed on my system: ~300FPS.

Ultra - Emulate and render at APU clock and supersample to the output sampling rate using a simple linear mixing scheme. Residue removal allows for fractional input sample per output sample counts. In FakeNES, this method gives the best quality and least aliasing since it emulates the waveform generators logically instead of synthetically.
Speed on my system: ~250FPS

Note that in all modes it uses "catch-up" type timing, where it performs delayed processing before reads and writes to the APU's registers to synchronize the interface state with the current CPU/PPU state before it can be modified or tested by software (the game).

Hope this helps to put some things into perspective. ^^
Post Reply