APU: volume and... envelope? ^^;;;
Moderator: Moderators
Re: APU: volume and... envelope? ^^;;;
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.
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.
Re: APU: volume and... envelope? ^^;;;
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.
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.
Re: APU: volume and... envelope? ^^;;;
My sound driver Pently pauses music as Pokun describes. When pently_stop_music clears the "music playing" flag, the following happens:
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.
- pently_update_music does not add the tempo to the variable that accumulates musical time since last row. This causes the next row not to occur.
- pently_update_music_ch does not update the channel's envelope or the track's grace note down counter. Instead, each channel sends a zero volume to the mixer (pently_update_one_ch), which continues to mix this silence with any ongoing sound effects.
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.
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: APU: volume and... envelope? ^^;;;
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.
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.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.
Re: APU: volume and... envelope? ^^;;;
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).
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).
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: APU: volume and... envelope? ^^;;;
No you shouldn't need to back anything up, that's the point. Volume will get overwritten every active frame anyway.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 don't write $FF to $4003. Sorry, this is getting like several steps removed from the problem.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).
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.
Re: APU: volume and... envelope? ^^;;;
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
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!
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
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!
[solved] APU: volume and... envelope? ^^;;;
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
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
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
- rainwarrior
- Posts: 8734
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: APU: volume and... envelope? ^^;;;
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.)
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.)
Re: APU: volume and... envelope? ^^;;;
I see. Thank you for the extra information. Right now this is what the famitracker driver does and it has no impact so far:
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 ^^;;;
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
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 ^^;;;
Re: APU: volume and... envelope? ^^;;;
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.
Thanks Rainwarrior for confirming that writing $80 to $4008 is sufficient to silence Triangle, and for fixing the wiki.
Re: APU: volume and... envelope? ^^;;;
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.
- 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.
Re: APU: volume and... envelope? ^^;;;
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
Re: APU: volume and... envelope? ^^;;;
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 !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.
Re: APU: volume and... envelope? ^^;;;
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!
Cool effects indeed!