How to properly calculate sampled duty cycles for the DPCM?

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

Moderator: Moderators

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

How to properly calculate sampled duty cycles for the DPCM?

Post by FrankenGraphics »

The goal is to get a tone equal to the frequency of E-3.

According to the famitracker wiki, e3 uses a value of $152 for its frequency. According to the formula on the same page, (1789772.727 / 16) / (Frequency register + 1), that'd be a frequency of ~726.368, which according to my synthesizer and this chart is almost an F#. So i know it ought to be wrong already, but i used audacity to generate a duty of that frequency. When i import the duty, loop it, and play it, it plays back as an "almost B" with the frequency set to "15".

What am i doing wrong here? I must've misunderstood something fundamental.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by tepples »

The values in that table are in hexadecimal. Hexadecimal 152 is decimal 338, and (1789772.727 / 16) / (338 + 1) equals 329.97 Hz. This is a perfect fourth below A440, or obviously an E.

But then the pulse wave is fixed at 16 CPU cycles per period unit. The DPCM channel isn't; it depends on the wave data. The output frequency depends on both the period table index value written to $4000 and the wavelength (number of samples per period) of the waveform in the wave data. How are you generating the wave data?
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by FrankenGraphics »

Thanks! I can't believe i missed that.

The process so far has been opening Audacity, then in the menus: generate > tone > (enter the frequency), ok.

then snip out one perfect duty, export it as .wav, and import into famitracker. Even with the new frequency, it yields a B.

If i add several duties in a string (which seems a little wasteful?), i do get the intended frequency but with a looping stutter. It also looks more lite a triform than a square in the oscilloscope view and sounds the part.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by tepples »

FrankenGraphics wrote:then snip out one perfect duty, export it as .wav, and import into famitracker. Even with the new frequency, it yields a B.

If i add several duties in a string (which seems a little wasteful?), i do get the intended frequency but with a looping stutter.
Looping is tricky with DPCM because the length register requires all waves to be 128 * n + 8 samples long. Practically, you need to use a 136-sample loop (which gives the key of B major), a 264-sample loop (which requires tuning everything else up 50 cents or a quarter tone), or an unlooped wave with several periods (which is what Sunsoft games do).
FrankenGraphics wrote:It also looks more lite a triform than a square in the oscilloscope view and sounds the part.
That's slope overload, one of the hard-to-avoid characteristics of delta modulation.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by FrankenGraphics »

Oh i see. So the sample rate would hypothetically need to be higher and/or the dynamic width of the waveform narrower for the slewed slopes to have less impact on something as abrupt as a square, since we can only increment/decrement one unit at a time.

In this case, i'm using E-3 and F-3 (so only two notes) for a quiet drone which the rest plays against. Or that's the idea, currently makeshifted with the mmc5 extension. I guess the sunsoft method is best for notes with decay, for the same reason i get the stutter when looping. Maybe detuning the whole composition as a setup phase would work best here, even if it may result in discomfort between different songs.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by tepples »

Would you be willing to post your module publicly so that one of us can try to show you how to replicate using the DPCM channel the drone that you have made using an expansion chip?

If you prefer real-time interaction, there's a channel for that in the FamiTracker users' Discord server. There's an invite link in the Famicompo Pico announcement.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by FrankenGraphics »

Here's the file. :) Not a full length song, but something. The drone is on mmc5 pulse 1.
Attachments
roman_chapel.ftm
(3.88 KiB) Downloaded 416 times
User avatar
za909
Posts: 248
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

Re: How to properly calculate sampled duty cycles for the DP

Post by za909 »

An incredibly limited solution is to use a 0×16+1 byte sample to avoid the detuning to B major. Now you have a C major scale mapped to pitches 0-7 (8 continues with D' but then 9 gives you an F')
Attachments
1-byte dpcm.ftm
(7.54 KiB) Downloaded 416 times
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by FrankenGraphics »

That's pretty nifty, za909! Especially as there's plenty of popular modes that share notes with C major.

Progress!
By transposing the song 1 semitone down, i got enough notes to harmonize with the B major of a 17 bytes long sample, even if it needs to take a few byways. Thanks both, i believe this will work great. :)

Here's the same short loop but with with the mentioned changes.
roman_chapelDPCM.ftm
(7.07 KiB) Downloaded 424 times
If anyone is wondering, i'm planning to use famitrackers' driver as a secondary driver separate to the actual game, to be used in its own bank for menus, game over, etc. Then keep a leaner engine for when there's competing action. It warrants making sure nothing important is left in the RAM space the both drivers use and try to keep it overlapped between them, but should be fine.

At first i thought it was a little extravagant, but then i remembered that it isn't without its precursor. Metroid has a separate driver in each level data bank, even if they're the same and simpler.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by rainwarrior »

If you wanted it to be closer in tune, you could replace Famitracker's A440-based tuning table with one that more closely matches the DPCM's accidental 16/17 detuning of A440 system. Well, in this case, 16/17 + 100 cents, since the 16/17 is already being approximated by a semitone shift.

If you want to make something that works in both NTSC and PAL you'd need separate tuning tables, though Famitracker's driver does have that.

There's an example tune I made a long time ago to demonstrate this, including a script to generate the tuning table:
http://famitracker.com/forum/posts.php?id=3424

There's an old thread on the topic of the apparently intended tuning of the DPCM frequencies, and also how they're bad at their goal, especially on PAL where two of the chosen frequencies seem to be off-by-one:
viewtopic.php?f=6&t=5473

Optimizing the tuning to match the very imprecise DPCM frequencies might be splitting a rather frizzy hair, though. There will be detuning no matter what while doing this, but replacing the tuning tables will at least centre that detuning.

My main complaint about the DPCM freqs is not actually that they made the mistake with loop lengths that adds an extra byte, but that it has so few octaves that are in tune with each other, so that looped or not you can't even count on that to be in tune, whether or not you adjust your other tuning tables.


BTW the one game that used looped 17-byte DPCM for a pitched instrument (The Immortal, Rob Hubbard) just took the "one semitone down is close enough to 16/17" approach:
https://www.youtube.com/watch?v=iXcnA_4OnkQ

(...also you can use longer looped samples, each length has a different detuning based on that +1 byte. 32/33, 48/49, etc.)
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: How to properly calculate sampled duty cycles for the DP

Post by lidnariq »

A few years ago I sat down and made DPCM triangle waves for every integer divisor (edit: except divisors that are multiples of 16. Those can't be represented, because there are no integers m, n just that 2·m=16·n+1 ). They're not too big, and they help compensate for the DPCM's stupid tuning table.

https://forums.nesdev.com/viewtopic.php ... 32#p154032
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by FrankenGraphics »

Lidnariq, these samples might prove invaluable to me. :beer:
After trying them on, building more a quite well rounded instrument with a decent tri volume in under or about 1k seems very doable, which isn't all that costly. Some ranges and some few notes will have to go, but that's not too much of a problem.

A side effect: The longer samples, if not looped, can act as short notes.
And all samples can be used as note stops in the same way.
Silencing a looped note will make a hard pop, so they're best for drones as-is, but just playing a one-shot sample won't pop.
rainwarrior wrote:BTW the one game that used looped 17-byte DPCM for a pitched instrument (The Immortal, Rob Hubbard) just took the "one semitone down is close enough to 16/17" approach
Cool to hear a song from the commercial era to use it!

I'm not too worried about some of the notes being a little honkey tonk (though some of the upper notes in my sample are unusable of course), as long as they don't play solo. The beating swell of the detune can sometimes act complementary, especially for the delta artifacts which go in and out. But the detuning can also get old quickly, so lidnariqs triangle library will be useful in that regard too.


Something i found interesting is that there seems to be some cancellation based, airy movement happening in between the alias noises of both the tri channel and the DPCM, presumably because the delta artifacts' phases clash asynchronously. You can control how much by using samples with more or less evident artifacts. It sort of reminds me of a rotary electric organ.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by rainwarrior »

FrankenGraphics wrote:Silencing a looped note will make a hard pop, so they're best for drones as-is, but just playing a one-shot sample won't pop.
In Famitracker, use the === note release instead of --- note cut. The former just halts the sound, the latter has an implicit return to 0, I think? (If I'm remembering correctly... at any rate a halt is technically possible and should not pop any worse than the triangle channel does when halted vs silenced. There may have been a workaround of playing a 'null' sample instead of note cut back before release was implemented?)

If not looping a sample, you are not really limited to integer divisions like this, you can use any pitch at all for that.

Re: timbre and volume variation, there's a lot of redundancy in the set, and if you pick samples with divisions that are close to each other they should be closer in sound as well. My quick script made no effort to do this, it was just taking whatever was specified last, I think, which probably always favours the highest divisor.
User avatar
RushJet1
Posts: 155
Joined: Wed Nov 10, 2004 10:17 pm
Contact:

Re: How to properly calculate sampled duty cycles for the DP

Post by RushJet1 »

When I tried making melodic waves on the DPCM channel I just resorted to medium-length triangle recordings that I then looped using Y commands.
Attachments
tis.ftm
(91.04 KiB) Downloaded 411 times
lidnariq
Posts: 11429
Joined: Sun Apr 13, 2008 11:12 am

Re: How to properly calculate sampled duty cycles for the DP

Post by lidnariq »

rainwarrior wrote:If not looping a sample, you are not really limited to integer divisions like this, you can use any pitch at all for that.
Yeah, that. The loops are really only important if you want looped/chip samples.
Re: timbre and volume variation, there's a lot of redundancy in the set, and if you pick samples with divisions that are close to each other they should be closer in sound as well. My quick script made no effort to do this, it was just taking whatever was specified last, I think, which probably always favours the highest divisor.
One thought that occurs to me now is that one could use an unbalanced waveform. Since this would rail to 0 or 126, it would allow a combination of triangle volume control as well as DPCM triangleish (somewhere between a conventional triangle wave and a pulse width wave) wave control.

Of course, you'd need separate samples for every combination of DPCM volume, triangle volume, and DPCM divisor wanted... would consume a lot of bytes awfully quick.
Post Reply