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

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

Moderator: Moderators

Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

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

Post by Pokun »

I don't know if it matters but in my pause routine I first silence all channels by clearing the volume setting in $4000, $4004, $400C and the mute setting in $4008 for the Triangle. $4015 is only used for DMC, the other APU channels are always enabled. Then I toggle a play flag (like the opposite of a pause flag as it's not only used for pausing) which skips the entire play routine each frame if cleared. Unpausing is simply done by calling the pause routine again toggling the play flag on again. The play routine is designed to set the appropriate volume each frame so there is no need to unmute the channels again. It might not be entirely perfect, but I have not noticed anything strange doing it this way as long as the channels are properly muted upon pausing. Failing to mute causes some small but noticeable audible glitches. But again this all depends on how the driver is designed.

Not sure if toggling the play flag is the best way though as if it fails for some reason the game might loose track of the flag's state and pause when it's supposed to unpause and vice versa. I might change that and have separate pause and unpause routines that guarantees the state of the flag, or you may have to read the state of the flag each time you use pause.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

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

Post by Banshaku »

The famitracker drivers clears its value, like you said, at $4000, $4004 and $400C when the music is stopped so my current issue is not related about that unfortunately. Thank you for the idea ;)

I think the reason is more related to the music format itself. For example, in a tracked song, you can start an effect/note that will be active for multiple frames. When you pause, you just stopped in the middle an active note/event, which means when you unpause it, it cannot continue unless it knew the state, somehow, when it was stopped and re-trigger it at that exact moment. I wouldn't be surprised if instruments that contains effects, if stopped in the middle of playing, won't continue because of that too, which would be why that some notes are not playing (effect was stopped) but the volumes are still applied to a stopped effect/note, which is my current issue.

I will live with it, not a big issue in my case. It would have just been a nice option in the jukebox but it's not a deal breaker.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

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

Post by tepples »

My sound driver Pently pauses music as Pokun describes. When pently_stop_music clears the "music playing" flag, the following happens:
Setting the flag back to a nonzero value (jsr pently_resume_music) causes the musical time and envelope generation to pick up exactly where they left off.

This approach works well on a PSG or wavetable with full software envelopes, such as those in the 2A03, MMC5, Sunsoft 5B (aka AY-3-8910 or YM2149F SSG), VRC6, or Namco 163. If software envelopes weren't available, such as on the Game Boy or a few Famicom expansion synths, it would need to wait for the next ADSR segment and resume the note from there.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

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

Post by rainwarrior »

Yeah setting volume to 0 for squares/noise is probably better than clearing $4015 like I suggested, esp. if the driver is normally updating volume every frame.
Banshaku wrote:I think the reason is more related to the music format itself. For example, in a tracked song, you can start an effect/note that will be active for multiple frames. When you pause, you just stopped in the middle an active note/event, which means when you unpause it, it cannot continue unless it knew the state, somehow, when it was stopped and re-trigger it at that exact moment. I wouldn't be surprised if instruments that contains effects, if stopped in the middle of playing, won't continue because of that too, which would be why that some notes are not playing (effect was stopped) but the volumes are still applied to a stopped effect/note, which is my current issue.
I'm pretty sure this is just the length counter issue I mentioned above. Until the cached value for $4003/4007 etc. changes it won't reload the length counter that got cleared by writing 0 to $4015, and the channel won't turn back on. Probably the zero volume technique is easier, since you don't have to go looking for the cache variables, but that was how I'd always done it in the past.
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, then I guess it worth giving it a try before giving up on it for now. I will just backup the volumes, set them to zero then pause the engine. When unpaused, put back the previous values and see how it goes.

What about 4003/4007, do they still need to be set to $FF to avoid popping? That part should be easy to test so I will know right away if it does has an impact (popping sound and other issues).
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

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

Post by rainwarrior »

Banshaku wrote:I see, then I guess it worth giving it a try before giving up on it for now. I will just backup the volumes, set them to zero then pause the engine. When unpaused, put back the previous values and see how it goes.
No you shouldn't need to back anything up, that's the point. Volume will get overwritten every active frame anyway.
Banshaku wrote:What about 4003/4007, do they still need to be set to $FF to avoid popping? That part should be easy to test so I will know right away if it does has an impact (popping sound and other issues).
No you don't write $FF to $4003. Sorry, this is getting like several steps removed from the problem.

If you write 0 to $4015 to silence all the channels, they will not "wake up" until there is some write to $4003, $4007, etc. to reload the length counter. However, sound engines tend to write these registers infrequently because writing it too often makes a bad noise. So... it's typical to have some variable somewhere that stores the last written value to $4003, which is checked before writing it to prevent any unnecessary writes. If you find that variable you can change its value so that on the next frame the engine will think $4003 is not up to date and take care of waking it up for you.

...and none of that needs to be done if you didn't write 0 to $4015. If you used the volume technique, then there's nothing to wake up.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

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

Post by Banshaku »

From my questions, you already figured out that I don't know much about the APU and try to guess about possible issues or how to do it (that's a programmer's habit, I guess ^^;;;).

Thank you for clarifying about $4003/$4007, I really appreciate it. This is one more reason I'm not touching the APU for now since I have no idea what I'm doing :lol:

Will test the volume without any backup or anything. Quite a simple approach and like it.

edit:

And I always enjoy learning new things. I know more about the APU today!
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

[solved] APU: volume and... envelope? ^^;;;

Post by Banshaku »

After testing more with the famitracker driver regarding my last question (pausing the song), there was nothing necessary to be done: the driver allows it, it just that there was not function with the name pause on it :lol:

Basically, if you just change the flag from playing ($01) to stopped ($00), the channels volumes will be set to OFF ($00 or $30 depending on the channel). When you put back the flag to $01, the song continue to play without issues. I was just trying to split hairs for nothing. Since all upper bits of the flag variable are not used, I just added an extra flag to it to know if I asked to pause it or the song finished naturally, which means my pause method knows in which state the driver is and won't try to restart something that was already finished.

Thanks rainwarrior and everyone that helped on the subject, it's now working like I wanted. cool :D
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

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

Post by rainwarrior »

Just to follow up on how to silence the triangle:

No, you don't have to write $400B after writing $4008. I think that was written because of a mistaken omission on that page, insinuating that writing $4008 is not sufficient to reload the linear counter. (It is sufficient.)

So really all you need to do is write $80 to $4008 to silence the triangle (and subsequently $FF to $4008 will wake it up). That will leave the counters halted too, which is probably what you want. Most people would not want to use the linear/length counter feature. The 1/4 frame delay is real, but kind of innocuous.


(I wrote a test ROM just to be sure, before making corrections to the wiki page.)
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. Thank you for the extra information. Right now this is what the famitracker driver does and it has no impact so far:

Code: Select all

noMusic:
	lda #$30			;mute channels when music does not play
	sta BUF_4000
	sta BUF_4004
	sta BUF_400C
	lda #$00
	sta BUF_4008
it could be specific to the Shiru's Famitracker/Famitone combo but I would need to dig in the original code to confirm though.

For now, I had no issue when I set back to play the flag. For some reason, it writes $00 instead of $80. I guess I need to learn more about the meaning of the values before talking more on the subject ^^;;;
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

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

Post by Pokun »

Is that your code or is it part of Famitracker? Bit 7 of $4008 is used to disable the hardware length counter for the Triangle (0=enabled, 1=disabled). Since most sound engines (not sure about Famitracker) doesn't use the hardware length counter and instead controls note lengths in software (by muting the Triangle when the note is supposed to be finished playing and unmuting when the next note comes), that flag is always set in such sound engines. Therefore $80 is used for muting and $FF for unmuting instead of $00 and $7F. It's the same reason the Squares and Noise are muted by writing $30 to $4000/$4004/$400C instead of $00 so that the hardware length counter and hardware envelope both are kept disabled at all times. By manipulating the volume over several frames, more advanced software envelopes can be created than the single hardware one (which is just a simple linear fade to 0 as Rainwarrior said).



Thanks Rainwarrior for confirming that writing $80 to $4008 is sufficient to silence Triangle, and for fixing the wiki.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

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

Post by Banshaku »

Good question. It either:

- was in famitracker
- was in famitracker/famitone combo

Not sure which one. Since I know nothing about sound engines, I didn't add that part and it was taken "as-is". For now, there is no ill effects and it has always worked well. Maybe the famitone engine for sfx uses it? I guess not since it should be using famitracker data. Hmmm..

I will try to find the origin of this code give a follow-up about it. Thanks for mentioning it!

edit:

I just confirm the origin of the code and it came from the famitracker/famitone neslib combo example. I will update it to $80 and test if it goes well.
User avatar
za909
Posts: 249
Joined: Fri Jan 24, 2014 9:05 am
Location: Mijn hart woont al in Nederland

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

Post by za909 »

I think there is still some use for the linear counter, even in an all-software environment because it lets you do something that software would normally be unable to do, which is to play those very short triangle bursts. Since my sound engine rewrites all three triangle registers every frame I have full control of the duration, but I can also, at any time, set the linear counter to something that takes less than one frame, producing some unusual distorted sounds. Basically I treat $4008 as a triangle "duty cycle" selector, where $00-$02 produce distorted tones and anything above $03 is a normal triangle wave.
Attachments
Triangle Linear Counter Effects.nsf
(9.45 KiB) Downloaded 406 times
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

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

Post by Bregalad »

za909 wrote:I think there is still some use for the linear counter, even in an all-software environment because it lets you do something that software would normally be unable to do, which is to play those very short triangle bursts. Since my sound engine rewrites all three triangle registers every frame I have full control of the duration, but I can also, at any time, set the linear counter to something that takes less than one frame, producing some unusual distorted sounds. Basically I treat $4008 as a triangle "duty cycle" selector, where $00-$02 produce distorted tones and anything above $03 is a normal triangle wave.
Well, this could be done in software, but only if your sound engine runs more than once per frame, which is impractical except on specific mappers. Interesting effects, by the way !
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

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

Post by Pokun »

Yeah I think it might be a good idea to add commands to a sound engine that allows the composer to change some registers arbitrarily in order to allow some advanced stuff not normally allowed by the sound data format.

Cool effects indeed! :)
Post Reply