Vibrato

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Vibrato
by on (#147176)
I've been trying to add a vibrato to my music engine, and I finally nailed it. I had to reverse-engineer the famitracker method a bit.

It uses a frequency shift pattern of +3, +4, +3, 0, -3, -4, -3, 0. And you have to adjust alot less than you would think.
$4003 (lower 2 bits), $4002 (8 bits) -> 00 0000 0000

if > 10 0000 0000, then adjust 4002 by ($1c, $20, $1c, $10, $04, $00, $04, $10)
if > 01 0000 0000, then adjust 4002 by ($0e, $10, $0e, $08, $02, $00, $02, $08)
if > 00 1000 0000, then adjust 4002 by ($07, $08, $07, $04, $01, $00, $01, $04)
if > 00 0100 0000, then adjust 4002 by ($03, $04, $03, $02, $01, $00, $01, $02)
if > 00 0010 0000, then adjust 4002 by ($02, $02, $01, $01, $00, $00, $01, $01)
if < 00 0010 0000, then skip it.

And write only to 4002, each loop, or else it will retrigger the note.
That's a byte per V_blank, 8 bytes total = 8 V_blanks per loop.
Re: Vibrato
by on (#149388)
I finally finished the code for my music engine (version 4). And I think I have all the bugs out.

Here is a quick demo, if anyone cares to hear...it's the opening lines to Fur Elise, done with 6 different effects.
1-3 are different 'voices', 4 is vibrato, 5 is tremolo, 6 is a fade in envelope filter.

http://dl.dropboxusercontent.com/s/sulk ... muse3b.nes

Only the right button is functional in the demo.

Don't be surprised if I use a longer version of this as the demo song in a Mario Paint style music game, NES homebrew. :)
Re: Vibrato
by on (#155533)
Did you expand on MetalSlime's music engine, or did you write yours from scratch? The only reason I ask is because I'd be more than interested in trying to integrate this into my own game, which uses his engine.
Re: Vibrato
by on (#155554)
I studied Metal Slime's engine, and wrote a much simpler one for my first games. I've been refining it and adding features as I go. Currently, it has optional duty cycles, pitch bends, vibrato, tremolo (volume rise and fall), and volume envelope. I actually have not used any of the pitch bend features, but I really like being able to play a plain note and have it transition to a vibrato note.

It could be rewritten to work with Metal Slimes engine. basically you need to store the note frequency, and count frames, and index from a frequency adjustment table, and loop it. And you need to decide how to handle frequencies that are right on the edge of low byte being 00. Because adjusting the high byte will retrigger the note and that will sound like shit.

I don't know if I was clear there, you would be rewriting the low byte every frame (or every few frames) with slight adjustment.
Re: Vibrato
by on (#155559)
The MUSE engine, used for Driar and STREEMERZ, uses the pitch sweep registers ($4001 and $4005) to change the high byte of period without a phase reset. I think the idea is to set a sweep to increase or decrease the period at next frame counter update, write to $4017 to trigger a frame counter update immediately, cancel the sweep (write $08 to $4001 or $4005), and then change the low byte.
Re: Vibrato
by on (#155560)
But, can you do a vibrato effect using pitch sweep effects?
Re: Vibrato
by on (#155561)
You'd do vibrato in the traditional way ($4002 or $4006 writes) and then use the sweep unit only to nudge the high byte of period from $00 to $FF or from $FF to $00 as needed.
Re: Vibrato
by on (#155570)
You can also do vibrato by flipping the direction of a sweep every few frames, but due to numerical precision problems it's not very versatile for subtle effects.

This is very different from the sweep trick tepples is describing, which is a trick to avoid the "click" of phase reset you get when vibrato goes over a frequency that is a multple of 256, e.g. that infamous clicky A3 vibrato: see mega man 2 ending. The only problem with this method is there are some old emulators that don't get this subtle behaviour of the sweep unit correct.


Instead of implementing vibrato as its own engine feature, I just implemented pitch macros generically. You can put the sequence you described in a pitch macro, though if you have relative pitch macros (like Famitracker's default) instead of an absolute offset from the base note, you put the differences in the macro rather than the target pitch offset.

i.e. an absolute offset of 3, 4, 3, 0 , -3, -4, -3, 0 turns into differences of: 3, 1, -1, -3, -3, -1, 1 3

I like relative pitch macros because you can do other things with them too, like a brief bend into the note, or a gradually increasing vibrato over time, or an easy pitch slide up or down just with one entry in a looped macro.