handmade.network » Wiki » DirectSound

Simple Sound Generator

 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
{
        IDirectSound8 *directSound = NULL;
        IDirectSoundBuffer *primaryBuffer = NULL;
        IDirectSoundBuffer8 *secondaryBuffer = NULL;
        IDirectSoundBuffer *temporaryBuffer = NULL;

        DSBUFFERDESC bufferDescription = {};
        WAVEFORMATEX waveFormat = {};

        DirectSoundCreate8(NULL, &directSound, NULL);
        directSound->SetCooperativeLevel(window, DSSCL_PRIORITY);

        bufferDescription.dwSize = sizeof(DSBUFFERDESC);
        bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
        bufferDescription.dwBufferBytes = 0;
        bufferDescription.dwReserved = 0;
        bufferDescription.lpwfxFormat = NULL;
        bufferDescription.guid3DAlgorithm = GUID_NULL;

        directSound->CreateSoundBuffer(&bufferDescription, &primaryBuffer, NULL);

        waveFormat.wFormatTag = WAVE_FORMAT_PCM;
        waveFormat.nSamplesPerSec = 44100;
        waveFormat.wBitsPerSample = 16;
        waveFormat.nChannels = 2;
        waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels;
        waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
        waveFormat.cbSize = 0;

        primaryBuffer->SetFormat(&waveFormat);

        bufferDescription.dwFlags = DSBCAPS_CTRLVOLUME;
        bufferDescription.dwBufferBytes = 44100 * 2 * 2;
        bufferDescription.lpwfxFormat = &waveFormat;

        directSound->CreateSoundBuffer(&bufferDescription, &temporaryBuffer, NULL);
        temporaryBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void **) &secondaryBuffer);
        temporaryBuffer->Release();

        uint8_t *buffer;
        DWORD bufferSize;
        secondaryBuffer->Lock(0, bufferDescription.dwBufferBytes, (void **) &buffer, &bufferSize, NULL, 0, 0);

        for (int i = 0; i < 44100; i++) {
            float f = sin((float) i / 8) * sin((float) i / 16);
            int16_t a = (int16_t) (f * 10000);

            buffer[i * 4 + 0] = i >  22050 ? (a >> 0) : 0;
            buffer[i * 4 + 1] = i >  22050 ? (a >> 8) : 0;
            buffer[i * 4 + 2] = i <= 22050 ? (a >> 0) : 0;
            buffer[i * 4 + 3] = i <= 22050 ? (a >> 8) : 0;
        }

        secondaryBuffer->Unlock((void *) buffer, bufferSize, NULL, 0);

        secondaryBuffer->SetCurrentPosition(0);
        secondaryBuffer->SetVolume(DSBVOLUME_MAX);
        secondaryBuffer->Play(0, 0, 0);
    }

Compile with

cl.exe main.cpp /DEBUG /Od /Zi shell32.lib user32.lib dsound.lib dxguid.lib winmm.lib

and include the headers

1
2
3
4
5
#include <windows.h>
#include <stdint.h>
#include <mmsystem.h>
#include <math.h>
#include <dsound.h>