Vibrato

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

Moderator: Moderators

Post Reply
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Vibrato

Post by dougeff »

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.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Vibrato

Post by dougeff »

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. :)
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Sogona
Posts: 186
Joined: Thu Jul 23, 2015 7:54 pm
Location: USA
Contact:

Re: Vibrato

Post by Sogona »

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.
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Vibrato

Post by dougeff »

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.
nesdoug.com -- blog/tutorial on programming for the NES
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Vibrato

Post by tepples »

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.
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Vibrato

Post by dougeff »

But, can you do a vibrato effect using pitch sweep effects?
nesdoug.com -- blog/tutorial on programming for the NES
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Vibrato

Post by tepples »

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.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Vibrato

Post by rainwarrior »

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.
Post Reply