Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /storage/content/49/145849/famitracker.com/public_html/forum/classes/dbHandler.php on line 29
So, I'm sure it's common knowledge that, especially the high end of the pitch range, some notes come out a little flat. I imagine that this is a result of the fact that the pitch goes up as the value of the frequency register shrinks, but as the values get smaller, the rounding errors become more noticeable.
Now, accordion to the wiki, the ratio of the frequencies between two adjacent semitones is 1:2^(1/12) (at least for the 2A03/etc. frequency register). This is close to true for all the values there, but, of course, there are rounding errors because the value of the frequency register is always an integer.
Even so, though, multiplying one register value by 1/(2^(1/12)) doesn't always yield the value of the next semitone up. For instance, E-5 apparently has a register value of 0x54. Converting that to decimal, multiplying by 1/(2^(1/12)), rounding down to the nearest integer and converting back to hex again yields 0x4F, but the next semitone up apparently has a register value of 0x50. What gives here?
In the end, Pxx commands can be used to help the situation. For instance, I've found that F#5 sounds more in tune when accompanied by P81. I seem to recall someone once having made a forum post that contained some information about which pitches should take Pxx commands of which values to sound better in tune. Am I recalling a dream, or does such a handy guide exist somewhere? If so, can it be re-posted here or to the wiki?
I think the ratio applies to frequencies only. Calculation of registers requires subtraction by 1, so double the register is not exactly half the frequency, but pretty close; same goes for semitones. Hope that makes sense.
let c = CPU clock rate / 16
let x = register value
freq(x) = c / (1 + x)
you want to compare the ratios of 1+x, not of x.
Also, the tuning is not done so that all semitone steps are as close to a semitone as possible; this would let errors accumulate and octaves would become detuned. The tuning is simply done by finding the closest match to a tone in the A440 12-TET scale (i.e. rounding to the nearest). This overall keeps the tuning more stable.
I've attached a table with the tuning used in famitracker. The first column is the period value and equivalent frequency, followed by the correct frequency for that semitone and the difference between both. You can see that the error increases as the pitch goes higher, due to less resolution.
Rounding to nearest integer is used which causes some notes to be below the target frequency, which I guess is the reason some tones are perceived as flat.
With that information and enough tweaking, I reckon octaves 5 and higher will actually be usable for non-sound effect purposes. Thanks for sharing that, jsr!
[quote=rainwarrior]let c = CPU clock rate / 16
let x = register value
freq(x) = c / (1 + x)
you want to compare the ratios of 1+x, not of x.[/quote]
Okay, I've seen this quite a few times now when people are discussing the wavelengths and their relationships to the register values and I've been ignoring it, but I have to assume there's some logic behind why it would be 1 + x, since it's so commonly used. Can someone please explain this to me? Is it that, while the register values level off at 8, the "first" register value would be 0? Like, what is the NES doing when it reads a register value? I don't know anything about programming, really, but mathematical precision is extremely important to me in music and I'd hate to think everything I've done so far has been out of tune. It doesn't sound out of tune to me, but maybe my ears just aren't sensitive enough. I'd think at least the octaves would be throwing me off...
I can't answer your question, but if you're in doubt about the formula, a fairly easy way to confirm a frequency is to export a wav from an nsf and check the wavelength in a wav editor. More accurate than just listening.
mayazimmerman, it has to do with how you compare your counter to the register. The basic number comparisons are < (less than), > (greater than), <= (less than or equal), >= (greater than or equal).
If R is the register value, let's say 5 in this example, and I is our counter. If we reset the counter to 0 and flip the square wave every time I >= R, you get:
I = 0, 1, 2, 3, 4, 0, 1, 2, 3, 4...
See that I's sequence has 5 steps in it. When I reaches 5, then 5 >= 5 and I gets reset to 0.
Alternatively, what if we do it when I > R?
I = 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5...
Now we reset to 0 when I reaches 6, because 6 > 5. The sequence has 6 steps in it now, and this is where you would get something like that 1 + x idea.
When you program for computers, you get used to making choices between < and <= comparisons; you learn to know which one will get you the sequence you want. When you make a mistake, it's often referred to as an "off by one" error.
There are other ways I could demonstrate how sequences can be one longer or shorter, but the < vs <= choice is one that you see a lot in programming. For the 2A03, they probably had a particular counter circuit design that was of the "1 + x" variety, and they used it. Maybe it was simpler or used less transistors than "x", or maybe the designer just liked this particular type of counter.
I dunno. If I was given the choice, I would have preferred just "x", since this allows you to do things like convert octaves by multiplying by 2, but the engineer who designed it probably didn't think this was important.
[quote=jsr]I've attached a table with the tuning used in famitracker. The first column is the period value and equivalent frequency, followed by the correct frequency for that semitone and the difference between both. You can see that the error increases as the pitch goes higher, due to less resolution.[/quote]
I think deviation in cents should be added to the table, because it gives a much better idea of how far off the note really is. A difference of 10 Hz might be inconsequential for a high note, but would result in a different note entirely for a low note. (Of course, all the low notes are pretty accurate until you hit the bottom of the NES's range; I'm just making the point that cents are more useful than Hz.)