How does Battletoads generate it's PCM drums internally?

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

Moderator: Moderators

Post Reply
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

How does Battletoads generate it's PCM drums internally?

Post by Bregalad »

I really wonder, is it considered like a 5th musical channel, or does it generate data based on what is present on the noise channel ? Is it possible to add drums to the regular level songs in order to make them sound better (in the NSF only obviously - not in the game) ?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

I'm pretty sure its a separate "channel" of data, not keyed off of noise. It seemed from the intro/ending music that it could be turned on and off too, since it apparently intentionally cuts out the PCM drums during parts of the intro where there's more animation going on. (I guess they found the "buzz" undesirable otherwise.)

I think it's a poll-based sample loop that just runs from the end of the regular update until the next NMI? (I doesn't appear to use IRQ.) Previous attempts to put it into an NSF used non-NSF-compliant stuff like using IRQs, and tend to work in only one or two very specific players, but since the "Deflemask technique" proved to work in a lot of popular NSF player implementations (including powerpak), I think it would be a really good way to try to do the Battletoads soundtrack in an NSF.

(I'd been meaning to re-rip Battletoads myself using the Deflemask technique for a long while, but it hasn't been high on my to-do list.)
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by Zepper »

As far as I know... it requires the $4017 watchdog timer to work properly. Only Nintendulator has such feature. I wonder what's the big idea behind the $4017 register and music playback/control/whatever...
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

Zepper wrote:As far as I know... it requires the $4017 watchdog timer to work properly. Only Nintendulator has such feature. I wonder what's the big idea behind the $4017 register and music playback/control/whatever...
You're talking about the Battletoads NSF rip that Quietust made for Nintendulator.
http://www.qmtpro.com/~nes/nsf/battletoads_pcm.zip (info)

I believe what this did was have an INIT that never returns, so it just ends in a spinning sample loop. The player detects an INIT that runs for an inordinately long number of cycles, and if it does, it just starts running PLAY as an interruption of the INIT routine. That way whenever it returns from PLAY, it goes back to that sample loop.

If I recall, Blargg's GME also implemented this hack.

I didn't like this "solution" for a few reasons, so I declined to implement it in my NSF player. It's only relevant to this one NSF, which was a one-off experiment. Hardware players like the PowerPak or TNS cart don't support it. (A hardware implementation of this idea would indeed require some kind of interrupt to break out of the non-returning INIT, but you don't need the VS watchdog, you could just use NMI and count frames until the arbitrary "timeout" is reached.)
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by Dwedit »

Wouldn't the best possible solution be for the NSF to return from play after 29780 cycles have passed?
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

No, a non-returning PLAY is allowed by the NSF spec and is used for lots of homebrew NSFs (e.g. SuperNSF). Can't remember if it's needed for any commercial game rips, though. There might be "lag frame" PLAY calls that run long and shouldn't be interrupted.

The Deflemask trick (which is widely supported) also relies on a non-returning PLAY.
Last edited by rainwarrior on Mon Feb 27, 2017 5:09 pm, edited 2 times in total.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by tepples »

I thought a non-returning play routine worked only for an NSF with one song, as hardware players would have no chance to read the controller to navigate to other songs.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

tepples wrote:I thought a non-returning play routine worked only for an NSF with one song, as hardware players would have no chance to read the controller to navigate to other songs.
Hmm, yes, that's a common problem with those. One way to get around this is to poll the controller and return when a button is pressed, but that's very implementation-dependent (and also outside the spec). So... maybe it's not the best way to rip Battletoads either. :S

Anyhow, basically the "return early from INIT" idea solves a problem for exactly one special NSF (quietust's Battletoads rip), and I don't think causes problems for any existing INIT functions which may happen to run too long, but I'm not entirely sure about that. A timeout on PLAY, however, will break hundreds of homebrew NSFs. It kinda depends what you're intending to support, and/or what future NSF rips you're planning to make to rely on it.

There's also the "NSF2" idea, which could add IRQ or other functionality, but nobody's really implemented that yet either.

Actually, maybe I should add an option to NSFPlay to support quietust's Battletoads rip technique...
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by tepples »

Going forward, would it be a good idea to deprecate non-returning init in favor of non-returning play, and then fix the Battletoads rip to return whenever PCM isn't played for greater hardware player compatibility? Or has that already been done?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

tepples wrote:Going forward, would it be a good idea to deprecate non-returning init in favor of non-returning play, and then fix the Battletoads rip to return whenever PCM isn't played for greater hardware player compatibility? Or has that already been done?
Non returning INIT can't be "deprecated", it was a single-use hack that has never been adopted as a standard. Non returning PLAY isn't exactly a substitute for non returning INIT, either. It's just something that's well established and supported in homebrew NSF circles. Non returning INIT is actually a good proposal, but doesn't work with most players.


Since the title track of Battletoads has PCM, if the NSF starts with that track, it'll lock the PowerPak to only playing that track. So, the Deflemask technique could be used as long as the PCM tracks aren't in between the PCM tracks and other tracks, I guess, but you'll only be able to access one of them. I dunno, there's isn't a great way to get more than one PCM track to work. (Polling the controller is effective on PowerPak, and all players I've tried though, but it's dependent on the implementation returning 00000000 with no controller. Then again, the Deflemask technique is already a bit of a hack anyway, since it disables IRQ, etc. so we're already outside the spec here.)

Non-returning INIT is actually a good way to do things, but the arbitrary timeout / watchdog approach feels like a kludgy way to implement it, IMO. The PowerPak NSF player could implement a watchdog IRQ on the INIT routine, perhaps, but I think there are a bunch of problems.

Non-returning INIT was part of the NSF2 proposal. What I think we should really have is an explicit end to the INIT, to tell it when to start doing PLAY. (There was discussion of this re: NSF2.) I'd kind of have a mind to do it as having three function pointers, INIT, PLAY, and IDLE. That way INIT runs, the NSF player sets up a timer IRQ then enters the IDLE loop, then its IRQ (or NMI) starts calling PLAY and checking input whenever it returns. That's the ideal, IMO, but it requires establishment of a new standard, reference implementation, demonstration NSFs, a new PowerPak player implementation, etc. etc. (I have been planning to implement NSF2 in NSFPlay eventually, but emulation accuracy was a higher priority so far, and of course my game project has completely pre-empted it for the time being.)


Anyhow, that's all speculation about the future state of NSF. If you want to make a Battletoads RIP that will run on PowerPak and some popular players, I think the most practical thing to do with current stuff would just be to have multiple NSFs. One for all the non-PCM music. One for each PCM track, using the Deflemask technique. (Or keep it in one NSF and poll the controller.)

...but if you want something that is up to spec and runs on everything that properly implements the spec, we need a new spec and new players. :P
Rahsennor
Posts: 479
Joined: Thu Aug 20, 2015 3:09 am

Re: How does Battletoads generate it's PCM drums internally?

Post by Rahsennor »

The reentrancy required for a non-returning INIT is a pain in the ### and I will be dropping support for it next time I touch that part of my NSF player, NSF2 be damned. It's a giant unreadable and error-prone kludge.

Is there any way to make a Battletoads rip whose PLAY return immediately when there's no PCM playing? It's not ideal, but given the choice between laggy controls and timing-variation-distorted sound, I'd pick laggy controls. And it's what I'd do when writing a PCM sound engine.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: How does Battletoads generate it's PCM drums internally?

Post by Bregalad »

I dunno, there's isn't a great way to get more than one PCM track to work.
Both Battletoads and Battletoads & Double Dragon have (at least) 2 different musical tracks with PCM drums. Battletoads have the title theme and the victory theme, Battletoads & Double Dragon has the title theme and the character select screen theme.

This still doesn't answer how Battletoads handles the PCM drums internally. So far there's a debate about how to implement this in NSF but that's somewhat different. The game seems to somehow freeze itself while playing but resume when not playing, you can see this during the intro when there is dialogue between T-Bird and the Dark Queen, the text appears only when PCM isn't playing. Also in many part (actually most) of the intro PCM playing is disabled.

Trying to log it with FCEU just leads to a huge mess, I cannot even figure out where the data that is written to $4011 comes from. Apparently it's not just plain replaying what's in the ROM and there's some kind of calculations (possibly decompression or some kind of sound synthesis) going on.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How does Battletoads generate it's PCM drums internally?

Post by rainwarrior »

Oh, so the samples are compressed in some way? That's interesting.

Just recording the intro's PCM part and looking at the waveforms in an editor, I see a lot of "triangular" straight lines, and in the code I saw a variable timer on the sample output... maybe the format involves straight-line ramp (inc/dec) pieces with variable speed/length?

(Also seems like the overall samples can be played at different pitches too.)
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: How does Battletoads generate it's PCM drums internally?

Post by Bregalad »

rainwarrior wrote:Oh, so the samples are compressed in some way? That's interesting.
Well, I don't know I just saw that the code arround the $4011 writes weren't a simple load/store/wait loop like you'd expect.

(Also seems like the overall samples can be played at different pitches too.)
I guess this can be easily done just by changing the wait time between writes. If you don't need precise pitch nor constant sample rate this is simple to achieve.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: How does Battletoads generate it's PCM drums internally?

Post by Bregalad »

Looking more in detail at code once more, I'm pretty sure it does not play samples at all - instead it simply synthesize sounds with matematical formulas, made of additions substractions, logical operations and shifts.
Post Reply