Last active
July 28, 2025 05:34
-
-
Save kalsprite/3d3a21646b6b2d8d5cda5e848d45da84 to your computer and use it in GitHub Desktop.
dsound init
This file contains hidden or 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
| // Released as Public Domain, Attribution appreciated but not required, Jon Lipstate | |
| package scratch | |
| import win32 "core:sys/windows" | |
| import "core:dynlib" | |
| import "core:fmt" | |
| import "vendor:directx/dxgi" | |
| IDirectSound :: struct { | |
| using lpVtbl: ^IDirectSoundVtbl, | |
| } | |
| IDirectSoundVtbl :: struct { | |
| using iunknown_vtable: dxgi.IUnknown_VTable, | |
| CreateSoundBuffer: proc "stdcall" ( | |
| this: ^IDirectSound, | |
| pcDSBufferDesc: ^DSBUFFERDESC, | |
| ppDSBuffer: ^^IDirectSoundBuffer, | |
| pUnkOuter: rawptr, | |
| ) -> win32.HRESULT, | |
| GetCaps: proc "stdcall" (this: ^IDirectSound, pDSCaps: ^DSCAPS) -> win32.HRESULT, | |
| DuplicateSoundBuffer: proc "stdcall" ( | |
| this: ^IDirectSound, | |
| pDSBufferOriginal: ^IDirectSoundBuffer, | |
| ppDSBufferDuplicate: ^^IDirectSoundBuffer, | |
| ) -> win32.HRESULT, | |
| SetCooperativeLevel: proc "stdcall" (this: ^IDirectSound, hwnd: win32.HWND, dwLevel: win32.DWORD) -> win32.HRESULT, | |
| Compact: proc "stdcall" (this: ^IDirectSound) -> win32.HRESULT, | |
| GetSpeakerConfig: proc "stdcall" (this: ^IDirectSound, pdwSpeakerConfig: ^win32.DWORD) -> win32.HRESULT, | |
| SetSpeakerConfig: proc "stdcall" (this: ^IDirectSound, dwSpeakerConfig: win32.DWORD) -> win32.HRESULT, | |
| Initialize: proc "stdcall" (this: ^IDirectSound, pcGuidDevice: ^win32.GUID) -> win32.HRESULT, | |
| } | |
| DSBUFFERDESC :: struct { | |
| dwSize: win32.DWORD, | |
| dwFlags: win32.DWORD, | |
| dwBufferBytes: win32.DWORD, | |
| dwReserved: win32.DWORD, | |
| lpwfxFormat: ^WAVEFORMATEX, | |
| // #if DIRECTSOUND_VERSION >= 0x0700 | |
| guid3DAlgorithm: win32.GUID, | |
| // #endif | |
| } | |
| WAVEFORMATEX :: struct { | |
| wFormatTag: win32.WORD, /* format type */ | |
| nChannels: win32.WORD, /* number of channels (i.e. mono, stereo...) */ | |
| nSamplesPerSec: win32.DWORD, /* sample rate */ | |
| nAvgBytesPerSec: win32.DWORD, /* for buffer estimation */ | |
| nBlockAlign: win32.WORD, /* block size of data */ | |
| wBitsPerSample: win32.WORD, /* number of bits per sample of mono data */ | |
| cbSize: win32.WORD, /* the count in bytes of the size of */ | |
| /* extra information (after cbSize) */ | |
| } | |
| IDirectSoundBuffer :: struct { | |
| using lpVtbl: ^IDirectSoundBufferVtbl, | |
| } | |
| IDirectSoundBufferVtbl :: struct { | |
| using iunknown_vtable: dxgi.IUnknown_VTable, | |
| GetCaps: proc "stdcall" (this: ^IDirectSoundBuffer, pDSBufferCaps: ^DSBCAPS) -> win32.HRESULT, //LPDSBCAPS | |
| GetCurrentPosition: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| pdwCurrentPlayCursor: ^win32.DWORD, | |
| pdwCurrentWriteCursor: ^win32.DWORD, | |
| ) -> win32.HRESULT, | |
| GetFormat: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| pwfxFormat: ^WAVEFORMATEX, | |
| dwSizeAllocated: win32.DWORD, | |
| pdwSizeWritten: ^win32.DWORD, | |
| ) -> win32.HRESULT, | |
| GetVolume: proc "stdcall" (this: ^IDirectSoundBuffer, plVolume: ^win32.LONG) -> win32.HRESULT, | |
| GetPan: proc "stdcall" (this: ^IDirectSoundBuffer, plPan: ^win32.LONG) -> win32.HRESULT, | |
| GetFrequency: proc "stdcall" (this: ^IDirectSoundBuffer, pdwFrequency: ^win32.DWORD) -> win32.HRESULT, | |
| GetStatus: proc "stdcall" (this: ^IDirectSoundBuffer, pdwStatus: ^win32.DWORD) -> win32.HRESULT, | |
| Initialize: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| pDirectSound: ^IDirectSound, | |
| pcDSBufferDesc: ^DSBUFFERDESC, | |
| ) -> win32.HRESULT, | |
| Lock: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| dwOffset: win32.DWORD, | |
| dwBytes: win32.DWORD, | |
| ppvAudioPtr1: ^win32.LPVOID, | |
| pdwAudioBytes1: ^win32.DWORD, | |
| ppvAudioPtr2: ^win32.LPVOID, | |
| pdwAudioBytes2: ^win32.DWORD, | |
| dwFlags: win32.DWORD, | |
| ) -> win32.HRESULT, | |
| Play: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| dwReserved1: win32.DWORD, | |
| dwPriority: win32.DWORD, | |
| dwFlags: win32.DWORD, | |
| ) -> win32.HRESULT, | |
| SetCurrentPosition: proc "stdcall" (this: ^IDirectSoundBuffer, dwNewPosition: win32.DWORD) -> win32.HRESULT, | |
| SetFormat: proc "stdcall" (this: ^IDirectSoundBuffer, pcfxFormat: ^WAVEFORMATEX) -> win32.HRESULT, | |
| SetVolume: proc "stdcall" (this: ^IDirectSoundBuffer, lVolume: win32.LONG) -> win32.HRESULT, | |
| SetPan: proc "stdcall" (this: ^IDirectSoundBuffer, lPan: win32.LONG) -> win32.HRESULT, | |
| SetFrequency: proc "stdcall" (this: ^IDirectSoundBuffer, dwFrequency: win32.DWORD) -> win32.HRESULT, | |
| Stop: proc "stdcall" (this: ^IDirectSoundBuffer) -> win32.HRESULT, | |
| Unlock: proc "stdcall" ( | |
| this: ^IDirectSoundBuffer, | |
| pvAudioPtr1: win32.LPVOID, | |
| dwAudioBytes1: win32.DWORD, | |
| pvAudioPtr2: win32.LPVOID, | |
| dwAudioBytes2: win32.DWORD, | |
| ) -> win32.HRESULT, | |
| Restore: proc "stdcall" (this: ^IDirectSoundBuffer) -> win32.HRESULT, | |
| } | |
| WAVE_FORMAT_PCM :: 1 | |
| DSSCL_PRIORITY :: 0x00000002 | |
| DSBCAPS_PRIMARYBUFFER :: 0x00000001 | |
| DSBCAPS_GETCURRENTPOSITION2 :: 0x00010000 | |
| DSBCAPS_GLOBALFOCUS :: 0x00008000 | |
| DSCAPS :: struct { | |
| dwSize:win32.DWORD, | |
| dwFlags:win32.DWORD, | |
| dwMinSecondarySampleRate:win32.DWORD, | |
| dwMaxSecondarySampleRate:win32.DWORD, | |
| dwPrimaryBuffers:win32.DWORD, | |
| dwMaxHwMixingAllBuffers:win32.DWORD, | |
| dwMaxHwMixingStaticBuffers:win32.DWORD, | |
| dwMaxHwMixingStreamingBuffers:win32.DWORD, | |
| dwFreeHwMixingAllBuffers:win32.DWORD, | |
| dwFreeHwMixingStaticBuffers:win32.DWORD, | |
| dwFreeHwMixingStreamingBuffers:win32.DWORD, | |
| dwMaxHw3DAllBuffers:win32.DWORD, | |
| dwMaxHw3DStaticBuffers:win32.DWORD, | |
| dwMaxHw3DStreamingBuffers:win32.DWORD, | |
| dwFreeHw3DAllBuffers:win32.DWORD, | |
| dwFreeHw3DStaticBuffers:win32.DWORD, | |
| dwFreeHw3DStreamingBuffers:win32.DWORD, | |
| dwTotalHwMemBytes:win32.DWORD, | |
| dwFreeHwMemBytes:win32.DWORD, | |
| dwMaxContigFreeHwMemBytes:win32.DWORD, | |
| dwUnlockTransferRateHwBuffers:win32.DWORD, | |
| dwPlayCpuOverheadSwBuffers:win32.DWORD, | |
| dwReserved1:win32.DWORD, | |
| dwReserved2:win32.DWORD, | |
| } | |
| DSBCAPS :: struct | |
| { | |
| dwSize:win32.DWORD, | |
| dwFlags:win32.DWORD, | |
| dwBufferBytes:win32.DWORD, | |
| dwUnlockTransferRate:win32.DWORD, | |
| dwPlayCpuOverhead:win32.DWORD, | |
| } |
This file contains hidden or 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
| // Released as Public Domain, Attribution appreciated but not required, Jon Lipstate | |
| package scratch | |
| import win32 "core:sys/windows" | |
| import "core:c" | |
| import "core:dynlib" | |
| import "core:fmt" | |
| import "vendor:directx/dxgi" | |
| global_secondary_buffer:^IDirectSoundBuffer | |
| main :: proc() { | |
| window,ok := win32_make_window() | |
| if ok { | |
| win32_init_dsound(window,48000,48000*2*size_of(i16)) | |
| } | |
| } | |
| win32_init_dsound :: proc(window: win32.HWND, samples_per_second: int, secondary_buffer_size: int) { | |
| lib, ok := dynlib.load_library("dsound.dll") | |
| assert(ok) | |
| sym, found := dynlib.symbol_address(lib, "DirectSoundCreate") | |
| assert(found) | |
| ds: ^IDirectSound = {} | |
| DirectSoundCreate := cast(proc(lpGuid: ^win32.GUID, ppDS: ^^IDirectSound, pUnkOuter: rawptr) -> win32.HRESULT)sym | |
| ds_result := DirectSoundCreate(nil, &ds, nil) | |
| if ds_result < 0 { | |
| fmt.eprintf("Error in DirectSoundCreate: 0x%X\n",u32(u64(ds_result) & 0x0000_0000_FFFF_FFFF)) | |
| return | |
| } | |
| wave_format: WAVEFORMATEX = { | |
| wFormatTag = WAVE_FORMAT_PCM, | |
| nChannels = 2, | |
| nSamplesPerSec = u32(samples_per_second), | |
| wBitsPerSample = 16, | |
| nBlockAlign = 2 * 16 / 8, | |
| nAvgBytesPerSec = u32(samples_per_second * (2 * 16 / 8)), | |
| cbSize = 0, | |
| } | |
| scl_res := ds->SetCooperativeLevel(window, DSSCL_PRIORITY) | |
| if scl_res < 0 { | |
| fmt.eprintf("Error in SetCooperativeLevel: 0x%X\n",u32(u64(scl_res) & 0x0000_0000_FFFF_FFFF)) | |
| return | |
| } | |
| p_buffer_desc: DSBUFFERDESC = { | |
| dwSize = size_of(DSBUFFERDESC), | |
| dwFlags = DSBCAPS_PRIMARYBUFFER, | |
| } | |
| primary_buffer: ^IDirectSoundBuffer = {} | |
| pb_res := ds->CreateSoundBuffer(&p_buffer_desc, &primary_buffer, nil) | |
| if pb_res < 0 { | |
| fmt.eprintf("Error in CreateSoundBuffer:Primary: 0x%X\n",u32(u64(pb_res) & 0x0000_0000_FFFF_FFFF) ) | |
| return | |
| } | |
| sf_res := primary_buffer->SetFormat(&wave_format) | |
| if sf_res < 0 { | |
| fmt.eprintf("Error in SetFormat:Primary: 0x%X\n",u32(u64(sf_res) & 0x0000_0000_FFFF_FFFF)) | |
| return | |
| } | |
| s_buffer_desc :DSBUFFERDESC= { | |
| dwSize = size_of(DSBUFFERDESC), | |
| dwFlags = DSBCAPS_GETCURRENTPOSITION2, | |
| dwBufferBytes = u32(secondary_buffer_size), | |
| lpwfxFormat = &wave_format, | |
| } | |
| sb_res := ds->CreateSoundBuffer(&s_buffer_desc,&global_secondary_buffer,nil) | |
| if sb_res < 0 { | |
| fmt.eprintf("Error in SetFormat:Secondary: 0x%X\n",u32(u64(sb_res) & 0x0000_0000_FFFF_FFFF)) | |
| return | |
| } | |
| } | |
| win32_make_window::proc() ->(window:win32.HWND,ok:bool){ | |
| instance := win32.HINSTANCE(nil) | |
| window_class: win32.WNDCLASSA = {} | |
| window_class.style = win32.CS_HREDRAW | win32.CS_VREDRAW | |
| window_class.lpfnWndProc = win32.WNDPROC(win32_main_window_callback) | |
| window_class.hInstance = instance | |
| window_class.hCursor = win32.LoadCursorA(win32.HINSTANCE(nil), win32.IDC_ARROW) | |
| window_class.lpszClassName = "ScratchWindowClass" | |
| ok= RegisterClassA(&window_class) != 0 | |
| window = nil | |
| if ok { | |
| window = CreateWindowExA( | |
| 0, | |
| window_class.lpszClassName, | |
| "Scratch", | |
| win32.WS_OVERLAPPEDWINDOW | win32.WS_VISIBLE, | |
| win32.CW_USEDEFAULT, | |
| win32.CW_USEDEFAULT, | |
| 10, | |
| 10, | |
| nil, | |
| nil, | |
| instance, | |
| nil, | |
| ) | |
| ok = window!=nil | |
| } | |
| return window,ok | |
| } | |
| @(export) | |
| win32_main_window_callback :: proc(window: win32.HWND, message: u32, wparam: win32.WPARAM, lparam: win32.LPARAM) -> win32.LRESULT { | |
| result: win32.LRESULT = 0 | |
| switch message { | |
| case: | |
| result = win32.DefWindowProcA(window, message, wparam, lparam) | |
| } | |
| return result | |
| } | |
| foreign import User32 "system:User32.lib" | |
| @(default_calling_convention = "stdcall") | |
| foreign User32 { | |
| CreateWindowExA :: proc(dwExStyle: win32.DWORD, lpClassName: win32.LPCSTR, lpWindowName: win32.LPCSTR, dwStyle: win32.DWORD, X: c.int, Y: c.int, nWidth: c.int, nHeight: c.int, hWndParent: win32.HWND, hMenu: win32.HMENU, hInstance: win32.HINSTANCE, lpParam: rawptr) -> win32.HWND --- | |
| RegisterClassA :: proc(lpWndClass: ^win32.WNDCLASSA) -> win32.ATOM --- | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
complete bindings exist here -
https://github.com/ftphikari/direct_sound