#168841 - Dwedit - Thu May 28, 2009 10:07 pm
I've written a new program that sets the GBC Square Wave channels' frequency and volume independently, without using volume envelopes. Normally, you need to reset the waveform in order to change the volume for the square channels.
I've written a test program that calculates the exact time it's okay to reset the phase of the wave with no artifacts, then performs the write to change the volume at that time.
The program itself isn't anything special, it just plays a chord of two square waves repeatedly, but it sounds correct on hardware, and fails miserably on current builds of VBA. I'm about to revise PocketNES to use this method for sound.
The basic algorithm:
You have the Sound Period for the GB channel
Multiply it by 16
That's your timer frequency (Negate it before you use it as a timer reload value obviously)
Add some "fudge" factor to set the initial value of the timer. I'm using 192.
Whenever you write to the sound register, set the timer's initial value and restart the sound channel at the same time. Then you can put the correct reload value in after you've added the fudged initial timer value.
When you want to change the sound, enable IRQs for that timer.
The interrupt handler for the timer will wait until the exact instant it should rewrite the sound register and timer. If the timer interrupt triggered too late, wait one more waveform before trying again.
Attachment
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
I've written a test program that calculates the exact time it's okay to reset the phase of the wave with no artifacts, then performs the write to change the volume at that time.
The program itself isn't anything special, it just plays a chord of two square waves repeatedly, but it sounds correct on hardware, and fails miserably on current builds of VBA. I'm about to revise PocketNES to use this method for sound.
The basic algorithm:
You have the Sound Period for the GB channel
Multiply it by 16
That's your timer frequency (Negate it before you use it as a timer reload value obviously)
Add some "fudge" factor to set the initial value of the timer. I'm using 192.
Whenever you write to the sound register, set the timer's initial value and restart the sound channel at the same time. Then you can put the correct reload value in after you've added the fudged initial timer value.
When you want to change the sound, enable IRQs for that timer.
The interrupt handler for the timer will wait until the exact instant it should rewrite the sound register and timer. If the timer interrupt triggered too late, wait one more waveform before trying again.
Attachment
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."