Last active
December 10, 2018 20:34
-
-
Save dlandahl/54e04832f3325d2c26c50a96f87f4e16 to your computer and use it in GitHub Desktop.
Making sound with DirectSound
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <iostream> | |
#include <string> | |
#include "dsound.h" | |
#include "mmreg.h" | |
#include "cguid.h" | |
HWND get_console_window(); | |
void hresult_log(HRESULT, std::string); | |
int main() | |
{ | |
char const guid_null[16] = { 0 }; | |
int const i16_max = 0x8000; | |
float const tau = 6.28318530f; | |
int const bitdepth = 16; | |
int const bytes = bitdepth / 8; | |
int const samplerate = 44100; | |
int const channels = 1; | |
std::cout << "Hi.\n"; | |
LPDIRECTSOUND8 device; | |
HRESULT ret; | |
hresult_log(DirectSoundCreate8(NULL, &device, NULL), | |
"DirectSoundCreate8"); | |
hresult_log(device->SetCooperativeLevel(get_console_window(), DSSCL_NORMAL), | |
"SetCooperativeLevel"); | |
LPDIRECTSOUNDBUFFER buffer = NULL; | |
WAVEFORMATEX format; | |
memset(&format, 0, sizeof(WAVEFORMATEX)); | |
format.wFormatTag = WAVE_FORMAT_PCM; | |
format.nChannels = channels; | |
format.nSamplesPerSec = samplerate; | |
format.nAvgBytesPerSec = samplerate * bytes * channels; | |
format.nBlockAlign = bytes * channels; | |
format.wBitsPerSample = bitdepth; | |
DSBUFFERDESC desc; | |
memset(&desc, 0, sizeof(DSBUFFERDESC)); | |
desc.dwSize = sizeof ( DSBUFFERDESC ); | |
desc.dwFlags = 0; | |
desc.dwBufferBytes = bytes * samplerate; | |
desc.dwReserved = 0; | |
desc.lpwfxFormat = &format; | |
desc.guid3DAlgorithm = *(GUID*)(guid_null); | |
hresult_log(device->CreateSoundBuffer(&desc, &buffer, NULL), | |
"CreateSoundBuffer"); | |
int16_t data[samplerate * channels]; | |
for (unsigned n = 0; n < samplerate; n++) | |
data[n] = int16_t(std::sin(double(tau * 220 * n) / samplerate) * i16_max); | |
[&buffer, &data]() { | |
LPVOID write_pointer; | |
DWORD return_size; | |
hresult_log(buffer->Lock(0, 0, &write_pointer, &return_size, NULL, NULL, DSBLOCK_ENTIREBUFFER), | |
"Lock"); | |
memcpy(write_pointer, data, return_size); | |
hresult_log(buffer->Unlock(write_pointer, return_size, NULL, 0), "Unlock"); | |
}(); | |
buffer->SetCurrentPosition(0); | |
hresult_log(buffer->Play(0, 0, 0), "Play"); | |
std::cin.get(); | |
} | |
void hresult_log(HRESULT result, std::string name) | |
{ | |
std::cout << std::hex << "Retcode " << name << ": 0x" << result << "\n"; | |
} | |
HWND get_console_window() | |
{ | |
unsigned const title_len = 128u; | |
TCHAR console_title[title_len]; | |
GetConsoleTitle(console_title, title_len); | |
HWND window_handle = FindWindow(NULL, console_title); | |
return window_handle; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment