The 32 4-bit samples in ch3 are played back at a frequency between 1024 and 2097152 Hz (counting each sample), depending on the value of NR33 and NR34.aprentice said:all i could get sound wise is pop and clicks in different frequencies, is the 16 samples in channel 3 per second? I'm using directsound, does anyone have any experiences in it? I know the buffer is circular, and i took that into account when writing to it.. I have my buffer size set to ~2kb, bits per sample to 8, and samples per second to 22050. Then i have it set to loop playback and every frame i mix the sound and write to the sound buffer. Am i not writing enough samples per second thus resulting in pops and clicks? I'm still confused about some aspects of sound but i understand more than what i started out with..
Dark Stalker said:The 32 4-bit samples in ch3 are played back at a frequency between 1024 and 2097152 Hz (counting each sample), depending on the value of NR33 and NR34.
I think you should focus on ch2 first. You only need to emulate the frequency to get the melodies going, just keep the high samples at something like a value of 32, and the low ones at -32. The value of the frequency registers can be implemented as a down-counter, which increments a wave duty counter upon reaching 0/being reloaded. The wave duty counter in turn determines whether the sample should be high or low. You could simply dictate this to be 50% high/low for now, you'll be able to recognise melodies anyway. You'll also probably want to stick to mono sound for now, or you'll have to generate pairs of stereo samples.
What do you mean by "every frame"? The buffer will need more data at a rate of samplerate/(buffer_size*sample_size), but you'll have to generate samples at least as often as the values of the sound registers are changed if you want accuracy. Generating samples only when the sound buffer needs more data should still be enough to get "proof of concept" sound output however.
AFAIK DirectSound has a "play cursor" and a "write cursor" that move in parallel. You'll need to write to the area beyond the "write cursor"/before the "play cursor". I suppose you could always poll positions to determine how much has been played back, but I think it should be possible to set a callback-function that fills the buffer when needed (in a seperate thread), that's what I'm using in sdl. I hope someone that knows directsound can give some input here.
A mostly unrelated side note: Remeber that the sample rate needs to be at least twice as high as the frequency of the wave it's representing, which is why 44100 Hz is a popular rate (hearing has it's limit at around 22kHz waves).
// Count framerate & slow down emu, I call this every time the
// screen is rendered
void VIDEO::CountFrameRate()
{
/* fps counter */
static int Last;
const int Past = SDL_GetTicks() - Last;
if(Past == 0)
mFps = 1000;
else
mFps = (1000 / Past);
Last = SDL_GetTicks();
// Slow Down the Framerate if it is greater than 60
// these values I just played with so it worked at the right speed in my emu,
// they may need to be adjusted (the 60 and the 15).
if(mFps>60) SDL_Delay(mFps/15);
}
I was of the impression that the write cursor moves with the play cursor, always staying a little bit ahead of the play cursor, to signal from which point on it's safe to write new data to the buffer.aprentice said:i already give samples for right and left speakers, i have a 64 byte buffer set up, 32 for left and 32 for right, i know it has a play cursor and theres a write cursor that you have created yourself to keep track of where you are in the buffer. What confuses me is how many samples do i need to generate to play a full second of audio, and how do i generate that many if channel 3 is only 16 bytes in lenght, do i just keep checking the gameboy sound buffer when i need more sound? and to detect if i need to fill the buffer again do i need to do if playpos < writepos?