Wavetable via $4011 is it possible?

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

Moderator: Moderators

Post Reply
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Wavetable via $4011 is it possible?

Post by za909 »

I've been listening to a lot of POKEY music and a lot of songs manipulate the channel volume at different rates to produce a 4-bit wavetable channel. And I'm curious, is it possible to do something like this with the NES? Just a single channel with <=64 samples per wavetable. (the bit depth could either be the full 7 bits or just a 4-bit one with a configurable number of left or right shifts to implement volume control)
And moreover, is this possible in a game using a mapper with a CPU cycle counter? (even if only bass-notes spent a low enough amount of CPU cycles)

Now I know that there have been demos of using a dummy sample and DMC IRQs for this, but with a mapper there would be no artifacts from playing the $AA byte.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Wavetable via $4011 is it possible?

Post by Bregalad »

Of course this is possible, but it has many practical consequences.

As you said it yourself this would require a mapper with CPU cycle IRQ, or at least it would greatly help. Then, there is the problem that it would be very CPU intensive.

The last problem is that VBlank NMI and sound IRQ would interfere with eachother, the NMI creating distortion in sound, and the sound potentially stealing cycles for VRAM updates.

I think Blargg made a demo where it combines $4011 and (short) DPCM sample in order to create a saw wave, the advantage is that less CPU is used, as it is mostly used to make the sharp side of the sound, while the normal DPCM sample is used for the ramp part of the sound and requires no CPU intervention. Of course emulator support for this is very low.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Wavetable via $4011 is it possible?

Post by tepples »

The most fundamental problem is OAM DMA blocking the IRQ. So when most games use timed writes to $4011, they stop the action to do so. That's fine for the Wheel of Fortune Featuring Vanna White audience shouting what game show it's based on, Blades of Steel signaling a "face-off", or Action 52 telling you to "make your selection now", but application to background music is very limited. It ends up used on scenes with little or no action, like the Skate or Die 2 title screen whose only animation is that of the palette, and Big Bird's Hide and Speak where Big Bird's mouth flaps happen only at quiet parts of the sample.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Wavetable via $4011 is it possible?

Post by thefox »

Bregalad wrote:Of course emulator support for this is very low.
Why would support be be low? It's a cool technique, but it's just normal DPCM usage as far as I know. It hasn't been used in any homebrew productions, though, unfortunately.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: Wavetable via $4011 is it possible?

Post by lidnariq »

This is basically a subset of what SuperNSF does...
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Wavetable via $4011 is it possible?

Post by Bregalad »

thefox wrote:
Bregalad wrote:Of course emulator support for this is very low.
Why would support be be low? It's a cool technique, but it's just normal DPCM usage as far as I know. It hasn't been used in any homebrew productions, though, unfortunately.
I do not know, I am no emulator author. I just noticed that Blarg's demo works almost only on Nestopia and Nintendulator if I remember well (too lazy to double check). Most emus support manual sample playing via $4011 and automatic play with $4010, $12 and $13, but not the combination of both at the same time, combined with tricky IRQ timing tricks.
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: Wavetable via $4011 is it possible?

Post by za909 »

Yeah I figured NMIs would be a no-no but also the OAM DMA... which I guess would still be a problem even if you choose lower pitches + increase the sample length (but it also detunes you to a B scale)
I threw these together in a couple minutes, and I was too lazy to add a controller reading routine so you can edit CPU $0000 for pitch and $0001 for sample length to find out what the combo throws out (I guess lengths that aren't powers of 2 might detune you do a different scale?)
And additionally the values written to $4011 could also be played with to gain volume control (works great for the saw)
and square waves kind of require you to split the wave period into the on and off phase, and more pulse widths could be achieved by dividing it more but would also take more CPU to do. I guess it could be used at certain places, FDS versions of a few games only used the FDS wavetable during scenes, so someone using this for the music that allows it, shouldn't be considered a "heretic" imo.
Definitely easier for games with no IRQ-s otherwise, and if the volume control is too much, it's easy to turn it on and off with SEI and CLI. As I've found when the music would need to change the note, a BRK could be useful, otherwise the pitch is left unchanged until the next IRQ.

Code: Select all

IRQ: ; Square Wave IRQ
pha
lsr $02 ; get phase bit
bcs @secondphase
inc $02 ; set wave phase to 1
lda #$00
beq @merge
@secondphase:
lda #$1F
@merge:
sta $4011
lda #$1F
sta $4015
pla
rti
Attachments
Square.nes
(40.02 KiB) Downloaded 190 times
Saw.nes
(40.02 KiB) Downloaded 188 times
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Wavetable via $4011 is it possible?

Post by Bregalad »

Oh so you're using a combination of automatic playback via $4010 and $4012/13 and $4011? I tought you were asking about $4011 only.
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: Wavetable via $4011 is it possible?

Post by za909 »

No, because the idea occured to me, that not only arbitrary waves could be made, but a lot of things where the instant level changes happen in IRQ and the rest is automatic. That way you can minimize the CPU usage because it's the automatic playback in-between IRQs, but at some point with complex waves you'd be better off just using DPCM anyway.
And if I attempt that, I should probably read from a table, using the phase counter as the index.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Wavetable via $4011 is it possible?

Post by Bregalad »

Well personally I'd think the advantage of using $4011 only is that you get finer control over frequency (assuming you have a mapper with CPU cycle timer) and better emulator support (in theory this should never be a significant argument, but in practice...)

For any practical "in game" situation (including ones with low CPU usage) you're going to get 60Hz or 50Hz hum in the sound anyway, so this is only practical for drums or other non-pitched sounds (i.e. Battletoads). This however defeats my "finer control over frequency" argument, because for non-pitched sounds nobody cares anymore.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Wavetable via $4011 is it possible?

Post by tepples »

The real advantage over $4011 is that you can use codecs other than delta modulation, which means less chance of slope overload distorting the crap out of the treble. One of my demos uses 4-bit quadratic delta PCM with invertible linear interpolation, which allows bits to be used either for 0-4000 Hz (most sounds) or 4000-8000 Hz (for "s" sounds).
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: Wavetable via $4011 is it possible?

Post by za909 »

Yeah I see the problems with this, and so I made a 16-bit LFSR to produce noise, whose bit-depth and volume are configurable via an AND of the low 8 bits of the LFSR with a variable. Then I filled the NMI with enough NOPs to get a fully used up VBlank time, and there really was no audible effect on the sound, especially if the noise was more than 1-bit.
And then I made a wavetable generator, and added a software "clock division" so that the square wave from the $AA sample byte could always be inaudible at rate F. The problem with that is that DMC IRQs don't happen often enough so the 8-bit division doesn't produce too many useful frequencies. It's slightly better when a square wave is played because that only takes two steps.
Now I'm not sure if the clash with OAM DMA can be solved by using rate E (If I'm not mistaken this means an IRQ happens every 576 CPU cycles) and aligning your write to $4014 so that it happens right after an IRQ and therefore has enough time to finish without affecting the sound at all.
User avatar
Bregalad
Posts: 8055
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Wavetable via $4011 is it possible?

Post by Bregalad »

Yeah I see the problems with this, and so I made a 16-bit LFSR to produce noise, whose bit-depth and volume are configurable via an AND of the low 8 bits of the LFSR with a variable. Then I filled the NMI with enough NOPs to get a fully used up VBlank time, and there really was no audible effect on the sound, especially if the noise was more than 1-bit.
I believe white noise is probably the waveform that will make the 60Hz buzz the less audible, since all frequencies are present in the noise. However, a constant frequency waveform of a non-multiple of 60 Hz will make it very audible.
Post Reply