My Init
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | internal void win32InitDSound(HWND Window, int32_t BufferSize, int32_t SamplesPerSecond) { // Load Library HMODULE DSoundLibrary = LoadLibrary("dsound.dll"); if (DSoundLibrary){ // Direct Sound Object direct_sound_create *DirectSoundCreate = (direct_sound_create *) GetProcAddress(DSoundLibrary, "DirectSoundCreate"); LPDIRECTSOUND DirectSound; if(DirectSoundCreate && SUCCEEDED(DirectSoundCreate(0, &DirectSound, 0)) ) { WAVEFORMATEX WaveFormat = {}; WaveFormat.wFormatTag = WAVE_FORMAT_PCM ; WaveFormat.nChannels = 2; WaveFormat.nSamplesPerSec = SamplesPerSecond; WaveFormat.wBitsPerSample = 16; WaveFormat.nBlockAlign = (WaveFormat.nChannels * WaveFormat.wBitsPerSample) / 8; WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign; WaveFormat.cbSize = 0; // create primary buffer if ( SUCCEEDED(DirectSound->SetCooperativeLevel(Window, DSSCL_PRIORITY)) ) { DSBUFFERDESC BufferDescription = {}; BufferDescription.dwSize = sizeof(BufferDescription); BufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; LPDIRECTSOUNDBUFFER PrimaryBuffer; if(SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &PrimaryBuffer, 0)) ) { if(SUCCEEDED(PrimaryBuffer->SetFormat(&WaveFormat))) { OutputDebugStringA("Primary Buffer format set. \n"); } else { // TODO: Logging } } else { // TODO: Logging } } else { // TODO: Logging } // create secondary buffer DSBUFFERDESC BufferDescription = {}; BufferDescription.dwSize = sizeof(BufferDescription); BufferDescription.dwFlags = 0; BufferDescription.dwBufferBytes = BufferSize; BufferDescription.lpwfxFormat = &WaveFormat; HRESULT Err = DirectSound->CreateSoundBuffer(&BufferDescription, &GlobalSecondaryBuffer, 0); if(SUCCEEDED(Err) ) { OutputDebugStringA("Secondary Buffer Created!\n"); } } else { // TODO: Logging } } } |
My Variables
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | HDC DeviceContext = GetDC(Window); // graphics int XOffset = 0; int YOffset = 0; // sound int samplesPerSecond = 48000; int Hz = 256; uint32_t RunningSampleIndex = 0; int SquareWavePeriod = samplesPerSecond/Hz; int HalfSquareWavePeriod = SquareWavePeriod/2; int BytesPerSample = sizeof(int16_t)* 2; int SecondaryBufferSize = samplesPerSecond*BytesPerSample; |
My Test Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | DWORD PlayCursor; DWORD WriteCursor; if(SUCCEEDED(GlobalSecondaryBuffer->GetCurrentPosition( &PlayCursor, &WriteCursor) )) { DWORD ByteToLock = RunningSampleIndex*BytesPerSample % SecondaryBufferSize; DWORD BytesToWrite; if(ByteToLock > PlayCursor) { ByteToLock = (SecondaryBufferSize - ByteToLock); BytesToWrite += PlayCursor; }else { BytesToWrite = PlayCursor - ByteToLock; } VOID *Region1; DWORD Region1Size; VOID *Region2; DWORD Region2Size; if(SUCCEEDED( GlobalSecondaryBuffer->Lock(ByteToLock, BytesToWrite, &Region1, &Region1Size, &Region2, &Region2Size, 0))) { int16_t *SampleOut = (int16_t *)Region1; DWORD Region1SampleCount = Region1Size/BytesPerSample; for(DWORD SampleIndex = 0; SampleIndex < Region1SampleCount; ++SampleIndex) { int16_t SampleValue = ( (RunningSampleIndex / HalfSquareWavePeriod) % 2 ) ? 6000 : -6000; *SampleOut++ = SampleValue; *SampleOut++ = SampleValue; ++RunningSampleIndex; } *SampleOut = (int16_t *)Region2; DWORD Region2SampleCount = Region2Size/BytesPerSample; for(DWORD SampleIndex = 0; SampleIndex < Region1SampleCount; ++SampleIndex) { int16_t SampleValue = ( (RunningSampleIndex / HalfSquareWavePeriod) % 2 ) ? 6000 : -6000; *SampleOut++ = SampleValue; *SampleOut++ = SampleValue; ++RunningSampleIndex; } GlobalSecondaryBuffer->Unlock(Region1, Region1Size, Region2, Region2Size); } |