Skip to content

Instantly share code, notes, and snippets.

@mojobojo
Created April 29, 2018 04:10
Show Gist options
  • Save mojobojo/2805c73dbf72e57825870731641907e5 to your computer and use it in GitHub Desktop.
Save mojobojo/2805c73dbf72e57825870731641907e5 to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <dsound.h>
#include <intrin.h>
#include <stdio.h>
typedef char i8;
typedef unsigned char u8;
typedef short i16;
typedef unsigned short u16;
typedef int i32;
typedef unsigned int u32;
typedef long long i64;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;
typedef i32 b32;
#define MAGIC_RIFF 0x46464952
#define MAGIC_WAVE 0x45564157
#define MAGIC_FMT_ 0x20746D66
#define MAGIC_DATA 0x61746164
struct riff_data {
u32 magic;
u32 size;
u32 format;
};
struct wav_format_data {
u32 magic;
u32 size;
u16 audio_format;
u16 number_of_channels;
u32 sample_rate;
u32 byte_rate;
u16 block_align;
u16 bits_per_sample;
};
struct wav_chunk {
u32 magic;
u32 size;
u8 data[];
};
HWND window;
HANDLE standard_out;
HANDLE process_heap;
wav_format_data *wav;
u8 *wav_file_data;
u32 wav_file_size;
u8 *sound_data;
u32 sound_data_size;
IDirectSound8 *direct_sound_8;
LPDIRECTSOUNDBUFFER direct_sound_buffer;
LPDIRECTSOUNDBUFFER secondary_sound_buffer;
WAVEFORMATEX wave_format;
void Sound_LoadWavFile(char *file_name) {
HANDLE file_handle = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle != INVALID_HANDLE_VALUE) {
wav_file_size = GetFileSize(file_handle, 0);
u8 *wav_file_data = (u8 *)HeapAlloc(process_heap, 0, wav_file_size);
if (wav_file_data) {
DWORD bytes_read;
ReadFile(file_handle, wav_file_data, wav_file_size, &bytes_read, NULL);
if (bytes_read == wav_file_size) {
riff_data *riff = (riff_data *)wav_file_data;
if (riff->magic == MAGIC_RIFF && riff->format == MAGIC_WAVE) {
wav = (wav_format_data *)(wav_file_data + sizeof(riff_data));
wave_format.wFormatTag = wav->audio_format;
wave_format.nChannels = wav->number_of_channels;
wave_format.nSamplesPerSec = wav->sample_rate;
wave_format.nAvgBytesPerSec = wav->byte_rate;
wave_format.nBlockAlign = wav->block_align;
wave_format.wBitsPerSample = wav->bits_per_sample;
wave_format.cbSize = sizeof(wave_format);
if (wav->magic == MAGIC_FMT_) {
wav_chunk *chunk = (wav_chunk *)(wav_file_data + sizeof(riff_data) + sizeof(wav_format_data));
while (true) {
if (chunk->magic == MAGIC_DATA) {
sound_data_size = chunk->size;
sound_data = chunk->data;
break;
}
chunk = (wav_chunk *)((u8 *)chunk + chunk->size + sizeof(wav_chunk));
}
} else {
__debugbreak();
}
} else {
__debugbreak();
}
} else {
__debugbreak();
}
CloseHandle(file_handle);
} else {
__debugbreak();
}
} else {
__debugbreak();
}
}
b32 Sound_CreatePrimaryBuffer() {
b32 success = false;
if (SUCCEEDED(DirectSoundCreate8(NULL, &direct_sound_8, NULL))) {
if (SUCCEEDED(direct_sound_8->SetCooperativeLevel(window, DSSCL_PRIORITY))) {
DSBUFFERDESC buffer_descriptor;
ZeroMemory(&buffer_descriptor, sizeof(buffer_descriptor));
buffer_descriptor.dwSize = sizeof(buffer_descriptor);
buffer_descriptor.dwFlags = DSBCAPS_PRIMARYBUFFER;
if (SUCCEEDED(direct_sound_8->CreateSoundBuffer(&buffer_descriptor, &direct_sound_buffer, NULL))) {
if (SUCCEEDED(direct_sound_buffer->SetFormat(&wave_format))) {
success = true;
}
} else {
__debugbreak();
}
} else {
__debugbreak();
}
} else {
__debugbreak();
}
return success;
}
BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) {
char buffer[256];
int size = sprintf_s(buffer, sizeof(buffer), "%s : %s\n", lpcstrDescription, lpcstrModule);
WriteConsoleA(standard_out, buffer, size, NULL, NULL);
return TRUE;
}
void Sound_PrintDevices() {
HRESULT direct_sound_enumerate_result = DirectSoundEnumerateA(DSEnumCallback, NULL);
if (FAILED(direct_sound_enumerate_result)) {
WriteConsoleA(standard_out, "wat\n", 4, NULL, NULL);
}
}
void Sound_TestPlay() {
Sound_LoadWavFile("My Broken Friend.wav");
Sound_CreatePrimaryBuffer();
DSBUFFERDESC loaded_wav_descriptor;
ZeroMemory(&loaded_wav_descriptor, sizeof(loaded_wav_descriptor));
loaded_wav_descriptor.dwSize = sizeof(loaded_wav_descriptor);
loaded_wav_descriptor.dwFlags = DSBCAPS_GLOBALFOCUS;
loaded_wav_descriptor.dwBufferBytes = sound_data_size;
loaded_wav_descriptor.lpwfxFormat = &wave_format;
if (SUCCEEDED(direct_sound_8->CreateSoundBuffer(&loaded_wav_descriptor, &secondary_sound_buffer, 0))) {
DWORD audio_offset = 0;
LPVOID audio_buffer;
LPVOID audio_buffer_wrap;
DWORD audio_buffer_size;
DWORD audio_buffer_wrap_size;
while (true) {
DWORD current_play_cursor;
DWORD current_write_cursor;
secondary_sound_buffer->GetCurrentPosition(&current_play_cursor, &current_write_cursor);
wprintf(L"Play Cursor: %d | Write Cursor: %d | Diff: %d\r", current_play_cursor, current_write_cursor, current_write_cursor - current_play_cursor);
HRESULT secondary_sound_buffer_creation_result = secondary_sound_buffer->Play(0, 0, DSBPLAY_LOOPING);
if (SUCCEEDED(secondary_sound_buffer_creation_result)) {
HRESULT lock_result = secondary_sound_buffer->Lock(audio_offset, 4096, &audio_buffer, &audio_buffer_size, &audio_buffer_wrap, &audio_buffer_wrap_size, 0);
if (SUCCEEDED(lock_result)) {
CopyMemory(audio_buffer, sound_data + audio_offset, audio_buffer_size);
if (FAILED(secondary_sound_buffer->Unlock(audio_buffer, audio_buffer_size, audio_buffer_wrap, audio_buffer_wrap_size))) {
__debugbreak();
}
audio_offset += audio_buffer_size;
audio_offset %= sound_data_size;
} else {
__debugbreak();
}
} else {
__debugbreak();
}
}
} else {
__debugbreak();
}
}
int main() {
standard_out = GetStdHandle(STD_OUTPUT_HANDLE);
process_heap = HeapCreate(0, 0, 0);
window = GetConsoleWindow();
if (process_heap != INVALID_HANDLE_VALUE && standard_out != INVALID_HANDLE_VALUE) {
Sound_PrintDevices();
Sound_TestPlay();
} else {
__debugbreak();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment