APU: volume and... envelope? ^^;;;

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

Moderator: Moderators

User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

APU: volume and... envelope? ^^;;;

Post by Banshaku »

As you can see from the question, I don't know much about the APU. After reading the wiki regarding for the register content for volume, I came more confused than before I looked at it :lol:

Maybe if I explain what I want to do, it will be easier to know if what I'm looking at is the right information. On a Jukebox screen, I want to show the current volume of each channel. The Famitracker/famitone combo driver that I'm using is buffering the values of each register so it should be easy to access but I don't know what to extract and what to show because of the volume/constant/envelope explained in the wiki.

My question is, what value should I extract from the register of each channel to show the current volume? I guess there must be a special case for triangle/dpcm since you cannot control it, so I need to figure out how it work to show a visualization of it.

Once I understand how to extract the values it should be easy to display them.

Thank you in advance for some basic information on the subject.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by rainwarrior »

Most likely for the thing you're working on you don't have to worry about envelope mode. Just use the current 4-bit constant volume.

Envelope isn't supported by Famitracker. Mostly only used by old games. It's kind of a badly implemented hardware feature, always has to start at full volume and does a simple linear fade to 0. Using constant volume with per-frame control is much more versatile.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

I see. I wouldn't have known just by looking at the wiki ^^;;; I was going to test first with the 4 bits only so it seems my instinct was right.

As for DPCM/Triangle, since there is no volume, what would be the best way to know if something is playing? I will check their registers and see if I can guess something out of it.

Thanks again!
User avatar
gravelstudios
Posts: 159
Joined: Mon Mar 13, 2017 5:21 pm
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by gravelstudios »

Maybe Off topic:
In my audio engine, I like the hardware envelope as a way to apply a simple articulation at the beginning of notes, especially since it doesn't use as much memory/cycles as my software envelope. It depends on how I want things to sound. I think it's also really good for sound effects. It gives a nice 'pingy' arcadey sound. Just my 2 cents.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by rainwarrior »

Banshaku wrote:As for DPCM/Triangle, since there is no volume, what would be the best way to know if something is playing?
DPCM is easy, you can just read $4015 and check bit 4.

Triangle there are a few different ways to silence. Which one is used depends on the engine. You can write 0 to $4008 to halt it with the "linear counter" at the next quarter-frame tick. You can write $4015 to disable it (not usually preferable because writing to $4015 has the potential to interfere with other channels, esp. DPCM). You can let the "length counter" run out. You can write 0 to the frequency registers to produce a pitch too high to be heard. I think the first method ($4008) is probably the one most often used?
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

@gravelstudios

Yes, it was offtopic since I'm not making an engine but just trying to read the status of channel in an existing engine :lol:

@rainwarrior

DPCM is quite easy, thanks! For the triangle, well, I don't know how famitracker does it so the pointers you gave should be a good start. Time to look inside the driver source code, I guess :D

edit:

I looked inside the code and inside apu.s, it set 4008 to 0 at "@KillTriangle", so I guess 0 means off for the triangle then.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

Sorry for the double post, just to say that it worked.

What I do, for other people that may want to do the same thing with famitracker.
- use the buffered value of the registers. If your version doesn't, just buffer them inside apu.s
- Square 1/2/noise: use the lower 4 bits of $4000, $4004, $400C
- triangle: check it $4008 value. If 0 then off else, something is playing
- DPCM: check status of value written to $4015. If bit 4 is set (or if all channel are on, if equal $1F) then DPCM is playing

That's it and it is working. My only thing left to do, which is not related to volume, is to check if famitracker driver allowed to pause music or not. For now I don't see the flag so either I removed it when restructuring code (duh) or there is no such thing. It's not that much of an important feature but would like to add it.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: APU: volume and... envelope? ^^;;;

Post by Pokun »

Try writing $80 to $4008 instead of 0. That's the most common way to mute the Triangle I think (depending on the engine), and that's how I do it in my sound engine. It should mute it at once. No idea if it works with Famitracker though.

The wiki suggests to write 0 to $4008, something to $400B and then something with bit 7 set to $4017 though. Sounds complicated.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by rainwarrior »

Pokun wrote:Try writing $80 to $4008 instead of 0. That's the most common way to mute the Triangle I think (depending on the engine), and that's how I do it in my sound engine. It should mute it at once. No idea if it works with Famitracker though.

The wiki suggests to write 0 to $4008, something to $400B and then something with bit 7 set to $4017 though. Sounds complicated.
I guess you're referring to the bottom of this page.
To $4008: $80 or $00 doesn't matter. The high bit controls whether it will count down, but you're setting its reload value either way. The actual silence happens once the frame sequence reloads it.

To $400B: I think the linear counter reload won't apply until after a $400B write? At least that's what a few emulators seem to implement. My memory is a bit hazy on this one. Weirdly my music engine might neglect writing $400B, but I don't recall this being a problem? Memory is hazy here, I'm kinda confused about this.

To $4017: This will clock the frame sequencer immediately, causing an instant silence instead of up to a 1/4 frame delay for the next clock whenever the frame sequence silences the triangle. If you want to eliminate that delay, this is necessary, though if you're using envelopes or other frame sequence stuff it will interfere with those. I'd personally say the delay is slight enough not to be a problem, but if you want an immediate halt this how to do it.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: APU: volume and... envelope? ^^;;;

Post by Pokun »

I see, I read somewhere that bit 7 must be set to silence Triangle right away. Seems that was wrong. The reason I write $80 might be because I don't use the internal length counter, so I have no reason the clear the Length Counter Halt Flag (although I'm not sure if that matters when muting). I'm sure I learned that from Nerdy Nights sound tutorial.

Yeah not using $400B and $4017 when muting the Triangle have never really created any audible problems for me. Seems just making the sound engine unnecessarily complicated unless you really need them for some reason. I think that bottom part of the wiki is new BTW. At least I don't remember reading it before.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

@Pokun

Since the values comes from the famitracker driver, the only way to change it would be to change how the driver works, which is not the goal of this post but just refresh each frame on the screen (volume bars) what is happening in each channel. No modification is required.

From the last few people, it seems people don't know if the driver does have a pause function or not. I will recheck the original version (Shiru's combo driver is based on 4.6) and see if such code existed, seems the only way. If not, I will just remove the button on the screen.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by rainwarrior »

Oh, I did not see that question.

No, Famitracker doesn't have a pause feature.

Usually the way I've implemented one is to set $4015 to 0 on pause. Then to unpause, set $4015 to $0F.

This isn't a complete solution, though, because the channels don't fully turn back on until the high frequency register is written ($4003, $4007, etc.) which reloads their length counter. To get that to work, I needed to find where Famitracker stores a cached value for those registers and invalidate it (i.e. set the value to $FF) so that on the next frame it is guaranteed to rewrite those registers.

The reason there's a cached value for those is because writing to e.g. $4003 resets phase and causes a pop sound, so it's normal to avoid writing to that register unless the value has actually changed. There's probably some CMP right next to the code that stores to $4003, that should tell you where the value is cached.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

I see, so it doesn't exist, like I was suspecting for a while. Thanks for confirming.

With what you said, I may be able to implement it quite fast. I don't understand the part that writing 0 to 4015 would stop the driver. It would stop the hardware channels, yes, but for the driver, I'm not aware because of lack of knowledge of how it works.

Still, what you just said gives me a lot of useful information on how to implement it so I will just test it and see how it goes then.

Thanks for the information!
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by rainwarrior »

Well you stop the driver by not calling its play routine every frame while you're paused.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Re: APU: volume and... envelope? ^^;;;

Post by Banshaku »

I was able to implement a quick pause flag with the current existing one and was able to restart it without modifying the play routine in nmi but depending on how the song is made, it causes on resume some channel to not be playing at all until some specific parameter reset it (i.e. the volume bars are still shown but no sound comes out).

I guess it may not be easy to smoothly return from pause and may not be that necessary anyway so for this project I think I will skip it until I understand more about the driver. It may be possible to do it more smoothly, it just my knowledge of the driver is lacking and my goal is not to learn famitracker innards to, someday.
Post Reply