Problem is: Channel 4 is generating a "buzz" effect that sounds louder than it should be. The effect of the "ocean waves" in the Zelda: Link's Awakening intro, or almost all songs from Mega Man III are good examples.
The noise is more noticeable than the other channels on Mega Man III, which is pretty annoying. Other channels sounds good.
Also, I noticed the Zelda logo "tliiiin" hiss that plays when it appears in the intro is not reached (looks like it's tone is higher than what I can sample), so it sounds just like a normal buzz. Other sounds effects plays correctly.
I followed the GBSOUND and Sound Hardware wiki page, maybe I'm doing something really wrong.
I was sampling before at 44100 Hz, but increased to 96000 Hz and sound quality improved, but both works.
I steps cycles in multiples of 4, inside a loop until all elapsed cycles are consumed (based on the last instruction cycles count - my emu is cycle count accurate only).
The periods for sampling are:
Code: Select all
44100 Hz: 4194304 / (44100 / 2); // gives ~735 samples
96000 Hz: 4194304 / (96000 / 2); // gives ~1606 samples
When called, I copy the buffer to audio buffer and clear my buffer for next frame.
The emulation is not synced to audio, so there's some skip (small sound gaps, sometimes very rarely)
All channels sounds good with that configuration, but channel 4 has those issues I mentioned earlier.
Code for channel 4:
Code: Select all
public void FreqTimerStep( )
{
// for each 4 cycles, this method is called from APU
m_timer -= 4;
if (m_timer <= 0)
{
int result = (m_linearShiftReg & 0x1) ^ ((m_linearShiftReg >> 1) & 0x1);
m_linearShiftReg >>= 1;
m_linearShiftReg |= result << 14;
if (m_stepsMode == 1)
{
m_linearShiftReg &= ~0x40; // clear bit 6
m_linearShiftReg |= result << 6;
}
// Reload Frequency
m_timer += CalcFrequency();
}
}
int CalcFrequency( )
{
int freq = 8;
switch (m_divRatio)
{
case 0:
freq = 8 << m_shiftFreq;
break;
case 1:
freq = 16 << m_shiftFreq;
break;
case 2:
freq = 32 << m_shiftFreq;
break;
case 3:
freq = 48 << m_shiftFreq;
break;
case 4:
freq = 64 << m_shiftFreq;
break;
case 5:
freq = 80 << m_shiftFreq;
break;
case 6:
freq = 96 << m_shiftFreq;
break;
case 7:
freq = 112 << m_shiftFreq;
break;
}
return freq;
}
The sampling code is
Code: Select all
// Output is bit 0 inverted
if ((m_linearShiftReg & 0x1) == 0)
{
return 15 & m_curVolume;
}
return 0;
Maybe I need some kind of audio filter for this channel?
Edit: if needed, full code is at https://github.com/fattard/xFF/blob/gb/ ... hannel4.cs