Stop audio API; switch to float based mixer

This commit is contained in:
Allen Webster 2020-11-23 17:45:04 -08:00
parent a9a1931e34
commit 4f31b9d5aa
12 changed files with 420 additions and 248 deletions

View File

@ -309,6 +309,16 @@ define_api(Arena *arena){
api_param(arena, call, "Audio_Control*", "control"); api_param(arena, call, "Audio_Control*", "control");
} }
{
API_Call *call = api_call(arena, api, "audio_is_playing", "b32");
api_param(arena, call, "Audio_Control*", "control");
}
{
API_Call *call = api_call(arena, api, "audio_stop", "void");
api_param(arena, call, "Audio_Control*", "control");
}
return(api); return(api);
} }

View File

@ -68,6 +68,9 @@ audio_clip_from_wav_data(String_Const_u8 data){
(Format->wChannels == 2) && (Format->wChannels == 2) &&
(Format->wBitsPerSample == 16) && (Format->wBitsPerSample == 16) &&
(Format->dwSamplesPerSec == 48000)){ (Format->dwSamplesPerSec == 48000)){
for (u32 i = 0; i < 2; i += 1){
Result.channel_volume[i] = 1.f;
}
Result.sample_count = SampleDataSize / (Format->wChannels*Format->wBitsPerSample/8); Result.sample_count = SampleDataSize / (Format->wChannels*Format->wBitsPerSample/8);
Result.samples = (i16 *)Samples; Result.samples = (i16 *)Samples;
} }

View File

@ -23,8 +23,8 @@ CUSTOM_DOC("Default command for responding to a startup event")
Audio_Clip test_clip = audio_clip_from_wav_file_name("W:\\4ed\\audio_test\\raygun_zap.wav"); Audio_Clip test_clip = audio_clip_from_wav_file_name("W:\\4ed\\audio_test\\raygun_zap.wav");
local_persist Audio_Control test_control = {}; local_persist Audio_Control test_control = {};
test_control.left_volume_knob = AUDIO_PRODUCER_KNOB_ONE; test_control.channel_volume[0] = 1.f;
test_control.right_volume_knob = AUDIO_PRODUCER_KNOB_ONE; test_control.channel_volume[1] = 1.f;
system_play_clip(test_clip, &test_control); system_play_clip(test_clip, &test_control);
} }
} }

View File

@ -262,6 +262,55 @@ CUSTOM_DOC("If you are reading this I forgot to delete this test, please let me
} }
global Audio_Control the_music_control = {};
CUSTOM_COMMAND_SIG(music_start)
CUSTOM_DOC("Starts the music.")
{
local_persist Audio_Clip the_music_clip = {};
local_persist b32 initialized = false;
if (!initialized){
initialized = true;
the_music_clip = audio_clip_from_wav_file_name("W:\\4ed\\audio_test\\chtulthu.wav");
}
if (!system_audio_is_playing(&the_music_control)){
the_music_control.loop = true;
the_music_control.channel_volume[0] = 1.f;
the_music_control.channel_volume[1] = 1.f;
system_play_clip(the_music_clip, &the_music_control);
}
}
CUSTOM_COMMAND_SIG(music_stop)
CUSTOM_DOC("Stops the music.")
{
system_audio_stop(&the_music_control);
}
CUSTOM_COMMAND_SIG(hit_sfx)
CUSTOM_DOC("Play the hit sound effect")
{
local_persist Audio_Clip the_hit_clip = {};
local_persist b32 initialized = false;
if (!initialized){
initialized = true;
the_hit_clip = audio_clip_from_wav_file_name("W:\\4ed\\audio_test\\hit.wav");
}
local_persist u32 index = 0;
local_persist Audio_Control controls[8] = {};
Audio_Control *control = &controls[index%8];
if (!system_audio_is_playing(control)){
control->loop = false;
control->channel_volume[0] = 1.f;
control->channel_volume[1] = 1.f;
system_play_clip(the_hit_clip, control);
index += 1;
}
}
// BOTTOM // BOTTOM

View File

@ -791,17 +791,17 @@ struct Process_State{
api(custom) api(custom)
struct Audio_Control{ struct Audio_Control{
#define AUDIO_PRODUCER_KNOB_ONE 256 volatile f32 channel_volume[2];
volatile u32 left_volume_knob;
volatile u32 right_volume_knob;
volatile u32 generation; volatile u32 generation;
volatile u32 last_played_sample_index;; volatile u32 last_played_sample_index;
volatile b32 loop;
}; };
api(custom) api(custom)
struct Audio_Clip{ struct Audio_Clip{
i16 *samples; i16 *samples;
Audio_Control *control; Audio_Control *control;
f32 channel_volume[2];
u32 sample_count; u32 sample_count;
u32 at_sample_index; u32 at_sample_index;
@ -814,7 +814,6 @@ struct Audio_System{
volatile u32 serving; volatile u32 serving;
volatile u32 generation; volatile u32 generation;
u32 next_playing_clip_index;
Audio_Clip playing_clips[64]; Audio_Clip playing_clips[64];
// NOTE(casey): Requests to play sounds are written to a pending array to avoid long locking // NOTE(casey): Requests to play sounds are written to a pending array to avoid long locking

View File

@ -2,7 +2,7 @@
#define command_id(c) (fcoder_metacmd_ID_##c) #define command_id(c) (fcoder_metacmd_ID_##c)
#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])
#define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id])
#define command_one_past_last_id 248 #define command_one_past_last_id 251
#if defined(CUSTOM_COMMAND_SIG) #if defined(CUSTOM_COMMAND_SIG)
#define PROC_LINKS(x,y) x #define PROC_LINKS(x,y) x
#else #else
@ -74,6 +74,7 @@ CUSTOM_COMMAND_SIG(goto_prev_jump);
CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips); CUSTOM_COMMAND_SIG(goto_prev_jump_no_skips);
CUSTOM_COMMAND_SIG(hide_filebar); CUSTOM_COMMAND_SIG(hide_filebar);
CUSTOM_COMMAND_SIG(hide_scrollbar); CUSTOM_COMMAND_SIG(hide_scrollbar);
CUSTOM_COMMAND_SIG(hit_sfx);
CUSTOM_COMMAND_SIG(hms_demo_tutorial); CUSTOM_COMMAND_SIG(hms_demo_tutorial);
CUSTOM_COMMAND_SIG(if0_off); CUSTOM_COMMAND_SIG(if0_off);
CUSTOM_COMMAND_SIG(if_read_only_goto_position); CUSTOM_COMMAND_SIG(if_read_only_goto_position);
@ -148,6 +149,8 @@ CUSTOM_COMMAND_SIG(move_up_to_blank_line_skip_whitespace);
CUSTOM_COMMAND_SIG(multi_paste); CUSTOM_COMMAND_SIG(multi_paste);
CUSTOM_COMMAND_SIG(multi_paste_interactive); CUSTOM_COMMAND_SIG(multi_paste_interactive);
CUSTOM_COMMAND_SIG(multi_paste_interactive_quick); CUSTOM_COMMAND_SIG(multi_paste_interactive_quick);
CUSTOM_COMMAND_SIG(music_start);
CUSTOM_COMMAND_SIG(music_stop);
CUSTOM_COMMAND_SIG(open_all_code); CUSTOM_COMMAND_SIG(open_all_code);
CUSTOM_COMMAND_SIG(open_all_code_recursive); CUSTOM_COMMAND_SIG(open_all_code_recursive);
CUSTOM_COMMAND_SIG(open_file_in_quotes); CUSTOM_COMMAND_SIG(open_file_in_quotes);
@ -269,7 +272,7 @@ char *source_name;
i32 source_name_len; i32 source_name_len;
i32 line_number; i32 line_number;
}; };
static Command_Metadata fcoder_metacmd_table[248] = { static Command_Metadata fcoder_metacmd_table[251] = {
{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 485 }, { PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 485 },
{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 417 }, { PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 417 },
{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 427 }, { PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 427 },
@ -335,6 +338,7 @@ static Command_Metadata fcoder_metacmd_table[248] = {
{ PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 511 }, { PROC_LINKS(goto_prev_jump_no_skips, 0), false, "goto_prev_jump_no_skips", 23, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 511 },
{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 704 }, { PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 704 },
{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 690 }, { PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 690 },
{ PROC_LINKS(hit_sfx, 0), false, "hit_sfx", 7, "Play the hit sound effect", 25, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 291 },
{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 869 }, { PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "W:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 869 },
{ PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 70 }, { PROC_LINKS(if0_off, 0), false, "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 70 },
{ PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 564 }, { PROC_LINKS(if_read_only_goto_position, 0), false, "if_read_only_goto_position", 26, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "W:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 564 },
@ -409,6 +413,8 @@ static Command_Metadata fcoder_metacmd_table[248] = {
{ PROC_LINKS(multi_paste, 0), false, "multi_paste", 11, "Paste multiple entries from the clipboard at once", 49, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 229 }, { PROC_LINKS(multi_paste, 0), false, "multi_paste", 11, "Paste multiple entries from the clipboard at once", 49, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 229 },
{ PROC_LINKS(multi_paste_interactive, 0), false, "multi_paste_interactive", 23, "Paste multiple lines from the clipboard history, controlled with arrow keys", 75, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 371 }, { PROC_LINKS(multi_paste_interactive, 0), false, "multi_paste_interactive", 23, "Paste multiple lines from the clipboard history, controlled with arrow keys", 75, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 371 },
{ PROC_LINKS(multi_paste_interactive_quick, 0), false, "multi_paste_interactive_quick", 29, "Paste multiple lines from the clipboard history, controlled by inputing the number of lines to paste", 100, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 380 }, { PROC_LINKS(multi_paste_interactive_quick, 0), false, "multi_paste_interactive_quick", 29, "Paste multiple lines from the clipboard history, controlled by inputing the number of lines to paste", 100, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 380 },
{ PROC_LINKS(music_start, 0), false, "music_start", 11, "Starts the music.", 17, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 267 },
{ PROC_LINKS(music_stop, 0), false, "music_stop", 10, "Stops the music.", 16, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 285 },
{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 850 }, { PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 850 },
{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 856 }, { PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 856 },
{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1574 }, { PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1574 },
@ -584,187 +590,190 @@ static i32 fcoder_metacmd_ID_goto_prev_jump = 61;
static i32 fcoder_metacmd_ID_goto_prev_jump_no_skips = 62; static i32 fcoder_metacmd_ID_goto_prev_jump_no_skips = 62;
static i32 fcoder_metacmd_ID_hide_filebar = 63; static i32 fcoder_metacmd_ID_hide_filebar = 63;
static i32 fcoder_metacmd_ID_hide_scrollbar = 64; static i32 fcoder_metacmd_ID_hide_scrollbar = 64;
static i32 fcoder_metacmd_ID_hms_demo_tutorial = 65; static i32 fcoder_metacmd_ID_hit_sfx = 65;
static i32 fcoder_metacmd_ID_if0_off = 66; static i32 fcoder_metacmd_ID_hms_demo_tutorial = 66;
static i32 fcoder_metacmd_ID_if_read_only_goto_position = 67; static i32 fcoder_metacmd_ID_if0_off = 67;
static i32 fcoder_metacmd_ID_if_read_only_goto_position_same_panel = 68; static i32 fcoder_metacmd_ID_if_read_only_goto_position = 68;
static i32 fcoder_metacmd_ID_increase_face_size = 69; static i32 fcoder_metacmd_ID_if_read_only_goto_position_same_panel = 69;
static i32 fcoder_metacmd_ID_interactive_kill_buffer = 70; static i32 fcoder_metacmd_ID_increase_face_size = 70;
static i32 fcoder_metacmd_ID_interactive_new = 71; static i32 fcoder_metacmd_ID_interactive_kill_buffer = 71;
static i32 fcoder_metacmd_ID_interactive_open = 72; static i32 fcoder_metacmd_ID_interactive_new = 72;
static i32 fcoder_metacmd_ID_interactive_open_or_new = 73; static i32 fcoder_metacmd_ID_interactive_open = 73;
static i32 fcoder_metacmd_ID_interactive_switch_buffer = 74; static i32 fcoder_metacmd_ID_interactive_open_or_new = 74;
static i32 fcoder_metacmd_ID_jump_to_definition = 75; static i32 fcoder_metacmd_ID_interactive_switch_buffer = 75;
static i32 fcoder_metacmd_ID_jump_to_definition_at_cursor = 76; static i32 fcoder_metacmd_ID_jump_to_definition = 76;
static i32 fcoder_metacmd_ID_jump_to_last_point = 77; static i32 fcoder_metacmd_ID_jump_to_definition_at_cursor = 77;
static i32 fcoder_metacmd_ID_keyboard_macro_finish_recording = 78; static i32 fcoder_metacmd_ID_jump_to_last_point = 78;
static i32 fcoder_metacmd_ID_keyboard_macro_replay = 79; static i32 fcoder_metacmd_ID_keyboard_macro_finish_recording = 79;
static i32 fcoder_metacmd_ID_keyboard_macro_start_recording = 80; static i32 fcoder_metacmd_ID_keyboard_macro_replay = 80;
static i32 fcoder_metacmd_ID_kill_buffer = 81; static i32 fcoder_metacmd_ID_keyboard_macro_start_recording = 81;
static i32 fcoder_metacmd_ID_kill_tutorial = 82; static i32 fcoder_metacmd_ID_kill_buffer = 82;
static i32 fcoder_metacmd_ID_left_adjust_view = 83; static i32 fcoder_metacmd_ID_kill_tutorial = 83;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 84; static i32 fcoder_metacmd_ID_left_adjust_view = 84;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 85; static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 85;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 86; static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 86;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 87; static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 87;
static i32 fcoder_metacmd_ID_list_all_locations = 88; static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 88;
static i32 fcoder_metacmd_ID_list_all_locations_case_insensitive = 89; static i32 fcoder_metacmd_ID_list_all_locations = 89;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier = 90; static i32 fcoder_metacmd_ID_list_all_locations_case_insensitive = 90;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 91; static i32 fcoder_metacmd_ID_list_all_locations_of_identifier = 91;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection = 92; static i32 fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 92;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 93; static i32 fcoder_metacmd_ID_list_all_locations_of_selection = 93;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition = 94; static i32 fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 94;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 95; static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition = 95;
static i32 fcoder_metacmd_ID_list_all_substring_locations = 96; static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 96;
static i32 fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 97; static i32 fcoder_metacmd_ID_list_all_substring_locations = 97;
static i32 fcoder_metacmd_ID_load_project = 98; static i32 fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 98;
static i32 fcoder_metacmd_ID_load_theme_current_buffer = 99; static i32 fcoder_metacmd_ID_load_project = 99;
static i32 fcoder_metacmd_ID_load_themes_default_folder = 100; static i32 fcoder_metacmd_ID_load_theme_current_buffer = 100;
static i32 fcoder_metacmd_ID_load_themes_hot_directory = 101; static i32 fcoder_metacmd_ID_load_themes_default_folder = 101;
static i32 fcoder_metacmd_ID_make_directory_query = 102; static i32 fcoder_metacmd_ID_load_themes_hot_directory = 102;
static i32 fcoder_metacmd_ID_miblo_decrement_basic = 103; static i32 fcoder_metacmd_ID_make_directory_query = 103;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 104; static i32 fcoder_metacmd_ID_miblo_decrement_basic = 104;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 105; static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 105;
static i32 fcoder_metacmd_ID_miblo_increment_basic = 106; static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 106;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 107; static i32 fcoder_metacmd_ID_miblo_increment_basic = 107;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 108; static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 108;
static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 109; static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 109;
static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 110; static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 110;
static i32 fcoder_metacmd_ID_move_down = 111; static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 111;
static i32 fcoder_metacmd_ID_move_down_10 = 112; static i32 fcoder_metacmd_ID_move_down = 112;
static i32 fcoder_metacmd_ID_move_down_textual = 113; static i32 fcoder_metacmd_ID_move_down_10 = 113;
static i32 fcoder_metacmd_ID_move_down_to_blank_line = 114; static i32 fcoder_metacmd_ID_move_down_textual = 114;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 115; static i32 fcoder_metacmd_ID_move_down_to_blank_line = 115;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 116; static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 116;
static i32 fcoder_metacmd_ID_move_left = 117; static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 117;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 118; static i32 fcoder_metacmd_ID_move_left = 118;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 119; static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 119;
static i32 fcoder_metacmd_ID_move_left_token_boundary = 120; static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 120;
static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 121; static i32 fcoder_metacmd_ID_move_left_token_boundary = 121;
static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 122; static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 122;
static i32 fcoder_metacmd_ID_move_line_down = 123; static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 123;
static i32 fcoder_metacmd_ID_move_line_up = 124; static i32 fcoder_metacmd_ID_move_line_down = 124;
static i32 fcoder_metacmd_ID_move_right = 125; static i32 fcoder_metacmd_ID_move_line_up = 125;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 126; static i32 fcoder_metacmd_ID_move_right = 126;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 127; static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 127;
static i32 fcoder_metacmd_ID_move_right_token_boundary = 128; static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 128;
static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 129; static i32 fcoder_metacmd_ID_move_right_token_boundary = 129;
static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 130; static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 130;
static i32 fcoder_metacmd_ID_move_up = 131; static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 131;
static i32 fcoder_metacmd_ID_move_up_10 = 132; static i32 fcoder_metacmd_ID_move_up = 132;
static i32 fcoder_metacmd_ID_move_up_to_blank_line = 133; static i32 fcoder_metacmd_ID_move_up_10 = 133;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 134; static i32 fcoder_metacmd_ID_move_up_to_blank_line = 134;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 135; static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 135;
static i32 fcoder_metacmd_ID_multi_paste = 136; static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 136;
static i32 fcoder_metacmd_ID_multi_paste_interactive = 137; static i32 fcoder_metacmd_ID_multi_paste = 137;
static i32 fcoder_metacmd_ID_multi_paste_interactive_quick = 138; static i32 fcoder_metacmd_ID_multi_paste_interactive = 138;
static i32 fcoder_metacmd_ID_open_all_code = 139; static i32 fcoder_metacmd_ID_multi_paste_interactive_quick = 139;
static i32 fcoder_metacmd_ID_open_all_code_recursive = 140; static i32 fcoder_metacmd_ID_music_start = 140;
static i32 fcoder_metacmd_ID_open_file_in_quotes = 141; static i32 fcoder_metacmd_ID_music_stop = 141;
static i32 fcoder_metacmd_ID_open_in_other = 142; static i32 fcoder_metacmd_ID_open_all_code = 142;
static i32 fcoder_metacmd_ID_open_long_braces = 143; static i32 fcoder_metacmd_ID_open_all_code_recursive = 143;
static i32 fcoder_metacmd_ID_open_long_braces_break = 144; static i32 fcoder_metacmd_ID_open_file_in_quotes = 144;
static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 145; static i32 fcoder_metacmd_ID_open_in_other = 145;
static i32 fcoder_metacmd_ID_open_matching_file_cpp = 146; static i32 fcoder_metacmd_ID_open_long_braces = 146;
static i32 fcoder_metacmd_ID_open_panel_hsplit = 147; static i32 fcoder_metacmd_ID_open_long_braces_break = 147;
static i32 fcoder_metacmd_ID_open_panel_vsplit = 148; static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 148;
static i32 fcoder_metacmd_ID_page_down = 149; static i32 fcoder_metacmd_ID_open_matching_file_cpp = 149;
static i32 fcoder_metacmd_ID_page_up = 150; static i32 fcoder_metacmd_ID_open_panel_hsplit = 150;
static i32 fcoder_metacmd_ID_paste = 151; static i32 fcoder_metacmd_ID_open_panel_vsplit = 151;
static i32 fcoder_metacmd_ID_paste_and_indent = 152; static i32 fcoder_metacmd_ID_page_down = 152;
static i32 fcoder_metacmd_ID_paste_next = 153; static i32 fcoder_metacmd_ID_page_up = 153;
static i32 fcoder_metacmd_ID_paste_next_and_indent = 154; static i32 fcoder_metacmd_ID_paste = 154;
static i32 fcoder_metacmd_ID_place_in_scope = 155; static i32 fcoder_metacmd_ID_paste_and_indent = 155;
static i32 fcoder_metacmd_ID_play_with_a_counter = 156; static i32 fcoder_metacmd_ID_paste_next = 156;
static i32 fcoder_metacmd_ID_profile_clear = 157; static i32 fcoder_metacmd_ID_paste_next_and_indent = 157;
static i32 fcoder_metacmd_ID_profile_disable = 158; static i32 fcoder_metacmd_ID_place_in_scope = 158;
static i32 fcoder_metacmd_ID_profile_enable = 159; static i32 fcoder_metacmd_ID_play_with_a_counter = 159;
static i32 fcoder_metacmd_ID_profile_inspect = 160; static i32 fcoder_metacmd_ID_profile_clear = 160;
static i32 fcoder_metacmd_ID_project_command_lister = 161; static i32 fcoder_metacmd_ID_profile_disable = 161;
static i32 fcoder_metacmd_ID_project_fkey_command = 162; static i32 fcoder_metacmd_ID_profile_enable = 162;
static i32 fcoder_metacmd_ID_project_go_to_root_directory = 163; static i32 fcoder_metacmd_ID_profile_inspect = 163;
static i32 fcoder_metacmd_ID_query_replace = 164; static i32 fcoder_metacmd_ID_project_command_lister = 164;
static i32 fcoder_metacmd_ID_query_replace_identifier = 165; static i32 fcoder_metacmd_ID_project_fkey_command = 165;
static i32 fcoder_metacmd_ID_query_replace_selection = 166; static i32 fcoder_metacmd_ID_project_go_to_root_directory = 166;
static i32 fcoder_metacmd_ID_quick_swap_buffer = 167; static i32 fcoder_metacmd_ID_query_replace = 167;
static i32 fcoder_metacmd_ID_redo = 168; static i32 fcoder_metacmd_ID_query_replace_identifier = 168;
static i32 fcoder_metacmd_ID_redo_all_buffers = 169; static i32 fcoder_metacmd_ID_query_replace_selection = 169;
static i32 fcoder_metacmd_ID_rename_file_query = 170; static i32 fcoder_metacmd_ID_quick_swap_buffer = 170;
static i32 fcoder_metacmd_ID_reopen = 171; static i32 fcoder_metacmd_ID_redo = 171;
static i32 fcoder_metacmd_ID_replace_in_all_buffers = 172; static i32 fcoder_metacmd_ID_redo_all_buffers = 172;
static i32 fcoder_metacmd_ID_replace_in_buffer = 173; static i32 fcoder_metacmd_ID_rename_file_query = 173;
static i32 fcoder_metacmd_ID_replace_in_range = 174; static i32 fcoder_metacmd_ID_reopen = 174;
static i32 fcoder_metacmd_ID_reverse_search = 175; static i32 fcoder_metacmd_ID_replace_in_all_buffers = 175;
static i32 fcoder_metacmd_ID_reverse_search_identifier = 176; static i32 fcoder_metacmd_ID_replace_in_buffer = 176;
static i32 fcoder_metacmd_ID_save = 177; static i32 fcoder_metacmd_ID_replace_in_range = 177;
static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 178; static i32 fcoder_metacmd_ID_reverse_search = 178;
static i32 fcoder_metacmd_ID_save_to_query = 179; static i32 fcoder_metacmd_ID_reverse_search_identifier = 179;
static i32 fcoder_metacmd_ID_search = 180; static i32 fcoder_metacmd_ID_save = 180;
static i32 fcoder_metacmd_ID_search_identifier = 181; static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 181;
static i32 fcoder_metacmd_ID_seek_beginning_of_line = 182; static i32 fcoder_metacmd_ID_save_to_query = 182;
static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 183; static i32 fcoder_metacmd_ID_search = 183;
static i32 fcoder_metacmd_ID_seek_end_of_line = 184; static i32 fcoder_metacmd_ID_search_identifier = 184;
static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 185; static i32 fcoder_metacmd_ID_seek_beginning_of_line = 185;
static i32 fcoder_metacmd_ID_select_all = 186; static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 186;
static i32 fcoder_metacmd_ID_select_next_scope_absolute = 187; static i32 fcoder_metacmd_ID_seek_end_of_line = 187;
static i32 fcoder_metacmd_ID_select_next_scope_after_current = 188; static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 188;
static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 189; static i32 fcoder_metacmd_ID_select_all = 189;
static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 190; static i32 fcoder_metacmd_ID_select_next_scope_absolute = 190;
static i32 fcoder_metacmd_ID_select_surrounding_scope = 191; static i32 fcoder_metacmd_ID_select_next_scope_after_current = 191;
static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 192; static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 192;
static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 193; static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 193;
static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 194; static i32 fcoder_metacmd_ID_select_surrounding_scope = 194;
static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 195; static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 195;
static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 196; static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 196;
static i32 fcoder_metacmd_ID_set_face_size = 197; static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 197;
static i32 fcoder_metacmd_ID_set_face_size_this_buffer = 198; static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 198;
static i32 fcoder_metacmd_ID_set_mark = 199; static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 199;
static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 200; static i32 fcoder_metacmd_ID_set_face_size = 200;
static i32 fcoder_metacmd_ID_set_mode_to_original = 201; static i32 fcoder_metacmd_ID_set_face_size_this_buffer = 201;
static i32 fcoder_metacmd_ID_setup_build_bat = 202; static i32 fcoder_metacmd_ID_set_mark = 202;
static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 203; static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 203;
static i32 fcoder_metacmd_ID_setup_build_sh = 204; static i32 fcoder_metacmd_ID_set_mode_to_original = 204;
static i32 fcoder_metacmd_ID_setup_new_project = 205; static i32 fcoder_metacmd_ID_setup_build_bat = 205;
static i32 fcoder_metacmd_ID_show_filebar = 206; static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 206;
static i32 fcoder_metacmd_ID_show_scrollbar = 207; static i32 fcoder_metacmd_ID_setup_build_sh = 207;
static i32 fcoder_metacmd_ID_show_the_log_graph = 208; static i32 fcoder_metacmd_ID_setup_new_project = 208;
static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 209; static i32 fcoder_metacmd_ID_show_filebar = 209;
static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 210; static i32 fcoder_metacmd_ID_show_scrollbar = 210;
static i32 fcoder_metacmd_ID_snippet_lister = 211; static i32 fcoder_metacmd_ID_show_the_log_graph = 211;
static i32 fcoder_metacmd_ID_string_repeat = 212; static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 212;
static i32 fcoder_metacmd_ID_suppress_mouse = 213; static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 213;
static i32 fcoder_metacmd_ID_swap_panels = 214; static i32 fcoder_metacmd_ID_snippet_lister = 214;
static i32 fcoder_metacmd_ID_test_the_new_api = 215; static i32 fcoder_metacmd_ID_string_repeat = 215;
static i32 fcoder_metacmd_ID_theme_lister = 216; static i32 fcoder_metacmd_ID_suppress_mouse = 216;
static i32 fcoder_metacmd_ID_to_lowercase = 217; static i32 fcoder_metacmd_ID_swap_panels = 217;
static i32 fcoder_metacmd_ID_to_uppercase = 218; static i32 fcoder_metacmd_ID_test_the_new_api = 218;
static i32 fcoder_metacmd_ID_toggle_filebar = 219; static i32 fcoder_metacmd_ID_theme_lister = 219;
static i32 fcoder_metacmd_ID_toggle_fps_meter = 220; static i32 fcoder_metacmd_ID_to_lowercase = 220;
static i32 fcoder_metacmd_ID_toggle_fullscreen = 221; static i32 fcoder_metacmd_ID_to_uppercase = 221;
static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 222; static i32 fcoder_metacmd_ID_toggle_filebar = 222;
static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 223; static i32 fcoder_metacmd_ID_toggle_fps_meter = 223;
static i32 fcoder_metacmd_ID_toggle_line_numbers = 224; static i32 fcoder_metacmd_ID_toggle_fullscreen = 224;
static i32 fcoder_metacmd_ID_toggle_line_wrap = 225; static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 225;
static i32 fcoder_metacmd_ID_toggle_mouse = 226; static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 226;
static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 227; static i32 fcoder_metacmd_ID_toggle_line_numbers = 227;
static i32 fcoder_metacmd_ID_toggle_show_whitespace = 228; static i32 fcoder_metacmd_ID_toggle_line_wrap = 228;
static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 229; static i32 fcoder_metacmd_ID_toggle_mouse = 229;
static i32 fcoder_metacmd_ID_tutorial_maximize = 230; static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 230;
static i32 fcoder_metacmd_ID_tutorial_minimize = 231; static i32 fcoder_metacmd_ID_toggle_show_whitespace = 231;
static i32 fcoder_metacmd_ID_uncomment_line = 232; static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 232;
static i32 fcoder_metacmd_ID_undo = 233; static i32 fcoder_metacmd_ID_tutorial_maximize = 233;
static i32 fcoder_metacmd_ID_undo_all_buffers = 234; static i32 fcoder_metacmd_ID_tutorial_minimize = 234;
static i32 fcoder_metacmd_ID_view_buffer_other_panel = 235; static i32 fcoder_metacmd_ID_uncomment_line = 235;
static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 236; static i32 fcoder_metacmd_ID_undo = 236;
static i32 fcoder_metacmd_ID_word_complete = 237; static i32 fcoder_metacmd_ID_undo_all_buffers = 237;
static i32 fcoder_metacmd_ID_word_complete_drop_down = 238; static i32 fcoder_metacmd_ID_view_buffer_other_panel = 238;
static i32 fcoder_metacmd_ID_write_block = 239; static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 239;
static i32 fcoder_metacmd_ID_write_hack = 240; static i32 fcoder_metacmd_ID_word_complete = 240;
static i32 fcoder_metacmd_ID_write_note = 241; static i32 fcoder_metacmd_ID_word_complete_drop_down = 241;
static i32 fcoder_metacmd_ID_write_space = 242; static i32 fcoder_metacmd_ID_write_block = 242;
static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 243; static i32 fcoder_metacmd_ID_write_hack = 243;
static i32 fcoder_metacmd_ID_write_text_input = 244; static i32 fcoder_metacmd_ID_write_note = 244;
static i32 fcoder_metacmd_ID_write_todo = 245; static i32 fcoder_metacmd_ID_write_space = 245;
static i32 fcoder_metacmd_ID_write_underscore = 246; static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 246;
static i32 fcoder_metacmd_ID_write_zero_struct = 247; static i32 fcoder_metacmd_ID_write_text_input = 247;
static i32 fcoder_metacmd_ID_write_todo = 248;
static i32 fcoder_metacmd_ID_write_underscore = 249;
static i32 fcoder_metacmd_ID_write_zero_struct = 250;
#endif #endif

View File

@ -55,6 +55,8 @@ vtable->is_fullscreen = system_is_fullscreen;
vtable->get_keyboard_modifiers = system_get_keyboard_modifiers; vtable->get_keyboard_modifiers = system_get_keyboard_modifiers;
vtable->set_key_mode = system_set_key_mode; vtable->set_key_mode = system_set_key_mode;
vtable->play_clip = system_play_clip; vtable->play_clip = system_play_clip;
vtable->audio_is_playing = system_audio_is_playing;
vtable->audio_stop = system_audio_stop;
} }
#if defined(DYNAMIC_LINK_API) #if defined(DYNAMIC_LINK_API)
function void function void
@ -114,6 +116,8 @@ system_is_fullscreen = vtable->is_fullscreen;
system_get_keyboard_modifiers = vtable->get_keyboard_modifiers; system_get_keyboard_modifiers = vtable->get_keyboard_modifiers;
system_set_key_mode = vtable->set_key_mode; system_set_key_mode = vtable->set_key_mode;
system_play_clip = vtable->play_clip; system_play_clip = vtable->play_clip;
system_audio_is_playing = vtable->audio_is_playing;
system_audio_stop = vtable->audio_stop;
} }
#undef DYNAMIC_LINK_API #undef DYNAMIC_LINK_API
#endif #endif

View File

@ -53,6 +53,8 @@
#define system_get_keyboard_modifiers_sig() Input_Modifier_Set system_get_keyboard_modifiers(Arena* arena) #define system_get_keyboard_modifiers_sig() Input_Modifier_Set system_get_keyboard_modifiers(Arena* arena)
#define system_set_key_mode_sig() void system_set_key_mode(Key_Mode mode) #define system_set_key_mode_sig() void system_set_key_mode(Key_Mode mode)
#define system_play_clip_sig() void system_play_clip(Audio_Clip clip, Audio_Control* control) #define system_play_clip_sig() void system_play_clip(Audio_Clip clip, Audio_Control* control)
#define system_audio_is_playing_sig() b32 system_audio_is_playing(Audio_Control* control)
#define system_audio_stop_sig() void system_audio_stop(Audio_Control* control)
typedef String_Const_u8 system_get_path_type(Arena* arena, System_Path_Code path_code); typedef String_Const_u8 system_get_path_type(Arena* arena, System_Path_Code path_code);
typedef String_Const_u8 system_get_canonical_type(Arena* arena, String_Const_u8 name); typedef String_Const_u8 system_get_canonical_type(Arena* arena, String_Const_u8 name);
typedef File_List system_get_file_list_type(Arena* arena, String_Const_u8 directory); typedef File_List system_get_file_list_type(Arena* arena, String_Const_u8 directory);
@ -108,6 +110,8 @@ typedef b32 system_is_fullscreen_type(void);
typedef Input_Modifier_Set system_get_keyboard_modifiers_type(Arena* arena); typedef Input_Modifier_Set system_get_keyboard_modifiers_type(Arena* arena);
typedef void system_set_key_mode_type(Key_Mode mode); typedef void system_set_key_mode_type(Key_Mode mode);
typedef void system_play_clip_type(Audio_Clip clip, Audio_Control* control); typedef void system_play_clip_type(Audio_Clip clip, Audio_Control* control);
typedef b32 system_audio_is_playing_type(Audio_Control* control);
typedef void system_audio_stop_type(Audio_Control* control);
struct API_VTable_system{ struct API_VTable_system{
system_get_path_type *get_path; system_get_path_type *get_path;
system_get_canonical_type *get_canonical; system_get_canonical_type *get_canonical;
@ -164,6 +168,8 @@ system_is_fullscreen_type *is_fullscreen;
system_get_keyboard_modifiers_type *get_keyboard_modifiers; system_get_keyboard_modifiers_type *get_keyboard_modifiers;
system_set_key_mode_type *set_key_mode; system_set_key_mode_type *set_key_mode;
system_play_clip_type *play_clip; system_play_clip_type *play_clip;
system_audio_is_playing_type *audio_is_playing;
system_audio_stop_type *audio_stop;
}; };
#if defined(STATIC_LINK_API) #if defined(STATIC_LINK_API)
internal String_Const_u8 system_get_path(Arena* arena, System_Path_Code path_code); internal String_Const_u8 system_get_path(Arena* arena, System_Path_Code path_code);
@ -221,6 +227,8 @@ internal b32 system_is_fullscreen(void);
internal Input_Modifier_Set system_get_keyboard_modifiers(Arena* arena); internal Input_Modifier_Set system_get_keyboard_modifiers(Arena* arena);
internal void system_set_key_mode(Key_Mode mode); internal void system_set_key_mode(Key_Mode mode);
internal void system_play_clip(Audio_Clip clip, Audio_Control* control); internal void system_play_clip(Audio_Clip clip, Audio_Control* control);
internal b32 system_audio_is_playing(Audio_Control* control);
internal void system_audio_stop(Audio_Control* control);
#undef STATIC_LINK_API #undef STATIC_LINK_API
#elif defined(DYNAMIC_LINK_API) #elif defined(DYNAMIC_LINK_API)
global system_get_path_type *system_get_path = 0; global system_get_path_type *system_get_path = 0;
@ -278,5 +286,7 @@ global system_is_fullscreen_type *system_is_fullscreen = 0;
global system_get_keyboard_modifiers_type *system_get_keyboard_modifiers = 0; global system_get_keyboard_modifiers_type *system_get_keyboard_modifiers = 0;
global system_set_key_mode_type *system_set_key_mode = 0; global system_set_key_mode_type *system_set_key_mode = 0;
global system_play_clip_type *system_play_clip = 0; global system_play_clip_type *system_play_clip = 0;
global system_audio_is_playing_type *system_audio_is_playing = 0;
global system_audio_stop_type *system_audio_stop = 0;
#undef DYNAMIC_LINK_API #undef DYNAMIC_LINK_API
#endif #endif

View File

@ -250,5 +250,13 @@ API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("play_c
api_param(arena, call, "Audio_Clip", "clip"); api_param(arena, call, "Audio_Clip", "clip");
api_param(arena, call, "Audio_Control*", "control"); api_param(arena, call, "Audio_Control*", "control");
} }
{
API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("audio_is_playing"), string_u8_litexpr("b32"), string_u8_litexpr(""));
api_param(arena, call, "Audio_Control*", "control");
}
{
API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("audio_stop"), string_u8_litexpr("void"), string_u8_litexpr(""));
api_param(arena, call, "Audio_Control*", "control");
}
return(result); return(result);
} }

View File

@ -53,3 +53,5 @@ api(system) function b32 is_fullscreen(void);
api(system) function Input_Modifier_Set get_keyboard_modifiers(Arena* arena); api(system) function Input_Modifier_Set get_keyboard_modifiers(Arena* arena);
api(system) function void set_key_mode(Key_Mode mode); api(system) function void set_key_mode(Key_Mode mode);
api(system) function void play_clip(Audio_Clip clip, Audio_Control* control); api(system) function void play_clip(Audio_Clip clip, Audio_Control* control);
api(system) function b32 audio_is_playing(Audio_Control* control);
api(system) function void audio_stop(Audio_Control* control);

View File

@ -359,14 +359,6 @@ system_set_key_mode_sig(){
win32vars.key_mode = mode; win32vars.key_mode = mode;
} }
////////////////////////////////
// NOTE(allen): Audio
internal
system_play_clip_sig(){
win32_play_clip(clip, control);
}
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Clipboard // NOTE(allen): Clipboard

View File

@ -1,5 +1,5 @@
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Win32 Audio Functions // NOTE(allen): Win32 Audio Helpers
function u32 function u32
AtomicAddU32AndReturnOriginal(u32 volatile *Value, u32 Addend) AtomicAddU32AndReturnOriginal(u32 volatile *Value, u32 Addend)
@ -22,8 +22,11 @@ win32_end_ticket_mutex(Audio_System *Crunky)
AtomicAddU32AndReturnOriginal(&Crunky->serving, 1); AtomicAddU32AndReturnOriginal(&Crunky->serving, 1);
} }
function void ////////////////////////////////
win32_play_clip(Audio_Clip clip, Audio_Control *control){ // NOTE(allen): Win32 Audio System API
internal
system_play_clip_sig(){
clip.control = control; clip.control = control;
Audio_System *Crunky = &win32vars.audio_system; Audio_System *Crunky = &win32vars.audio_system;
win32_begin_ticket_mutex(Crunky); win32_begin_ticket_mutex(Crunky);
@ -34,60 +37,127 @@ win32_play_clip(Audio_Clip clip, Audio_Control *control){
win32_end_ticket_mutex(Crunky); win32_end_ticket_mutex(Crunky);
} }
function void internal
win32_mix_audio(Audio_System *Crunky, u32 SampleCount, i16 *Dest){ system_audio_is_playing_sig(){
// NOTE(casey): Move pending sounds into the playing list Audio_System *Crunky = (Audio_System *)&win32vars.audio_system;
b32 result = (Crunky->generation - control->generation < 2);
return(result);
}
internal
system_audio_stop_sig(){
Audio_System *Crunky = (Audio_System *)&win32vars.audio_system;
win32_begin_ticket_mutex(Crunky); win32_begin_ticket_mutex(Crunky);
++Crunky->generation;
for(u32 PendIndex = 0; Audio_Clip *clip = Crunky->playing_clips;
PendIndex < Crunky->pending_clip_count; for(u32 i = 0;
++PendIndex) i < ArrayCount(Crunky->playing_clips);
i += 1, clip += 1){
if (clip->control == control){
clip->at_sample_index = clip->sample_count;
}
}
control->loop = false;
win32_end_ticket_mutex(Crunky);
}
////////////////////////////////
// NOTE(allen): Win32 Audio Loop
function void
win32_mix_audio(Audio_System *Crunky, u32 SampleCount, i16 *Dest, void *mix_buffer_memory){
// NOTE(casey): Clear the output buffer
u32 MixBufferSize = SampleCount*2*sizeof(f32);
f32 *MixBuffer = (f32 *)mix_buffer_memory;
memset(MixBuffer, 0, MixBufferSize);
win32_begin_ticket_mutex(Crunky);
// NOTE(casey): Move pending sounds into the playing list
{ {
u32 DestIndex = Crunky->next_playing_clip_index++ % ArrayCount(Crunky->playing_clips); Crunky->generation += 1;
Crunky->playing_clips[DestIndex] = Crunky->pending_clips[PendIndex]; u32 PendIndex = 0;
Audio_Clip *clip = Crunky->playing_clips;
for(u32 DestIndex = 0;
(DestIndex < ArrayCount(Crunky->playing_clips)) && (PendIndex < Crunky->pending_clip_count);
DestIndex += 1, clip += 1)
{
if (clip->at_sample_index == clip->sample_count)
{
Audio_Control *control = clip->control;
if (control == 0 || !control->loop){
*clip = Crunky->pending_clips[PendIndex++];
}
}
} }
Crunky->pending_clip_count = 0; Crunky->pending_clip_count = 0;
}
win32_end_ticket_mutex(Crunky); win32_end_ticket_mutex(Crunky);
memset(Dest, 0, SampleCount*4); // NOTE(casey): Mix all sounds into the output buffer
{
Audio_Clip *clip = Crunky->playing_clips;
for(u32 SoundIndex = 0; for(u32 SoundIndex = 0;
SoundIndex < ArrayCount(Crunky->playing_clips); SoundIndex < ArrayCount(Crunky->playing_clips);
++SoundIndex) SoundIndex += 1, clip += 1)
{ {
Audio_Clip Sound = Crunky->playing_clips[SoundIndex]; Audio_Control *control = clip->control;
u32 SamplesToMix = Min((Sound.sample_count - Sound.at_sample_index), SampleCount); if (control != 0 && control->loop && clip->at_sample_index == clip->sample_count){
Crunky->playing_clips[SoundIndex].at_sample_index += SamplesToMix; clip->at_sample_index = 0;
i32 LeftVol = AUDIO_PRODUCER_KNOB_ONE;
i32 RightVol = AUDIO_PRODUCER_KNOB_ONE;
if(SamplesToMix && Sound.control)
{
LeftVol = Sound.control->left_volume_knob;
RightVol = Sound.control->right_volume_knob;
Sound.control->generation = Crunky->generation;
Sound.control->last_played_sample_index = Crunky->playing_clips[SoundIndex].at_sample_index;
} }
// NOTE(casey): Determine how many samples are left to play in this
// sound (possible none)
u32 SamplesToMix = Min((clip->sample_count - clip->at_sample_index), SampleCount);
clip->at_sample_index += SamplesToMix;
// NOTE(casey): Load the volume out of the control if there is one,
// and if there is, update the generation and sample index so
// external controllers can take action
f32 LeftVol = clip->channel_volume[0];
f32 RightVol = clip->channel_volume[1];
if(SamplesToMix && control != 0)
{
LeftVol *= control->channel_volume[0];
RightVol *= control->channel_volume[1];
control->generation = Crunky->generation;
control->last_played_sample_index = clip->at_sample_index;
}
// NOTE(casey): Mix samples
for(u32 SampleIndex = 0; for(u32 SampleIndex = 0;
SampleIndex < SamplesToMix; SampleIndex < SamplesToMix;
++SampleIndex) ++SampleIndex)
{ {
u32 src_base_indx = 2*(Sound.at_sample_index + SampleIndex); u32 src_index = 2*(clip->at_sample_index + SampleIndex);
u32 dst_base_indx = 2*SampleIndex; f32 Left = LeftVol*(f32)clip->samples[src_index + 0];
Dest[dst_base_indx + 0] += (i16)(LeftVol*(i32)Sound.samples[src_base_indx + 0]/AUDIO_PRODUCER_KNOB_ONE); f32 Right = RightVol*(f32)clip->samples[src_index + 1];
Dest[dst_base_indx + 1] += (i16)(RightVol*(i32)Sound.samples[src_base_indx + 1]/AUDIO_PRODUCER_KNOB_ONE);
u32 dst_index = 2*SampleIndex;
MixBuffer[dst_index + 0] += Left;
MixBuffer[dst_index + 1] += Right;
}
}
for(u32 SampleIndex = 0;
SampleIndex < SampleCount;
++SampleIndex)
{
f32 Left = MixBuffer[2*SampleIndex + 0];
f32 Right = MixBuffer[2*SampleIndex + 1];
Dest[2*SampleIndex + 0] = (i16)Left;
Dest[2*SampleIndex + 1] = (i16)Right;
} }
} }
} }
function b32 function b32
win32_submit_audio(Audio_System *Crunky, HWAVEOUT WaveOut, WAVEHDR *Header){ win32_submit_audio(Audio_System *Crunky, HWAVEOUT WaveOut, WAVEHDR *Header, u32 SampleCount, void *mix_buffer){
b32 Result = false; b32 Result = false;
u32 SampleCount = Header->dwBufferLength/4;
i16 *Samples = (i16 *)Header->lpData; i16 *Samples = (i16 *)Header->lpData;
win32_mix_audio(Crunky, SampleCount, Samples); win32_mix_audio(Crunky, SampleCount, Samples, mix_buffer);
DWORD Error = waveOutPrepareHeader(WaveOut, Header, sizeof(*Header)); DWORD Error = waveOutPrepareHeader(WaveOut, Header, sizeof(*Header));
if(Error == MMSYSERR_NOERROR) if(Error == MMSYSERR_NOERROR)
@ -120,7 +190,8 @@ win32_audio_loop(void *Passthrough){
u32 BufferSize = SamplesPerBuffer*BytesPerSample; u32 BufferSize = SamplesPerBuffer*BytesPerSample;
u32 HeaderSize = sizeof(WAVEHDR); u32 HeaderSize = sizeof(WAVEHDR);
u32 TotalBufferSize = (BufferSize+HeaderSize); u32 TotalBufferSize = (BufferSize+HeaderSize);
u32 TotalAudioMemorySize = BufferCount*TotalBufferSize; u32 MixBufferSize = (SamplesPerBuffer*ChannelCount*sizeof(f32));
u32 TotalAudioMemorySize = BufferCount*TotalBufferSize + MixBufferSize;
// //
// NOTE(casey): Initialize audio out // NOTE(casey): Initialize audio out
@ -135,24 +206,28 @@ win32_audio_loop(void *Passthrough){
Format.nBlockAlign = (Format.nChannels*Format.wBitsPerSample)/8; Format.nBlockAlign = (Format.nChannels*Format.wBitsPerSample)/8;
Format.nAvgBytesPerSec = Format.nBlockAlign * Format.nSamplesPerSec; Format.nAvgBytesPerSec = Format.nBlockAlign * Format.nSamplesPerSec;
void *MixBuffer = 0;
void *AudioBufferMemory = 0;
if(waveOutOpen(&WaveOut, WAVE_MAPPER, &Format, GetCurrentThreadId(), 0, CALLBACK_THREAD) == MMSYSERR_NOERROR) if(waveOutOpen(&WaveOut, WAVE_MAPPER, &Format, GetCurrentThreadId(), 0, CALLBACK_THREAD) == MMSYSERR_NOERROR)
{ {
void *AudioBufferMemory = VirtualAlloc(0, TotalAudioMemorySize, MEM_COMMIT, PAGE_READWRITE); AudioBufferMemory = VirtualAlloc(0, TotalAudioMemorySize, MEM_COMMIT, PAGE_READWRITE);
if(AudioBufferMemory) if(AudioBufferMemory)
{ {
u8 *At = (u8 *)AudioBufferMemory; u8 *At = (u8 *)AudioBufferMemory;
MixBuffer = At;
At += MixBufferSize;
for(u32 BufferIndex = 0; for(u32 BufferIndex = 0;
BufferIndex < BufferCount; BufferIndex < BufferCount;
++BufferIndex) ++BufferIndex)
{ {
WAVEHDR *Header = (WAVEHDR *)At; WAVEHDR *Header = (WAVEHDR *)At;
At += sizeof(WAVEHDR); Header->lpData = (char *)(Header + 1);
Header->lpData = (char *)At; Header->dwBufferLength = BufferSize;
Header->dwBufferLength = TotalBufferSize;
At += TotalBufferSize; At += TotalBufferSize;
win32_submit_audio(Crunky, WaveOut, Header); win32_submit_audio(Crunky, WaveOut, Header, SamplesPerBuffer, MixBuffer);
} }
} }
else else
@ -168,7 +243,8 @@ win32_audio_loop(void *Passthrough){
// //
// NOTE(casey): Serve audio forever (until we are told to stop) // NOTE(casey): Serve audio forever (until we are told to stop)
// //
// SetTimer(0, 0, 100, 0);
SetTimer(0, 0, 100, 0);
while(!Crunky->quit) while(!Crunky->quit)
{ {
MSG Message = {}; MSG Message = {};
@ -183,10 +259,20 @@ win32_audio_loop(void *Passthrough){
waveOutUnprepareHeader(WaveOut, Header, sizeof(*Header)); waveOutUnprepareHeader(WaveOut, Header, sizeof(*Header));
win32_submit_audio(Crunky, WaveOut, Header); win32_submit_audio(Crunky, WaveOut, Header, SamplesPerBuffer, MixBuffer);
} }
} }
if(WaveOut)
{
waveOutClose(WaveOut);
}
if(AudioBufferMemory)
{
VirtualFree(AudioBufferMemory, 0, MEM_RELEASE);
}
return(0); return(0);
} }