FamiTone and fading out music

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

Moderator: Moderators

Post Reply
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

FamiTone and fading out music

Post by DRW »

I don't know much about writing a good NES music driver, that's why, for my games, I use FamiTone2 unaltered.

But now there's a feature that I might need that FamiTone doesn't seem to provide:
I want to be able to fade out the music instead of outright stopping it.

So, to see if this is even in the realm of possibilities without much hazzle, I've got some questions:

How complicated would it be to include this feature if the original FamiTone2 code is my current basis?

Would it be possible to write a new function that simply uses the FamiTone variables, but where the "famitone2.s" file is left completely unaltered?
Like this:

Code: Select all

.include "famitone2.s"

MyNewFamiToneFadeoutFunction:

    ...
    RTS
Or would this feature require that I alter the "famitone2.s" file itself since existing functions need to be changed as well?


Alternately:
Is there any other way to simulate this feature? Stuff like manually reducing the volume values in the APU (after FamiToneUpdate was written) or something like that? (But this would also silence the sound effects.)
Would reading values back from the APU even be possible? And would this sound alright, if I change existing values after they have already been sent to the APU?
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: FamiTone and fading out music

Post by FrankenGraphics »

I won't claim to know the innards of famitone.

I believe (correct me if i'm wrong) that updates done to audio are, unlike graphics, continously noticable/audible (more or less). But a subroutine tacked on in sequence directly after famitones' updates should be quick enough not to cause a delay that feels wrong, i think. Maybe (and just maybe), an envelope going from 0 to near max will get an audibly different transient if the damp is delayed this way.

If this is the case, you should probably modify famitone directly if the result is unpleasant sounding.
Last edited by FrankenGraphics on Fri Sep 22, 2017 2:23 am, edited 1 time in total.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: FamiTone and fading out music

Post by rainwarrior »

FrankenGraphics wrote:a subroutine tacked on in sequence directly iafter famitones' updates should be quick enough not to cause an delay that feels wrong
No, it would be quite audible as a 60hz buzz.

Look for where the writes to the actual audio registers are, and replace those with something that intervenes with your faded out values BEFORE the write.
User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2064
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: FamiTone and fading out music

Post by FrankenGraphics »

60hz buzz.
Huh. Oh, right, because this delay happens 60 times a second. the buzz should vary in amplitude with the difference between the change and the original value, though - not that it'll be pleasant in any case.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: FamiTone and fading out music

Post by DRW »

At the end of FamiToneUpdate, he does this:

Code: Select all

	;send data from the output buffer to the APU

	lda FT_OUT_BUF		;pulse 1 volume
	sta APU_PL1_VOL
	lda FT_OUT_BUF+1	;pulse 1 period LSB
	sta APU_PL1_LO
	lda FT_OUT_BUF+2	;pulse 1 period MSB, only applied when changed
	cmp FT_PULSE1_PREV
	beq @no_pulse1_upd
	sta FT_PULSE1_PREV
	sta APU_PL1_HI
@no_pulse1_upd:

	lda FT_OUT_BUF+3	;pulse 2 volume
	sta APU_PL2_VOL
	lda FT_OUT_BUF+4	;pulse 2 period LSB
	sta APU_PL2_LO
	lda FT_OUT_BUF+5	;pulse 2 period MSB, only applied when changed
	cmp FT_PULSE2_PREV
	beq @no_pulse2_upd
	sta FT_PULSE2_PREV
	sta APU_PL2_HI
@no_pulse2_upd:

	lda FT_OUT_BUF+6	;triangle volume (plays or not)
	sta APU_TRI_LINEAR
	lda FT_OUT_BUF+7	;triangle period LSB
	sta APU_TRI_LO
	lda FT_OUT_BUF+8	;triangle period MSB
	sta APU_TRI_HI

	lda FT_OUT_BUF+9	;noise volume
	sta APU_NOISE_VOL
	lda FT_OUT_BUF+10	;noise period
	sta APU_NOISE_LO
This is a good place to intercept the four volume values before they go into the PPU. This way, you only need to add a simple macro call to the original file and everything else can be written in another file.
I tried it out and it works.

O.k., we still have the problem that sound effects wouldn't be handled individually, but I guess I can live with that if it means that I don't have to fiddle with the rest of FamiTone and still have an efficient fadeout function.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: FamiTone and fading out music

Post by dougeff »

the four volume values
Three. Triangle channel has no volume. You will have to cut it completely at some point.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: FamiTone and fading out music

Post by DRW »

Right. I will probably cut it when the rest is somewhere in the middle.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: FamiTone and fading out music

Post by tepples »

dougeff wrote:Three. Triangle channel has no volume. You will have to cut it completely at some point.
True.

But in many music engines, such as that of Hatris, a fadeout makes notes on the triangle channel shorter. This means the engine's internal concept of "volume" is used to know when to turn the triangle channel on or off. And in other engines, such as Pently, volume determines priority between the sound effect on a channel and the musical instrument on the same channel.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: FamiTone and fading out music

Post by tokumaru »

I guess you could internally treat the triangle channel as if it had a 4-bit volume like the other channels, and do envelopes, fades, etc. normally, but when updating the registers, compare the volume against a threshold to decide whether to enable or disable it. That'd make decaying notes shorter.

As for a global volume setting (i.e. fading songs/effects), couldn't you use a 256-byte look-up table to "mix" each channel's volume with a global volume to get the final volume setting? Like, have the global volume in the upper 4 bits, OR it with the channel's volume which are in the lower 4-bits, and use the result as an index to look up the final volume in the 256-byte look-up table.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: FamiTone and fading out music

Post by DRW »

tokumaru wrote:As for a global volume setting (i.e. fading songs/effects), couldn't you use a 256-byte look-up table to "mix" each channel's volume with a global volume to get the final volume setting? Like, have the global volume in the upper 4 bits, OR it with the channel's volume which are in the lower 4-bits, and use the result as an index to look up the final volume in the 256-byte look-up table.
I thought that I would simply have a regular byte variable. And when I want to fade-out the music, I would decrement the volume in each channel by the current value of the variable.

I.e., usually my variable is 0, so the volumes are the original ones:
NewVolume = OldVolume - 0

But when I want to fade out, I increment the value every few frames, until it has reached 15.

This means the volume values will be reduced every few frames and eventually, all of them will be at 0:

NewVolume = OldVolume - 1
NewVolume = OldVolume - 2
NewVolume = OldVolume - 3
...
NewVolume = OldVolume - 15

(Of course, paying attention that a value that's already at 0 doesn't get decremented any further since this would just set it back to maximum again.)
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: FamiTone and fading out music

Post by rainwarrior »

Startropics actually uses $4011 to fade out the triangle. It's only about 50% effective, and and you get a slight buzz from changing it at a regular interval, but it does actually fade the triangle a bit.
Post Reply