DPCM playback rate does really correlate with note freqs

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
DPCM playback rate does really correlate with note freqs
by on (#49524)
I have posted that on 2A03.org 2 years ago http://2a03.org/forum/viewtopic.php?id=924. (all the data in the period column is from blargg APU reference, so I assume it's accurate ;) ) It shows the same info like in any docs that talks about DPCM, but I've added one crucial info: the obvious detuning of some speeds.

But recently I thought, "Well, it's surely all detuned, but those freqs are high and it's nearly impossible with a "timer" system to stay in tune in high freqs. Are those speeds the closest possible to tuned note frequencies?"

I took my Voyage200 and divided the 2A03 master clock (1.7897725MHz) by all the frequencies of the tuned notes, rounded it to the closest integer (so I get a value of what I'm supposed to put in the internal DPCM period register to be at the closest possible frequency) and I compared the result with the period of each speed.

The error is within -1 to 1, half of the time being 0.

Bananmos were not sure if "Nintendo designed certain values to be notes, or if it's just blind luck that they are". Well, there's strong evidence here that those periods were chosen according to how close it gets to some note's frequencies.

P.S.: If you really want to see all my calculations, I can post them on demand.

by on (#49687)
So if I read this correctly, it seems that they did try to get every DPCM value to be as close to the corresponding pitches as possible?

Pretty cool. But that kind of makes me wonder why Nintendo never bothered making use of that. There were zero first party games that used DPCM for melodic parts, correct? I know there were issues of cost, space, and efficiency regarding samples, but it seems a bit funny that they'd let some 3rd party companies essentially figure it out on their own (as I would assume), and do nothing with it themselves.

Also, thanks again for making that table. I've made use of it. :)

by on (#49698)
That's a great finding, and it seems logical, all the heavy DPCM usage by Sunsoft wouldn't have been possible if all pitches were just random, or they'd have to store dozens of samples instead of just 5/6 which wouldn't have been possible.

Anyway altough I like music in Sunsoft games, the DPCM bass often sounds detuned and "windy". If only Nintendo would have provided us another sample encoding instead...

by on (#49708)
Bregalad wrote:
Anyway altough I like music in Sunsoft games, the DPCM bass often sounds detuned and "windy". If only Nintendo would have provided us another sample encoding instead...


pff you can do that forever though, if only nintendo had given us 3 squares instead of two, or if only the triangle had volume

by on (#49709)
The only "if only" I care about is "if only Nintendo had run the audio path through the Game Pak connector on the NES as it had on the Famicom".

by on (#49805)
tepples wrote:
The only "if only" I care about is "if only Nintendo had run the audio path through the Game Pak connector on the NES as it had on the Famicom".


yes this one is valid, though at least we got detachable controllers
Re: DPCM playback rate does really correlate with note freqs
by on (#49821)
~J-@D!~ wrote:
Bananmos were not sure if "Nintendo designed certain values to be notes, or if it's just blind luck that they are". Well, there's strong evidence here that those periods were chosen according to how close it gets to some note's frequencies.

Actually it was Memblers who wrote that doc, not Bananmos ;) Anyways, cool that somebody actually bothered to try this out.

by on (#57380)
I know this is an old topic but that link is bad. does anyone have those freqs/maths for dpcm tuning? could you post.

thanks in advance.

by on (#57396)
tmro wrote:
I know this is an old topic but that link is bad. does anyone have those freqs/maths for dpcm tuning? could you post.

thanks in advance.
A2O3 Homepage wrote:
GENERAL NOTICE!

I'm sad to say that due to a mistake on my host's behalf the whole website account got deleted.
In practise this means we lost over a year of the most recent forum data and possibly some NSF files.
However, this does not mean the website isn't coming back. It will take a while so I ask for your patience.
In the meantime support and help is welcome at the official IRC channel #8bitpeoples (EFNet).

-Snowrobot
If their host didn't suck and Google Cache didn't crap out, it might have been recoverable. One more reason to have your own hosting instead of relying on unreliable fucks. :wink:

by on (#57407)
Keep a local mirror of files on your host. You should never rely on a host for anything but the server availability (and if they are unable to deliver on that, simply switch hosts).

by on (#57408)
How often are the databases of wiki.nesdev.com and nesdev.com/bbs backed up?

That said, as soon as someone comes up with a test ROM to confirm the PAL frequency timings, I'll add the relative note frequencies to the wiki.

by on (#57428)
tepples wrote:
How often are the databases of wiki.nesdev.com and nesdev.com/bbs backed up?


I think you don't have to worry about that part. I think it's every day and kept for 30 days. Koitsu is doing a good job about it. And if you're that worry, I'm sure he could give us a backup anytime if that was the case but I'm not that worried compared to the last wiki server ;) Parodius do their job well, period.

by on (#57450)
I've always been concerned about the Wiki's well-being. It's one advantage I find for local text documents over it. How big is the database, if one wanted to keep his own copy?

by on (#57457)
blargg wrote:
I've always been concerned about the Wiki's well-being. It's one advantage I find for local text documents over it. How big is the database, if one wanted to keep his own copy?


That's a good question, I never checked the size. BUT for people that want a local copy, if you were not aware, there exist a local html version of the wiki here. It's the same thing as the wiki except static. I use a plug-in to extract the content. I update it once in a while. I thought it was a nice thing to have for people that sometime don't have access to the net but still want to see the wiki content. It can serve as a somewhat "poor man backup" if something goes very wrong: as long as you update the local version often.

There a way to ask the wiki for an xml version of the complete wiki that you can import in yours so there is always a way to get the content without having access to the DB. I was not aware of that when I moved the content... I would have saved time.

by on (#58909)
just FYI, the site is now back, and the data is still here.

by on (#92241)
Sorry for the bump, but there's good discussion here and I'd rather not clutter up the board with a closely-related topic. :)

I was wondering if someone can answer this question:
I'm curious about the gaps in the scale when downtuning. Know of any reasons it was designed that way?

How would you explain to a layperson what a "timer system" is, and why there are larger gaps up at the higher pitches? Is there a reason it starts off with a major scale and then eventually starts taking bigger leaps?

by on (#92243)
Well, there are some decisions in the 2A03 design that are extremely arbitrary. Take a look at the possible length counter values, for instance: http://wiki.nesdev.com/w/index.php/APU_Length_Counter.

I don't think there's really a good explanation for the DPCM frequencies. I think they're just frequencies somebody at Nintendo thought might be useful.

by on (#92256)
My wild guess about the larger gaps at the higher pitches is that there is less precision in the sample periods once it goes that high.

by on (#92418)
Tepples' totally right.

Here my GNU Octave code (can work in Matlab with few modifications):
Code:
0; % if you want to put in a m file
function hz = midi2freq(note)
  hz = 440 * 2 .^((note - 69) / 12);
end

nesfreq = 1.7897725e6;
dmcperiods = [0x36; 0x48; 0x54; 0x6A; 0x80; 0x8E; 0xA0; 0xBE; 0xD6; 0xE2; 0xFE; 0x11E; 0x140; 0x154; 0x17C; 0x1AC];

notes = [12*12; 11*12+7; 11*12+4; 11*12; 10*12+9; 10*12+7; 10*12+5; 10*12+2; 10*12; 9*12+11; 9*12+9; 9*12+7; 9*12+5; 9*12+4; 9*12+2; 9*12];

most_tuned_dmcperiods = round(nesfreq ./ midi2freq(notes));

fprintf("difference between original DMC periods and the most tuned possible DMC periods:\n")

disp( most_tuned_dmcperiods - dmcperiods)


Output:
Code:
difference between original DMC periods and the most tuned possible DMC periods:
  -1
  -1
   1
   1
  -1
   1
   0
   0
   0
   0
   0
  -1
   0
  -1
   1
   0


As you can see, they didn't get the most tuned possible values, but they're very close to it. And if you change the 'round' by 'floor' (simple truncation) it outputs:

Code:
difference between original DMC periods and the most tuned possible DMC periods:
  -1
  -1
   0
   0
  -1
   0
   0
   0
  -1
   0
   0
  -1
   0
  -1
   0
  -1

which shows that it is even closer to that algorithm.

by on (#92434)
Notice that all the values in dmcperiods are even. This means the counter is probably triggered by the APU clock, which is half the CPU clock. (Quietust traced the circuit, and it turned out that pulse, noise, and DMC period dividers are clocked by the APU clock.) So what happens when you round most_tuned_dmcperiods to the nearest even period? I don't know Octave, so I have no idea whether the following is working syntax:
Code:
most_tuned_dmcperiods = 2 * round(nesfreq ./ (2 * midi2freq(notes)));

And there's an exact formula for nesfreq: 315000000/176

by on (#92458)
You know Tepples, Octave is really like Matlab, with just less restrictions on the language and of course, Octave is not backed with powerful toolboxes; nevertheless, you should apt-get installthat, and also some useful packages like octave-control and octave-signal.

And yeah, you're right again:

Code:
0; % if you want to put in a m file
function hz = midi2freq(note)
  hz = 440 * 2 .^((note - 69) / 12);
end

nesfreq = 315000000 / 176;
dmcperiods = [0x36; 0x48; 0x54; 0x6A; 0x80; 0x8E; 0xA0; 0xBE; 0xD6; 0xE2; 0xFE; 0x11E; 0x140; 0x154; 0x17C; 0x1AC];

notes = [12*12; 11*12+7; 11*12+4; 11*12; 10*12+9; 10*12+7; 10*12+5; 10*12+2; 10*12; 9*12+11; 9*12+9; 9*12+7; 9*12+5; 9*12+4; 9*12+2; 9*12];

most_tuned_dmcperiods = 2 * round(nesfreq ./ (2 * midi2freq(notes)));

fprintf("difference between original DMC periods and the most tuned possible DMC periods:\n")

disp( most_tuned_dmcperiods - dmcperiods)


Output:
Code:
difference between original DMC periods and the most tuned possible DMC periods:
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0
   0


So now it's apparent that it really correlate with notes, no doubts. That wasn't random at all.

by on (#92469)
So what about the "gaps" after the first several chromatic pitches? How many cents off are they? (Would the best case for the skipped pitches be really bad?)

by on (#92472)
Data is posted on the (old) 2A03.org forums, but since it has proved instable, I'll post the results here, and recalc them to be sure, posting at the same time my GNU Octave code to get that data, so anyone can verify how the result was obtained.

Code:
0; % if you want to put in a m file

function hz = midi2freq(note)
  hz = 440 * 2 .^((note - 69) / 12);
end

% an helper
function notestruct = make_notestruct(octave, scale, cents)
  notestruct = struct("octave", octave, "scale", scale, "cents", cents);
end

% note that it can output an invalid MIDI notes (values outside 0~127)
% as well as non integer values.
function midinote = freq2midi(freq)
  midinote = log2(freq ./ 440) .* 12 + 69;
end

function notestruct = midi2notestruct(midinote)
  closestnote = round(midinote);
  oct_offs    = floor(closestnote/12);
  closestnote = closestnote - oct_offs*12;
  octave      = oct_offs - 1;
  scale       = closestnote;
  cents       = (midinote - oct_offs*12 - scale) * 100;

  notestruct = make_notestruct(octave, scale, cents);
end

function str = scale2disp(scale)
   scaledisp = ["C";"C#";"D";"D#";"E";"F";"F#";"G";"G#";"A";"A#";"B"];
   str = scaledisp(scale+1);
end

nesfreq = 315000000 / 176;
dmcperiods = [0x36; 0x48; 0x54; 0x6A; 0x80; 0x8E; 0xA0; 0xBE; 0xD6; 0xE2; 0xFE; 0x11E; 0x140; 0x154; 0x17C; 0x1AC];

dmcfreqs = nesfreq ./ dmcperiods;

dmcmidi = freq2midi(dmcfreqs);

dmcnotes = midi2notestruct(dmcmidi);

fprintf("DMC period  octave     scale   cents\n");
fprintf("-----------------------------------------\n");
for i=1:length(dmcperiods)
  fprintf("0x%03X       %2d        %2s       %+2.6g\n", dmcperiods(i), ...
                                                        dmcnotes.octave(i), ...
                                                        scale2disp(dmcnotes.scale)(i), ...
                                                        dmcnotes.cents(i));
end

Results:
Code:
DMC period  octave     scale   cents
-----------------------------------------
0x036       11         C       -17.8827
0x048       10         G       -15.9277
0x054       10         E       +17.2014
0x06A       10         C       +14.4778
0x080        9         A       -12.0177
0x08E        9         G       +8.28576
0x0A0        9         F       +1.66859
0x0BE        9         D       +4.15558
0x0D6        9         C       -1.77808
0x0E2        8         B       +3.76755
0x0FE        8         A       +1.56068
0x11E        8         G       -3.8633
0x140        8         F       +1.66859
0x154        8         E       -3.28682
0x17C        8         D       +4.15558
0x1AC        8         C       -1.77808

by on (#92485)
I don't have octave, but I wrote a similar python program to answer the question I was asking. What I wanted to know was what are the best-fit values that could have been used for any given note.

http://rainwarrior.ca/projects/nes/dpcm_freqs.py

Code:
DMC   Octave   Note   Cents       
-----------------------------------
0x002 16       A      -12.01769334
0x004 15       A      -12.01769334
0x006 15       D      -13.97269421
0x008 14       A      -12.01769334
0x00A 14       F      +1.66859279
0x00C 14       D      -13.97269421
0x00E 13       B      +19.15640019
0x010 13       A      -12.01769334
0x012 13       G      -15.92769507
0x014 13       F      +1.66859279
0x016 13       D#     +36.66436429
0x018 13       D      -13.97269421
0x01A 13       C      +47.45464489
0x01C 12       B      +19.15640019
0x01E 12       A#     -0.28640807
0x020 12       A      -12.01769334
0x022 12       G#     -16.97310284
0x024 12       G      -15.92769507
0x026 12       F#     -9.53070947
0x028 12       F      +1.66859279
0x02A 12       E      +17.20139932
0x02C 12       D#     +36.66436429
0x030 12       D      -13.97269421
0x032 12       C#     +15.35487893
0x036 12       C      -17.88269594   *****
0x038 11       B      +19.15640019
0x03C 11       A#     -0.28640807
0x040 11       A      -12.01769334
0x044 11       G#     -16.97310284
0x048 11       G      -15.92769507   *****
0x04C 11       F#     -9.53070947
0x050 11       F      +1.66859279
0x054 11       E      +17.20139932   *****
0x05A 11       D#     -2.24140894
0x060 11       D      -13.97269421
0x064 11       C#     +15.35487893
0x06A 11       C      +14.47776118   *****
0x072 10       B      -11.48571034
0x078 10       A#     -0.28640807
0x080 10       A      -12.01769334   *****
0x086 10       G#     +8.67527811
0x08E 10       G      +8.28576325    *****
0x098 10       F#     -9.53070947
0x0A0 10       F      +1.66859279    *****
0x0AA 10       E      -3.28681671
0x0B4 10       D#     -2.24140894
0x0BE 10       D      +4.15557666    *****
0x0CA 10       C#     -1.87147264
0x0D6 10       C      -1.77807702    *****
0x0E2 9        B      +3.76755176    *****
0x0F0 9        A#     -0.28640807
0x0FE 9        A      +1.56068253    *****
0x10E 9        G#     -4.19640980
0x11E 9        G      -3.86329747    *****
0x12E 9        F#     +1.89661947
0x140 9        F      +1.66859279    *****
0x154 9        E      -3.28681671    *****
0x168 9        D#     -2.24140894
0x17C 9        D      +4.15557666    *****
0x194 9        C#     -1.87147264
0x1AC 9        C      -1.77807702    *****
0x1C4 8        B      +3.76755176
0x1E0 8        A#     -0.28640807
0x1FC 8        A      +1.56068253
-----------------------------------


Does it shed any light on why they picked the particular notes they did? I dunno, by this the choices still look kinda arbitrary to me.

by on (#92486)
Musically the note choice makes a fair amount of sense-

The entire Ionian octave at the bottom.
Most of the next octave, missing the 3rd and 7th scale degrees
The major triad of the next octave up
The root scale degree at top.

Because any desired detune and transposition can be encoded when the sample is made, this allows any song to play notes over most of two octaves in Ionian or Dorian modes.

Is it be as good as a fully programmable divisor as on the triangle and pulse wave channels? Obviously not. Would other decisions that only used 4 bits for specifying period make more sense? Yes; I think including one octave of a full chromatic scale at plus a few higher notes would probably have been a better design. But I think this is far more explicable than the restrictions on noise frequency or the duplicate pulse duty (1/4 and 3/4 have the same sound).

by on (#92489)
You can build large samples at any frequency, at whichever samplerate from the table is good for you, but interestingly it doesn't seem to be based around doing that kind of thing. In that sort of situation it would be more useful to keep your samplerates in tune with each other, rather than trying to keep them in tune with an arbitrary standard like A440 (which is clearly in use here). Note that only the lowest two Cs are exactly an octave apart; the rest are jittered up and down trying to match to A440 rather than matching each other.

It's not particularly good for short looped samples either, since the sample length is 16n+1 bytes. A 1 byte sample would be too quiet to be useful. If it was an even 16, with 16 bytes you could make a decent DPCM triangle 3-7 octaves down from the frequencies mentioned, and play it all over that major scale. However, it's 17 bytes, which detunes it by 16/17... which kind of makes the scale mostly pointless (unless you want to tune your square/triangle at A=414hz). Kinda seems like it's not intended for that either. The only place I've seen this tried was in Rob Hubbard's The Immortal, which used a 17 byte bass, but doesn't really bother to compensate for the 16/17 detune, just kinda uses it sparingly, and accompanies it with vibrato generally. 16/17 is most of a semitone off, so it's still close enough to be usable. (So for example, in track 2 he uses DPCM pitch 2, an E frequency, to play a tone close enough to E-flat to be acceptable.)

Honestly I think they're rather poorly chosen for any purpose. Sunsoft tried to make do with them, and they do an okay job, but you'll notice their basslines jump in octaves all the time and they bottom and top of the octave really never sound in tune with each other. They just live with the approximation. Note that they for the most part don't use the low samplerates where that pre-fab major scale resides, because they'd sound too muddy at such a low samplerate anyway. They're forced to use the more poorly tuned higher ones, and do the tuning via multiple samples.


If you ask what my guess is, the designer originally presumed sample lengths wouldn't have the +1, and designed the scale for short looped samples in an A440 tuning. After the first octave, just chose arbitrary pitches; F and G are good because they're in the middle but also an important scale note, I guess trying to space out the higher frequencies so there are more to work with? Other ones are just haphazardly chosen, in my opinion. Maybe they were chosen early on, intended for a different purpose, and then as a feature it was de-emphasized later on in the design process and it didn't ever get a rework.

by on (#92491)
Sure; they evidently knew just enough to make decisions for the audio hardware that are correct at first glimpse and inadequate when a person who knows more about the situation looks at it. See also: the looped noise mode's interactions with the restrictions on noise rate.

by on (#92493)
At least on the Game Boy, looped noise makes acceptable C, D, F, and G# in each octave, which allows for passable covers of the Super Mario Bros. 2 and the end of "Wish" by Nine Inch Nails (which uses a D, C, G#, F descending scale).

by on (#92494)
On a whim I decided I would try to make an in-tune 17-byte looped DPCM sample. Or, well, at least as in tune as is possible on the NES.

http://rainwarrior.ca/projects/nes/lately_tuned.nsf

So, this is a short tune with a 17-byte looped DPCM sample. It makes sure to use all 16 possible pitches. The pitch tables used for the other channels have been custom built with A-flat = 440hz * 16 / 17, to compensate for the detune due to sample length.

As you can hear, for the high notes especially, the DPCM really doesn't have a lot of resolution to get pitches accurate anyway. I'm bent over as far as I can to try and sound in-tune with the DPCM's chosen scale, and even with this the results aren't particularly magical.

The NES has never really been an instrument for precision tuning anyway, I suppose, but if I did this correctly, this is a best-case example for DPCM tuning.

by on (#92497)
Just to point out how bad this tuning scheme actually is, check out the four Cs:

Code:
0x036 12       C      -17.88269594
0x06A 11       C      +14.47776118
0x0D6 10       C      -1.77807702
0x1AC 9        C      -1.77807702


Note that 0x036 and 0x06A are a total of 31 cents apart, because one rounds up and the other down! This is almost comic. You cannot use the DPCM's pitches to play an in-tune octave, except between the lowest two (which are the least likely to be used since the samplerate is so low down there).

It would have been much better to just forget about trying to hit the A440 scale and make these power of 2 multiples of each other. Sunsoft games could have had much nicer tuning in their basslines.


Also, Tepples, I'd be interested in hearing that GB Wish cover, if you have a link.

by on (#92506)
rainwarrior wrote:
Also, Tepples, I'd be interested in hearing that GB Wish cover, if you have a link.

I never made it. It never got farther than a quick experiment playing around in a tracker, unlike my cover of SMB2 underground. This is actually from a tracker, and the pitches aren't exact, though the waveforms are.

by on (#94079)
I was building a table of the PAL frequencies for the wiki DMC page and I noticed this also fits the same pattern of picking the same set of notes and their closest match to A440, with two glaring exceptions. (The following table lists potential closest matches to A440 among available pitches.)

Code:
DMC   Octave   Note   Cents       
-----------------------------------
0x032 12       C      -12.2401718  ******
0x034 11       B      +19.8595941
0x038 11       A#     -8.43865057
0x03C 11       A      -27.8814588
0x03E 11       G#     +15.3516834
0x042 11       G      +7.11431267  ******
0x046 11       F#     +5.24763556
0x04A 11       F      +9.04321714
0x04E 11       E      +17.9045932  ******
0x054 11       D#     -10.3936514
0x058 11       D      +9.06931353
0x05E 11       C#     -5.11936612
0x062 11       C      +22.7354429  <- ???
0x064 11       C      -12.2401718  <- Why not this?
0x06A 10       B      -13.1172895
0x070 10       A#     -8.43865057
0x076 10       A      +1.21559666  ******
0x07E 10       G#     -12.3486523
0x084 10       G      +7.11431267  ******
0x08C 10       F#     +5.24763556
0x094 10       F      +9.04321714  ******
0x09E 10       E      -4.14964192
0x0A6 10       D#     +10.3399382
0x0B0 10       D      +9.06931353  ******
0x0BC 10       C#     -5.11936612
0x0C6 10       C      +5.15931180  ******
0x0D2 9        B      +3.29263470  ******
0x0DE 9        A#     +7.08821628
0x0EC 9        A      +1.21559666  ******
0x0FA 9        G#     +1.44611430
0x10A 9        G      -5.95166671  <- Why not this?
0x114 9        F#     +30.1579077  <- ???
0x118 9        F#     +5.24763556
0x12A 9        F      -2.61496866  ******
0x13C 9        E      -4.14964192  ******
0x14E 9        D#     -0.05789507
0x162 9        D      -0.73940420  ******
0x176 9        C#     +4.11390403
0x18E 9        C      -3.56228876  ******


Did they really get it wrong like this when building the 2A07, or is the information on the wiki incorrect? If I had a PAL NES to test I'd verify it myself, but as I can't, can anyone else verify it for me?

by on (#94082)
I believe Quietust had said that the tables didn't exist as a conventional LUT but were instead the result of a tuned LFSR. I don't know what kind of magic is involved in packing short LUTs into even smaller LFSRs, but maybe that's why?

by on (#94092)
It's ordinarily a 1:1 conversion from binary to Galois domain. Either there is a typo on the wiki or there was a typo inside Nintendo or Ricoh. Only a test ROM would distinguish these cases. Should I be the one to make it?

by on (#94103)
Made this quickly in FamiTracker:
dpcm_pitch_test.nsf (dropbox link removed, file lost)

It's just a 17-byte looped triangleish bass. An audio recording of this from a PAL NES should be enough to measure the wavelength to determine the correct values.[/url]

by on (#94105)
tepples wrote:
It's ordinarily a 1:1 conversion from binary to Galois domain.
Tepples, do you have a link I could read about this? Ideally without involving graduate-level math?

by on (#94112)
Clocking an LFSR is equivalent to multiplying by x in a finite field. Probably the most accessible description of how multiplication works in a finite field, the one I read when first trying to understand how Reed-Solomon error correction works, is "Finite field arithmetic" on Wikipedia. It's not graduate math, but it might be undergraduate math. And if you do anything with RS codes, you'll have to wrap your head around it sooner rather than later.

An 8-bit LFSR operates in the finite field GF(256). (Here, I use "integer" for an ordinary whole number and "bit pattern" for an element of a finite field.) What you're looking for is the number that when multiplied by 00000010 n times results in 00000001, so because 00000010 to the 255th power is 00000001, you'll want to take 00000010 to the power of (255 - n).

Please let me know which sentence in this post was the first sentence that you failed to understand.

There are ways of calculating the powers of 00000010. One is to build a lookup table from integers n to bit patterns 00000010^n. Building this table requires O(n) multiplications, but the resulting "log table" can be reused at O(1) each for multiple entries, such as the 32 entries in the length counter LUT or the 16 entries in the noise or DMC period LUT. The RS module in a typical QR barcode library generally uses this method for GF(256). The other, which is faster but may be hard to understand for people who don't know finite fields well, is exponentiation by squaring. This requires only O(log n) multiplications per table entry that's actually used.

by on (#94140)
tepples wrote:
What you're looking for is the number that when multiplied by 00000010 n times results in 00000001, so because 00000010 to the 255th power is 00000001, you'll want to take 00000010 to the power of (255 - n).

Under what conditions is (00000010 ≅ x)²⁵⁵ ≡ 1 mod 256? 256 isn't prime, and I don't see a reducing polynomial mentioned. If we need to find such a polynomial, how do we find both the reducing polynomial and the seed at the same time? If we don't, what's going on?

Quote:
There are ways of calculating the powers of 00000010. One is to build a lookup table from integers n to bit patterns 00000010^n. Building this table requires O(n) multiplications, but the resulting "log table" can be reused at O(1) each for multiple entries, such as the 32 entries in the length counter LUT or the 16 entries in the noise or DMC period LUT.

Am I mistaken in thinking that there is only one set of taps (the reducing polynomial) and the LFSR just loaded in a seed and then was clocked N times?

by on (#94155)
lidnariq wrote:
Under what conditions is (00000010 ≅ x)²⁵⁵ ≡ 1 mod 256?

Under any reducing polynomial with x^8 as the highest order term.

Quote:
If we need to find such a polynomial

The taps determine the reducing polynomial.

Quote:
Am I mistaken in thinking that there is only one set of taps (the reducing polynomial) and the LFSR just loaded in a seed and then was clocked N times?

There exist more than one primitive reducing polynomial for each field size, and some field sizes need more than two taps. That is, there exist more than one valid set of taps for each LFSR length. One can find tables of such polynomials for each order. But even though (say) QR and DataMatrix use different polynomials, people speak of "the" GF(256), or "the" finite field with 256 elements, because there's an isomorphism between any two fields of the same order with different polynomials.

by on (#94187)
tepples wrote:
Quote:
Am I mistaken in thinking that there is only one set of taps (the reducing polynomial) and the LFSR just loaded in a seed and then was clocked N times?

There exist more than one primitive reducing polynomial for each field size, and some field sizes need more than two taps. That is, there exist more than one valid set of taps for each LFSR length. One can find tables of such polynomials for each order. But even though (say) QR and DataMatrix use different polynomials, people speak of "the" GF(256), or "the" finite field with 256 elements, because there's an isomorphism between any two fields of the same order with different polynomials.

Sorry, what I meant was, "In the silicon, is each LUT one specific seed and one specific set of taps and entry N is contents of the LFSR when clocked N times?" You explained how to find the seed given the taps; is there an method for finding the taps?

by on (#94191)
lidnariq wrote:
In the silicon, is each LUT one specific seed and one specific set of taps and entry N is contents of the LFSR when clocked N times?

In the silicon, there is only one set of taps, used for all LUT entries. Each entry is 00000010^(INT_MAX - n).

Quote:
You explained how to find the seed given the taps; is there an method for finding the taps?

The taps depend on the length of the LFSR. A table of taps for each length can be found in any book on finite field theory, and there are online tools to find them. For most lengths, two or four taps are used. For example, the polynomial x^8 + x^4 + x^3 + x^2 + 1 is primitive, and it leads to an 8-bit 4-tap LFSR. That polynomial corresponds to the entry 1 0 0 0 1 1 1 0 1 when you tell the tool to generate "Primitive polynomials over GF(2), n = 8".

by on (#95316)
Sorry for the bump. Got back to a question from bucky o'hare.

Well, why did they choose these notes? Well, C-D-E-F-G-A-B-C (speed 0-8) is the major C scale, and C-E-G-C is a major C chord (speed 12-15), but what about C-D-F-G-A-C (speed 8-12) ?

First thing to note is that it's a kind of a scale, the pentatonic scale (F pentatonic scale to be more precise). The special thing about it is that it doesn't have any semitones or tritones, so it always sounds good. I noticed that the church's bells are C-D-F-G-A-C at the one near my girlfriend's parents, and it's never dissonant.

More interesting aspect however, is that C-D-F-G-A-C is actually the Slendro scale used in some oriental music (indonesian gamelan music). That might be why these notes were used.

EDIT: removed a non-intentional smiley.

by on (#95346)
Yeah, they could have been going for a pentatonic scale, maybe, though I don't know why they'd pick that particular version of it.

I don't think Slendro is a reasonable candidate, though. Its tuning is very different from 12-TET, and we've already determined that the DPCM frequencies are all tuned to A-440 12-TET. It only looks like the pentatonic scale when you approximate it in 12-TET.

by on (#97124)
I was finally able to verify the PAL DPCM frequencies from a recording jrlepage made for me with this PAL NES. The table on the wiki is correct, which means those two frequencies which don't match the tuning scheme are actually that way in the hardware. So, I guess they made a mistake when building the 2A07, which is quite interesting.