v0.01.003 - Mouse pointers, Audio improvement & features, bug fixes
This commit is contained in:
parent
b631b96e62
commit
d89ef01fa6
7 changed files with 150 additions and 61 deletions
21
TODO
21
TODO
|
@ -1,6 +1,6 @@
|
||||||
|
- Gamepad
|
||||||
|
|
||||||
- Audio
|
- Audio
|
||||||
- Avoid playing identical audio at the same time
|
|
||||||
- Allow audio programming
|
- Allow audio programming
|
||||||
- Inject mixer proc per player
|
- Inject mixer proc per player
|
||||||
- Inject a mixer proc before and after filling output buffer
|
- Inject a mixer proc before and after filling output buffer
|
||||||
|
@ -9,14 +9,13 @@
|
||||||
- Handle audio sources which had their format defaulted to update when default device changes
|
- Handle audio sources which had their format defaulted to update when default device changes
|
||||||
For streamed audio sources this should be easy enough, because the conversion happens from raw format to source format as we stream it.
|
For streamed audio sources this should be easy enough, because the conversion happens from raw format to source format as we stream it.
|
||||||
For loaded sources though, we would need to convert the source->pcm_frames.
|
For loaded sources though, we would need to convert the source->pcm_frames.
|
||||||
|
Probably just dirty flag
|
||||||
- Optimize
|
- Optimize
|
||||||
- Spam simd
|
- Spam simd
|
||||||
- Concurrent jobs for players?
|
|
||||||
- Pool of intermediate buffers (2^)
|
- Pool of intermediate buffers (2^)
|
||||||
- Bugs:
|
- Bugs / Issues:
|
||||||
- Small fadeout on pause is slightly noisy
|
- Small fadeout on start/pause is sometimes noisy
|
||||||
- Setting time stamp/progression causes noise (need fade transition like on pause/play)
|
- If audio starts/end abrubtly we will get noise. Maybe detect that on load and apply small fade in/out?
|
||||||
- End of clip also causes noise if audio clip does not end smoothly
|
|
||||||
- Setting audio source to a format which differs from audio output format in both channels and bit_width at the same time will produce pure loud noise.
|
- Setting audio source to a format which differs from audio output format in both channels and bit_width at the same time will produce pure loud noise.
|
||||||
- 24-Bit audio conversion doesn't really work
|
- 24-Bit audio conversion doesn't really work
|
||||||
|
|
||||||
|
@ -38,12 +37,14 @@
|
||||||
- OS
|
- OS
|
||||||
- Window::bool is_minimized
|
- Window::bool is_minimized
|
||||||
- don't set window.width & window.height to 0
|
- don't set window.width & window.height to 0
|
||||||
|
- Handle monitor change
|
||||||
- Sockets recv, send
|
- Sockets recv, send
|
||||||
- Mouse pointer
|
- Mouse pointer
|
||||||
- Hide mouse pointer
|
- Hide mouse pointer
|
||||||
|
|
||||||
|
- Better hash table
|
||||||
|
|
||||||
- Memory
|
- Memory
|
||||||
- In heap allocator, mark pages that fit entirely into free nodes as NOACCESS
|
|
||||||
- Arenas
|
- Arenas
|
||||||
|
|
||||||
- Examples/Guides:
|
- Examples/Guides:
|
||||||
|
@ -51,13 +52,19 @@
|
||||||
- Z sorting
|
- Z sorting
|
||||||
- Scissor boxing
|
- Scissor boxing
|
||||||
- Concurrency
|
- Concurrency
|
||||||
|
- strings
|
||||||
|
|
||||||
- Rework profiler
|
- Rework profiler
|
||||||
- Store records and convert to google trace format on exit
|
- Store records and convert to google trace format on exit
|
||||||
- Measure both time and cycles, output a google_trace_cycles.json & google_trace_time.json
|
- Measure both time and cycles, output a google_trace_cycles.json & google_trace_time.json
|
||||||
|
|
||||||
|
- Concurrency
|
||||||
|
- Event objects for binary semaphore
|
||||||
|
|
||||||
- Needs testing:
|
- Needs testing:
|
||||||
- Audio format channel conversions
|
- Audio format channel conversions
|
||||||
- sample rate downsampling
|
- sample rate downsampling
|
||||||
- non stereo or mono audio
|
- non stereo or mono audio
|
||||||
- Audio spacialization on anything that's not stereo
|
- Audio spacialization on anything that's not stereo
|
||||||
|
- Compiling with msvc
|
||||||
|
- Compiling with gcc
|
|
@ -1,8 +1,12 @@
|
||||||
|
|
||||||
## v0.01.003 - Stuff
|
## v0.01.003 - Mouse pointers, Audio improvement & features, bug fixes
|
||||||
- Os layer
|
- Os layer
|
||||||
- Implemented setting of mouse pointers, either to system standard pointers or a custom image
|
- Implemented setting of mouse pointers, either to system standard pointers or a custom image
|
||||||
- Ignore SETCURSOR events unless window resize
|
os_set_mouse_pointer_standard(kind)
|
||||||
|
os_set_mouse_pointer_custom(pointer)
|
||||||
|
os_make_custom_mouse_pointer(image, width, height, hotspot_x, hotspot_y)
|
||||||
|
os_make_custom_mouse_pointer_from_file(path, hotspot_x, hotspot_y, allocator)
|
||||||
|
- Ignore SETCURSOR events unless for window resize pointer
|
||||||
- Store SYSTEM_INFO in init
|
- Store SYSTEM_INFO in init
|
||||||
- os_get_number_of_logical_processors()
|
- os_get_number_of_logical_processors()
|
||||||
|
|
||||||
|
@ -15,14 +19,35 @@
|
||||||
- os_lock_program_memory_pages
|
- os_lock_program_memory_pages
|
||||||
- Heap locks pages when completely free
|
- Heap locks pages when completely free
|
||||||
|
|
||||||
|
- Audio
|
||||||
|
- Implemented playback speed configuration
|
||||||
|
- Implemented a way to recognize audio sources which start playing at the exact same time so we can avoid phase cancellation
|
||||||
|
- Refactor playback configuration members in Audio_Player to be in a struct Audio_Playback_Configuration
|
||||||
|
Example: player.volume -> player.config.volume
|
||||||
|
- bool disable_spacialization -> bool enable_spacialization (inverted)
|
||||||
|
- Deprecated:
|
||||||
|
play_one_audio_clip_source_at_position()
|
||||||
|
play_one_audio_clip_at_position()
|
||||||
|
- Added:
|
||||||
|
play_one_audio_clip_source_with_config()
|
||||||
|
play_one_audio_clip_with_config()
|
||||||
|
- Removed 'bool retain_progression_factor' parameter in audio_player_set_source()
|
||||||
|
- Fixed a bug where players didn't loop when set to do so
|
||||||
|
- Fixed a bug where wav sources would return 4 garbage samples at the start of playback, causing a glitch in the sound
|
||||||
|
- Fixed a crash when default audio device could not be initialized
|
||||||
|
- Fixed a bunch of bugs & woopsies
|
||||||
|
- Updated audio_test.c
|
||||||
|
|
||||||
- Misc
|
- Misc
|
||||||
- Deprecate Rangef stuff
|
- Deprecated Rangef stuff
|
||||||
- peek_random()
|
- added peek_random()
|
||||||
- Update #Contributions
|
- Updated #Contributions
|
||||||
- Clean up memory barriers in concurrency.c and use volatile instead
|
- Cleaned up memory barriers in concurrency.c and use volatile instead
|
||||||
- Output d3d11 debug messages before crash on hr fail
|
- Made hr fails output d3d11 debug messages before crash
|
||||||
- Configurable temporary storage size for new threads
|
- Made temporary storage size runtime-configurable for new threads
|
||||||
- Cleanup temporary storage after thread destroy
|
- Cleanup temporary storage after thread destroy
|
||||||
|
- Added Header checking in growing array
|
||||||
|
- Unfucked linmath alignment
|
||||||
|
|
||||||
|
|
||||||
## v0.01.002 - Flexible build options, Hotloading, growing array
|
## v0.01.002 - Flexible build options, Hotloading, growing array
|
||||||
|
|
|
@ -249,7 +249,7 @@ typedef struct Cpu_Capabilities {
|
||||||
#define COMPILER_CAN_DO_AVX2 0
|
#define COMPILER_CAN_DO_AVX2 0
|
||||||
#define COMPILER_CAN_DO_AVX512 0
|
#define COMPILER_CAN_DO_AVX512 0
|
||||||
|
|
||||||
#define deprecated(msg)
|
#define DEPRECATED(proc, msg)
|
||||||
|
|
||||||
#define MEMORY_BARRIER
|
#define MEMORY_BARRIER
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ int entry(int argc, char **argv) {
|
||||||
bool bruh_ok = audio_open_source_load(&bruh, STR("oogabooga/examples/bruh.wav"), heap);
|
bool bruh_ok = audio_open_source_load(&bruh, STR("oogabooga/examples/bruh.wav"), heap);
|
||||||
assert(bruh_ok, "Could not load bruh.wav");
|
assert(bruh_ok, "Could not load bruh.wav");
|
||||||
|
|
||||||
bool song_ok = audio_open_source_stream_format(&song, STR("oogabooga/examples/song.ogg"), heap);
|
bool song_ok = audio_open_source_stream(&song, STR("oogabooga/examples/song.ogg"), heap);
|
||||||
assert(song_ok, "Could not load song.ogg");
|
assert(song_ok, "Could not load song.ogg");
|
||||||
|
|
||||||
// By default, audio sources will be converted to the same format as the output buffer.
|
// By default, audio sources will be converted to the same format as the output buffer.
|
||||||
|
|
|
@ -1,46 +1,85 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Thing *things;
|
Full API:
|
||||||
growing_array_init(&things, sizeof(Thing));
|
|
||||||
|
|
||||||
growing_array_deinit(&things);
|
void growing_array_init_reserve(void **array, u64 block_size_in_bytes, u64 count_to_reserve, Allocator allocator);
|
||||||
|
void growing_array_init(void **array, u64 block_size_in_bytes, Allocator allocator);
|
||||||
|
void growing_array_deinit(void **array);
|
||||||
|
|
||||||
Thing new_thing;
|
void *growing_array_add_empty(void **array);
|
||||||
growing_array_add(&things, &new_thing); // 'thing' is copied
|
void growing_array_add(void **array, void *item);
|
||||||
|
|
||||||
Thing *nth_thing = &things[n];
|
void growing_array_reserve(void **array, u64 count_to_reserve);
|
||||||
|
void growing_array_resize(void **array, u64 new_count);
|
||||||
|
void growing_array_pop(void **array);
|
||||||
|
void growing_array_clear(void **array);
|
||||||
|
|
||||||
growing_array_reserve_count(&things, 690);
|
// Returns -1 if not found
|
||||||
growing_array_resize_count(&things, 69);
|
s32 growing_array_find_index_from_left_by_pointer(void **array, void *p);
|
||||||
|
s32 growing_array_find_index_from_left_by_value(void **array, void *p);
|
||||||
|
|
||||||
// "Slow", but stuff in the array keeps the same order
|
void growing_array_ordered_remove_by_index(void **array, u32 index);
|
||||||
growing_array_ordered_remove_by_index(&things, i);
|
void growing_array_unordered_remove_by_index(void **array, u32 index);
|
||||||
|
bool growing_array_ordered_remove_by_pointer(void **array, void *p);
|
||||||
|
bool growing_array_unordered_remove_by_pointer(void **array, void *p);
|
||||||
|
bool growing_array_ordered_remove_one_by_value(void **array, void *p);
|
||||||
|
bool growing_array_unordered_remove_one_by_value(void **array, void *p);
|
||||||
|
|
||||||
// Fast, but will not keep stuff ordered
|
u32 growing_array_get_valid_count(void *array);
|
||||||
growing_array_unordered_remove_by_index(&things, i);
|
u32 growing_array_get_allocated_count(void *array);
|
||||||
|
|
||||||
growing_array_ordered_remove_by_pointer(&things, nth_thing);
|
Usage:
|
||||||
growing_array_unordered_remove_by_pointer(&things, nth_thing);
|
|
||||||
|
|
||||||
Thing thing_prototype;
|
Thing *things;
|
||||||
growing_array_ordered_remove_one_by_value(&things, thing_prototype);
|
growing_array_init(&things, sizeof(Thing));
|
||||||
growing_array_unordered_remove_one_by_value(&things, thing_prototype);
|
|
||||||
growing_array_ordered_remove_all_by_value(&things, thing_prototype);
|
|
||||||
growing_array_unordered_remove_all_by_value(&things, thing_prototype);
|
|
||||||
|
|
||||||
growing_array_get_valid_count(&things);
|
growing_array_deinit(&things);
|
||||||
growing_array_get_allocated_count(&things);
|
|
||||||
|
Thing new_thing;
|
||||||
|
growing_array_add(&things, &new_thing); // 'thing' is copied
|
||||||
|
|
||||||
|
Thing *nth_thing = &things[n];
|
||||||
|
|
||||||
|
growing_array_reserve_count(&things, 690);
|
||||||
|
growing_array_resize_count(&things, 69);
|
||||||
|
|
||||||
|
// "Slow", but stuff in the array keeps the same order
|
||||||
|
growing_array_ordered_remove_by_index(&things, i);
|
||||||
|
|
||||||
|
// Fast, but will not keep stuff ordered
|
||||||
|
growing_array_unordered_remove_by_index(&things, i);
|
||||||
|
|
||||||
|
growing_array_ordered_remove_by_pointer(&things, nth_thing);
|
||||||
|
growing_array_unordered_remove_by_pointer(&things, nth_thing);
|
||||||
|
|
||||||
|
Thing thing_prototype;
|
||||||
|
growing_array_ordered_remove_one_by_value(&things, thing_prototype);
|
||||||
|
growing_array_unordered_remove_one_by_value(&things, thing_prototype);
|
||||||
|
growing_array_ordered_remove_all_by_value(&things, thing_prototype);
|
||||||
|
growing_array_unordered_remove_all_by_value(&things, thing_prototype);
|
||||||
|
|
||||||
|
growing_array_get_valid_count(&things);
|
||||||
|
growing_array_get_allocated_count(&things);
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define GROWING_ARRAY_SIGNATURE 2224364215
|
||||||
|
|
||||||
typedef struct Growing_Array_Header {
|
typedef struct Growing_Array_Header {
|
||||||
|
u32 signature;
|
||||||
u32 valid_count;
|
u32 valid_count;
|
||||||
u32 allocated_count;
|
u32 allocated_count;
|
||||||
u32 block_size_in_bytes;
|
u32 block_size_in_bytes;
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
} Growing_Array_Header;
|
} Growing_Array_Header;
|
||||||
|
|
||||||
|
bool
|
||||||
|
check_growing_array_signature(void **array) {
|
||||||
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
|
if (header->signature != GROWING_ARRAY_SIGNATURE) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
growing_array_init_reserve(void **array, u64 block_size_in_bytes, u64 count_to_reserve, Allocator allocator) {
|
growing_array_init_reserve(void **array, u64 block_size_in_bytes, u64 count_to_reserve, Allocator allocator) {
|
||||||
|
@ -54,6 +93,7 @@ growing_array_init_reserve(void **array, u64 block_size_in_bytes, u64 count_to_r
|
||||||
header->block_size_in_bytes = block_size_in_bytes;
|
header->block_size_in_bytes = block_size_in_bytes;
|
||||||
header->valid_count = 0;
|
header->valid_count = 0;
|
||||||
header->allocated_count = count_to_reserve;
|
header->allocated_count = count_to_reserve;
|
||||||
|
header->signature = GROWING_ARRAY_SIGNATURE;
|
||||||
|
|
||||||
*array = header+1;
|
*array = header+1;
|
||||||
}
|
}
|
||||||
|
@ -63,12 +103,14 @@ growing_array_init(void **array, u64 block_size_in_bytes, Allocator allocator) {
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
growing_array_deinit(void **array) {
|
growing_array_deinit(void **array) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
dealloc(header->allocator, header);
|
dealloc(header->allocator, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
growing_array_reserve(void **array, u64 count_to_reserve) {
|
growing_array_reserve(void **array, u64 count_to_reserve) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
|
|
||||||
if (header->allocated_count >= count_to_reserve) return;
|
if (header->allocated_count >= count_to_reserve) return;
|
||||||
|
@ -90,6 +132,7 @@ growing_array_reserve(void **array, u64 count_to_reserve) {
|
||||||
|
|
||||||
void*
|
void*
|
||||||
growing_array_add_empty(void **array) {
|
growing_array_add_empty(void **array) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
growing_array_reserve(array, header->valid_count+1);
|
growing_array_reserve(array, header->valid_count+1);
|
||||||
|
|
||||||
|
@ -119,18 +162,21 @@ void growing_array_resize(void **array, u64 new_count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void growing_array_pop(void **array) {
|
void growing_array_pop(void **array) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
assert(header->valid_count > 0, "No items to pop in growing array");
|
assert(header->valid_count > 0, "No items to pop in growing array");
|
||||||
header->valid_count -= 1;
|
header->valid_count -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void growing_array_clear(void **array) {
|
void growing_array_clear(void **array) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
header->valid_count = 0;
|
header->valid_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
growing_array_ordered_remove_by_index(void **array, u32 index) {
|
growing_array_ordered_remove_by_index(void **array, u32 index) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
assert(index < header->valid_count, "Growing array index out of range");
|
assert(index < header->valid_count, "Growing array index out of range");
|
||||||
|
|
||||||
|
@ -150,6 +196,7 @@ growing_array_ordered_remove_by_index(void **array, u32 index) {
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
growing_array_unordered_remove_by_index(void **array, u32 index) {
|
growing_array_unordered_remove_by_index(void **array, u32 index) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
assert(index < header->valid_count, "Growing array index out of range");
|
assert(index < header->valid_count, "Growing array index out of range");
|
||||||
|
|
||||||
|
@ -171,6 +218,7 @@ growing_array_unordered_remove_by_index(void **array, u32 index) {
|
||||||
|
|
||||||
s32
|
s32
|
||||||
growing_array_find_index_from_left_by_pointer(void **array, void *p) {
|
growing_array_find_index_from_left_by_pointer(void **array, void *p) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
|
|
||||||
for (u32 i = 0; i < header->valid_count; i++) {
|
for (u32 i = 0; i < header->valid_count; i++) {
|
||||||
|
@ -184,6 +232,7 @@ growing_array_find_index_from_left_by_pointer(void **array, void *p) {
|
||||||
}
|
}
|
||||||
s32
|
s32
|
||||||
growing_array_find_index_from_left_by_value(void **array, void *p) {
|
growing_array_find_index_from_left_by_value(void **array, void *p) {
|
||||||
|
assert(check_growing_array_signature(array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)*array) - 1;
|
||||||
|
|
||||||
for (u32 i = 0; i < header->valid_count; i++) {
|
for (u32 i = 0; i < header->valid_count; i++) {
|
||||||
|
@ -251,11 +300,13 @@ growing_array_unordered_remove_one_by_value(void **array, void *p) {
|
||||||
|
|
||||||
u32
|
u32
|
||||||
growing_array_get_valid_count(void *array) {
|
growing_array_get_valid_count(void *array) {
|
||||||
|
assert(check_growing_array_signature(&array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)array) - 1;
|
||||||
return header->valid_count;
|
return header->valid_count;
|
||||||
}
|
}
|
||||||
u32
|
u32
|
||||||
growing_array_get_allocated_count(void *array) {
|
growing_array_get_allocated_count(void *array) {
|
||||||
|
assert(check_growing_array_signature(&array), "Not a valid growing array");
|
||||||
Growing_Array_Header *header = ((Growing_Array_Header*)array) - 1;
|
Growing_Array_Header *header = ((Growing_Array_Header*)array) - 1;
|
||||||
return header->allocated_count;
|
return header->allocated_count;
|
||||||
}
|
}
|
|
@ -396,6 +396,11 @@ void os_init(u64 program_memory_capacity) {
|
||||||
#ifndef OOGABOOGA_HEADLESS
|
#ifndef OOGABOOGA_HEADLESS
|
||||||
win32_init_window();
|
win32_init_window();
|
||||||
|
|
||||||
|
// Set a dummy output format before audio init in case it fails.
|
||||||
|
audio_output_format.sample_rate = 48000;
|
||||||
|
audio_output_format.channels = 2;
|
||||||
|
audio_output_format.bit_width = AUDIO_BITS_32;
|
||||||
|
|
||||||
local_persist Thread audio_thread, audio_poll_default_device_thread;
|
local_persist Thread audio_thread, audio_poll_default_device_thread;
|
||||||
|
|
||||||
os_thread_init(&audio_thread, win32_audio_thread);
|
os_thread_init(&audio_thread, win32_audio_thread);
|
||||||
|
@ -1416,8 +1421,6 @@ const GUID CLSID_MMDeviceEnumerator = {0xbcde0395, 0xe52f, 0x467c, {0x8e,0x3d, 0
|
||||||
const GUID IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
|
const GUID IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
|
||||||
const GUID IID_IAudioClient = {0x1cb9ad4c, 0xdbfa, 0x4c32, {0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2}};
|
const GUID IID_IAudioClient = {0x1cb9ad4c, 0xdbfa, 0x4c32, {0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2}};
|
||||||
const GUID IID_IAudioRenderClient = {0xf294acfc, 0x3146, 0x4483, {0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2}};
|
const GUID IID_IAudioRenderClient = {0xf294acfc, 0x3146, 0x4483, {0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2}};
|
||||||
DEFINE_GUID(IID_ISimpleAudioVolume,
|
|
||||||
0x87CE5498, 0x68D6, 0x44E5, 0x92, 0x15, 0x6D, 0xA4, 0x7E, 0xF8, 0x83, 0xD8);
|
|
||||||
|
|
||||||
IAudioClient* win32_audio_client;
|
IAudioClient* win32_audio_client;
|
||||||
IAudioRenderClient* win32_render_client;
|
IAudioRenderClient* win32_render_client;
|
||||||
|
@ -1425,12 +1428,13 @@ bool win32_audio_deactivated = false;
|
||||||
Audio_Format audio_output_format; // For use when loading audio sources
|
Audio_Format audio_output_format; // For use when loading audio sources
|
||||||
IMMDevice* win32_audio_device = 0;
|
IMMDevice* win32_audio_device = 0;
|
||||||
IMMDeviceEnumerator* win32_device_enumerator = 0;
|
IMMDeviceEnumerator* win32_device_enumerator = 0;
|
||||||
ISimpleAudioVolume* win32_audio_volume = 0;
|
|
||||||
Mutex audio_init_mutex;
|
Mutex audio_init_mutex;
|
||||||
|
|
||||||
void
|
void
|
||||||
win32_audio_init() {
|
win32_audio_init() {
|
||||||
|
|
||||||
|
local_persist bool did_report_error_last_call = false;
|
||||||
|
|
||||||
win32_audio_client = 0;
|
win32_audio_client = 0;
|
||||||
win32_render_client = 0;
|
win32_render_client = 0;
|
||||||
win32_audio_deactivated = 0;
|
win32_audio_deactivated = 0;
|
||||||
|
@ -1502,7 +1506,8 @@ win32_audio_init() {
|
||||||
);
|
);
|
||||||
if (hr != S_OK) {
|
if (hr != S_OK) {
|
||||||
win32_audio_deactivated = true;
|
win32_audio_deactivated = true;
|
||||||
log_error("Default audio output device is not supported.");
|
if (!did_report_error_last_call) log_error("Default audio output device is not supported.");
|
||||||
|
did_report_error_last_call = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
output_format = (WAVEFORMATEX*)format_s16;
|
output_format = (WAVEFORMATEX*)format_s16;
|
||||||
|
@ -1518,6 +1523,12 @@ win32_audio_init() {
|
||||||
BUFFER_DURATION_MS*10000ll, 0,
|
BUFFER_DURATION_MS*10000ll, 0,
|
||||||
output_format, 0
|
output_format, 0
|
||||||
);
|
);
|
||||||
|
if (hr == 0x8889000A) {
|
||||||
|
if (!did_report_error_last_call) log_error("IAudioClient_Initialize failed for default device\nSample rate: %d\nBit-width: %d\n Channels: %d", device_base_format->nSamplesPerSec, device_base_format->wBitsPerSample, device_base_format->nChannels);
|
||||||
|
win32_audio_deactivated = true;
|
||||||
|
did_report_error_last_call = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
win32_check_hr(hr);
|
win32_check_hr(hr);
|
||||||
|
|
||||||
hr = IAudioClient_GetService(win32_audio_client, &IID_IAudioRenderClient, (void**)&win32_render_client);
|
hr = IAudioClient_GetService(win32_audio_client, &IID_IAudioRenderClient, (void**)&win32_render_client);
|
||||||
|
@ -1536,14 +1547,8 @@ win32_audio_init() {
|
||||||
DWORD task_index;
|
DWORD task_index;
|
||||||
AvSetMmThreadCharacteristics(TEXT("Pro Audio"), &task_index);
|
AvSetMmThreadCharacteristics(TEXT("Pro Audio"), &task_index);
|
||||||
|
|
||||||
hr = IAudioClient_GetService(win32_audio_client, &IID_ISimpleAudioVolume, (void**)&win32_audio_volume);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = ISimpleAudioVolume_SetMasterVolume(win32_audio_volume, 1.0f, 0);
|
|
||||||
win32_check_hr(hr);
|
|
||||||
ISimpleAudioVolume_Release(win32_audio_volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info("Successfully initialized default audio device. Channels: %d, sample_rate: %d, bits: %d", audio_output_format.channels, audio_output_format.sample_rate, get_audio_bit_width_byte_size(audio_output_format.bit_width)*8);
|
log_info("Successfully initialized default audio device. Channels: %d, sample_rate: %d, bits: %d", audio_output_format.channels, audio_output_format.sample_rate, get_audio_bit_width_byte_size(audio_output_format.bit_width)*8);
|
||||||
|
did_report_error_last_call = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1574,6 +1579,7 @@ win32_audio_poll_default_device_thread(Thread *t) {
|
||||||
win32_check_hr(hr);
|
win32_check_hr(hr);
|
||||||
|
|
||||||
if (wcscmp(now_default_id, previous_id) != 0) {
|
if (wcscmp(now_default_id, previous_id) != 0) {
|
||||||
|
log("Hi");
|
||||||
win32_audio_deactivated = true;
|
win32_audio_deactivated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue