nesdev.com
http://forums.nesdev.com/

FamiTone and fading out music
http://forums.nesdev.com/viewtopic.php?f=6&t=16521
Page 1 of 1

Author:  DRW [ Fri Sep 22, 2017 1:07 am ]
Post subject:  FamiTone and fading out music

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:
.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?

Author:  FrankenGraphics [ Fri Sep 22, 2017 2:18 am ]
Post subject:  Re: FamiTone and fading out music

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.

Author:  rainwarrior [ Fri Sep 22, 2017 2:22 am ]
Post subject:  Re: FamiTone and fading out music

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.

Author:  FrankenGraphics [ Fri Sep 22, 2017 2:29 am ]
Post subject:  Re: FamiTone and fading out music

Quote:
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.

Author:  DRW [ Fri Sep 22, 2017 5:07 am ]
Post subject:  Re: FamiTone and fading out music

At the end of FamiToneUpdate, he does this:
Code:
   ;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.

Author:  dougeff [ Fri Sep 22, 2017 5:57 am ]
Post subject:  Re: FamiTone and fading out music

Quote:
the four volume values


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

Author:  DRW [ Fri Sep 22, 2017 6:24 am ]
Post subject:  Re: FamiTone and fading out music

Right. I will probably cut it when the rest is somewhere in the middle.

Author:  tepples [ Fri Sep 22, 2017 6:42 am ]
Post subject:  Re: FamiTone and fading out music

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.

Author:  tokumaru [ Fri Sep 22, 2017 7:14 am ]
Post subject:  Re: FamiTone and fading out music

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.

Author:  DRW [ Fri Sep 22, 2017 7:32 am ]
Post subject:  Re: FamiTone and fading out music

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.)

Author:  rainwarrior [ Fri Sep 22, 2017 1:43 pm ]
Post subject:  Re: FamiTone and fading out music

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.

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/