Octaves

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Octaves
by on (#26609)
Ok, I'm making a music engine, and I have it use one single table for the periods to use for each note of the scale. However, this table only has the lowest possible octave. The idea is that I have the lowest octave (so each period has the most resolution), and then I shift the octave up to the target octave, somehow. I've tried multiple methods to do this, but some notes distort as the octave gets higher, but others don't.

For example, A (the music note A, I mean). A can be either %10000000, or %01111111 (on register 2). Here's the weird thing: continually shifting %10000000 right will result in distortion (the pitch gets lower as the octave rises), but continually shifting %01111111 right will result in each octave being correct.

I would just like a way to shift octaves up without causing distortion, but I'm really not sure how to do it, other than fine-tuning each entry in the table until they don't distort.

by on (#26610)
Shift right, and then round based on the final carry value. Try a few examples manually to get your head around the logic.

by on (#26613)
Ah, thank you Tepples! This works better than what I was using. There's still distortion, but it's on really REALLY high notes, and at that point, I think it'd be pretty impossible to get each note exactly right.

Either way, now I'm shifting right, and just SBCing the period, without touching C. It seems to work just fine. When I was messing in SNDTEST, I needed to subtract one when C would be 0.

Thanks again! :)

by on (#26615)
Also you should do your period table 16-bits wide (at least 11-bit) to reach lowest possible notes too. Shifting left will work, but you will lose precision.

by on (#26623)
Bregalad wrote:
Also you should do your period table 16-bits wide (at least 11-bit) to reach lowest possible notes too. Shifting left will work, but you will lose precision.

Yeah, that's exactly what I've been doing, for that exact reason.

My note period lookup tables are all at the lowest possible octave. The only shifting I ever do is to the right.

by on (#26628)
For those of us who can't tell absolute pitch, couldn't you slightly adjust your lowest frequency so that the higher frequencies can be represented with less error (rounding)? It seems like there would be some sweet spots.

by on (#26629)
Gah! If you screw up the musical scale, you get the utterly dissonant music of Megaman 4. I hope nobody makes that mistake again.

by on (#26633)
I meant to transpose the scale slightly, hence my pitch about those of us who can't tell absolute pitch. All the ratios between notes would stay the same.

by on (#26639)
Ideally, ratios between notes should vary based on the key ("just intonation"). Even the idea of a fixed 2^(1/12) ratio between semitones ("equal temperament") is an approximation.

by on (#26644)
Well, I throught it was the other way arround. Anyway the difference between both is rather small, and the frequency registers in the NES are aproximative enough so that will bypass the difference.
Wind and string instruments are manually tuned, so I guess they give aproximative tones anyway. Each note in a piano is maually tuned, so I guess a piano can be tuned either way. The only way to know the real trurth would be the to known the ratio between the lenght of the pipes of a real organ.

by on (#26647)
Yeah, either way, although the distortion is a LOT less severe, it's still there, but the distorted notes are so high, I doubt I'd ever have anything that extensively uses them.

Also, those high pitches are actually *impossible* to get accurate, because there isn't enough resolution at those frequencies. I.E., [pitch] slightly too low, and [pitch+1] is slightly too high.

Anyway, the octave range that 99% of my songs end up using anyway is in tune, without distortions, so it should be fine.

To get an idea of what I'm talking about, take a pitch at the lowest possible octave, and shift it right 5 times, subtracting 1 when C is 0 after the shift. This is where the distorted pitches start happening, and it's pretty high, and the distortion is always the pitch getting too high.

Either way, if it's a huge problem, I can keep a seperate table which will indicate which notes need to be fine tuned (by 1) when the 5th shift occurs. (Edit:) Actually, I just tried this method, and it's too much trouble for what it's worth. There just isn't enough resolution to get everything exactly right, so there's pretty much no way to absolutely completely fix it.

by on (#26849)
Ok, I just improved the octaves even more.

My previous implementation was "shift right, subtract if !carry, repeat"
And that caused distortion such that all notes above a certain (high) octave were too high.

My new implementation is "shift right, repeat, subtract if !carry".
Basically, I only subtract once, and it's after all of the shifting is done. This seems to yield better results.

So yeah, I was doing the rounding wrong. It's much better now.