oh, hello.
Shonumi wrote:Make sure you calculate the frequency as 65536/(2048-x) Hz where x represents Bits 0-2 of NR34.
Actually, at channel INIT I was grabbing NR34 bits 2-0, and all bits of NR33, OR them to get 11bit frequency, subtract them from 2048 and multiply the result with 2. Then compare it with cpu cycles (cpu cycles >= frequency timer as you said) to hear just static (like a mic with a bad cable). Although I ran a square channel on that frequency, the same way I run channels 1 & 2 and it played correctly (in square of course). The problem is my timings advancing the wave sample: I think i'm advancing it VERY slowly, hence the static (it's like i'm changing DC offsets fast, which is not fast enough to be considered a wave).
Shonumi wrote:
To calculate the period (in GB CPU cycles) you just do 4194304 / (65536/(2048-x)). So if x is 0, you get an output frequency of 32 Hz, meaning your period is 131072 CPU cycles. In the case where x = 0, your if statement would have to check if channel3_clocks is greater than or equal to 131072.
Ok, I totally aggree, but no matter how small the frequency, I just hear static. Shouldn't I consider sample rate somewhere in the phase/time calculations?
Shonumi wrote:My APU emulation doesn't even count CPU cycles, and my Sound 3 code is atrociously inaccurate, but it somehow manages to work 98% of the time :p
! My APU doesn't count clocks at channels 1 & 2 too! xD. That's why I find it hard to get chann 3 working i believe.
edit: Actually after playing with my sound (laughing hard after each result), I came up with a code that slightly reminded me of channel 3 in some games. The practice is the worst possible: Keep track of phase 0-2π . Divide phase by 32 this gives 0.196. After 0.196 (rads?) I advance one sample. It's not better than having no channel 3 at all, but at least it reminded me of something
edit2:
Ok I think i got it working now (with this nasty way as well):
Code: Select all
public float update_wave(float volume) {
sample_num = (int)(phase * 5.09);
byte sample = Memory.mem[0xFF30 + sample_num / 2];
if (sample_num % 2 == 0) {
amplitude = ((sample >> 4) - 8);
}
else amplitude = ((sample & 0xF) - 8);
phase = phase + ((Math.PI * frequency) / 44100);
if (phase > 2 * Math.PI) {
phase = phase - (2 * Math.PI);
}
return amplitude * 0.0625f * volume;
}
Don't ask me why it works. But if you think it, it's quite logic. 32 / (2 * π) = 5.09 . Each gives one sample. So I multiply phase with 5.09, apparently giving me the sample number. And so, this is the ratio of period-to-game boy sample.