Credits goes to Disch for the code in this .DLL, i didn't code it. But have used a lot in my NES emu.
I share this DLL that let you play samples in realtime.
As NES emulator authors we know that there is a need to have a code/lib that can output saples to the soundcard on the fly.
I'ts true, the DLL is very basic, but since the channels in emudaving a NES are mixed internally, it's handy to those who doesn't want to use SDL or somehing else, to have something to start with.
The DLL is compiled under VS 2019. The header file would be adaptable to GNU C++, but i don't use it and i don't have tools right now to test it. So if you want to make one. Do it.
BASIC BEHAVOR
-------------------
1 - Instatiate CSoundOut class
Thjs Create the object, then initalize it and finally set the main buffer format. In this case to 48KHZ 16-bit per sample, 0 for MONO sound, and the buffer latency in milliseconds.
2 - Wait the DSound circular buffer has enough free samples to play
If you are generating 800 NES samples, thos are 800 * 2 16-BIT samples.
You do:
This will keep writing sound as the emulator loops and generates more samples.
The Sleep(1) is not needed but frees up the cpu for a time and syncs sound. You can practically sync the emu to sound doing this, but as we know a PPU frame isn't exactly Vertical 60 hz.
3 - Finally you can Destroy() the deallocate dsound.
4 - There are other methods in the class like flush() to silence the buffer, Stop(), that are much self explanatory.
I hope is helpfull
I share this DLL that let you play samples in realtime.
As NES emulator authors we know that there is a need to have a code/lib that can output saples to the soundcard on the fly.
I'ts true, the DLL is very basic, but since the channels in emudaving a NES are mixed internally, it's handy to those who doesn't want to use SDL or somehing else, to have something to start with.
The DLL is compiled under VS 2019. The header file would be adaptable to GNU C++, but i don't use it and i don't have tools right now to test it. So if you want to make one. Do it.
BASIC BEHAVOR
-------------------
1 - Instatiate CSoundOut class
Code:
CSoundOut * sound_out = new CSoundOut();
sound_out->Initialize(hwnd);
sound_out->SetFormat(48000, 16, 0, 200);
sound_out->Initialize(hwnd);
sound_out->SetFormat(48000, 16, 0, 200);
Thjs Create the object, then initalize it and finally set the main buffer format. In this case to 48KHZ 16-bit per sample, 0 for MONO sound, and the buffer latency in milliseconds.
2 - Wait the DSound circular buffer has enough free samples to play
If you are generating 800 NES samples, thos are 800 * 2 16-BIT samples.
You do:
Code:
if (!sound_out->IsPlaying())
sound_out->Play();
while(sound_out->CanWrite() < 1600)
Sleep(1);
sound_out->Write((char *)buffer, 1600);
sound_out->Play();
while(sound_out->CanWrite() < 1600)
Sleep(1);
sound_out->Write((char *)buffer, 1600);
This will keep writing sound as the emulator loops and generates more samples.
The Sleep(1) is not needed but frees up the cpu for a time and syncs sound. You can practically sync the emu to sound doing this, but as we know a PPU frame isn't exactly Vertical 60 hz.
3 - Finally you can Destroy() the deallocate dsound.
4 - There are other methods in the class like flush() to silence the buffer, Stop(), that are much self explanatory.
I hope is helpfull