From 7de0634e97ebe67a5ca37684e2273072702a2ca7 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 19 Apr 2023 20:49:29 -0700 Subject: [PATCH] bug fixes: switch to 64-bit integers for sample counts and related values to avoid truncation in arithmetic on large inputs --- bin/compiler_flags.txt | 4 +++- src/podcastoscope.cpp | 53 ++++++++++++++++++++++-------------------- src/podcastoscope.h | 18 +++++++------- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/bin/compiler_flags.txt b/bin/compiler_flags.txt index 37e4d32..5b8d8ec 100644 --- a/bin/compiler_flags.txt +++ b/bin/compiler_flags.txt @@ -15,6 +15,8 @@ clang>-Wno-switch ###### Debug ################################################################## debug>-DENABLE_ASSERT=1 -release>-DENABLE_ASSERT=0 +optimize>-DENABLE_ASSERT=0 cl>debug>-Zi +###### Optimized ############################################################## +cl>optimize>-O2 \ No newline at end of file diff --git a/src/podcastoscope.cpp b/src/podcastoscope.cpp index f512b02..042524e 100644 --- a/src/podcastoscope.cpp +++ b/src/podcastoscope.cpp @@ -2,6 +2,9 @@ ** Podcast Video Renderer */ +#define M_DEFAULT_RESERVE_SIZE TB(1) +#define M_COMMIT_BLOCK_SIZE MB(256) + #include "base/base_inc.h" #include "os/os_inc.h" @@ -76,8 +79,8 @@ //////////////////////////////// // NOTE(allen): Configuration Stuff -#define PLAY_TEST_TRACK 0 -#define TEST_TRACK "C:\\mr4th\\podcast\\test__anti_allen\\test__combined.wav" +#define PLAY_TEST_TRACK 1 +#define TEST_TRACK "C:/..." #define AVATAR_DISPLAY_SIDE 280 #define AVATAR_DISPLAY_RADIUS 140.f @@ -99,7 +102,7 @@ #define ENABLE_SRGB_CONVERSION 1 #define ENABLE_MULTISAMPLE 0 -#define CONSIDERED_SILENCE_DB -40.f +#define CONSIDERED_SILENCE_DB -45.f #define CONSIDERED_MINIMUM_DB -33.f #define CONSIDERED_FULL_DB -15.f @@ -843,7 +846,7 @@ track_from_file_path(M_Arena *arena, String8 full_path){ String8 data = os_file_read(scratch.arena, full_path); // parse wave file - U32 block_count = 0; + U64 block_count = 0; F32 *channels[2] = {0}; if (data.str != 0){ @@ -902,26 +905,26 @@ decibel_from_linear(F32 r){ function Array_F32 db_per_frame_from_samples(M_Arena *arena, - F32 *samples, U32 sample_count, - U32 sample_frequency){ - U32 frame_count = CeilIntDiv(sample_count*60, sample_frequency); + F32 *samples, U64 sample_count, + U64 sample_frequency){ + U64 frame_count = CeilIntDiv(sample_count*60, sample_frequency); U32 sample_per_frame = sample_frequency/60; U32 window_size = 150; F32 window_mean_norm = 1.f/(F32)window_size; F32 *out_buf = push_array(arena, F32, frame_count); - for (U32 i = 0; i < frame_count; i += 1){ - U32 first_sample_i = i*sample_per_frame; - U32 opl_sample_i_raw = first_sample_i + sample_per_frame; - U32 opl_sample_i = ClampTop(opl_sample_i_raw, sample_count); + for (U64 i = 0; i < frame_count; i += 1){ + U64 first_sample_i = i*sample_per_frame; + U64 opl_sample_i_raw = first_sample_i + sample_per_frame; + U64 opl_sample_i = ClampTop(opl_sample_i_raw, sample_count); F32 max_var_db = -100.f; - for (U32 j = first_sample_i; j < opl_sample_i; j += window_size){ - U32 first_sample_j = j; - U32 opl_sample_j_raw = first_sample_j + window_size; - U32 opl_sample_j = ClampTop(opl_sample_j_raw, sample_count); + for (U64 j = first_sample_i; j < opl_sample_i; j += window_size){ + U64 first_sample_j = j; + U64 opl_sample_j_raw = first_sample_j + window_size; + U64 opl_sample_j = ClampTop(opl_sample_j_raw, sample_count); F32 *first_sample = samples + first_sample_j; F32 *opl_sample = samples + opl_sample_j; @@ -959,7 +962,7 @@ db_per_frame_from_samples(M_Arena *arena, function void speaker_marker_push(M_Arena *arena, SpeakerMarkerList *list, - U32 frame_idx, U32 speaker_idx, B32 begin){ + U64 frame_idx, U32 speaker_idx, B32 begin){ SpeakerMarkerNode *node = push_array(arena, SpeakerMarkerNode, 1); SLLQueuePush(list->first, list->last, node); list->count += 1; @@ -1054,8 +1057,8 @@ speaker_marker_array_sort_in_place(SpeakerMarker *markers, U64 count){ U64 j2_opl = range2->opl; for (;j1 < j1_opl && j2 < j2_opl;){ - U32 frame_idx1 = src_markers[j1].frame_idx; - U32 frame_idx2 = src_markers[j2].frame_idx; + U64 frame_idx1 = src_markers[j1].frame_idx; + U64 frame_idx2 = src_markers[j2].frame_idx; if (frame_idx1 <= frame_idx2){ dst_markers[i] = src_markers[j1]; j1 += 1; @@ -1113,8 +1116,8 @@ window_resize_handler(GFX_Window window, U32 width, U32 height){ function ProcessedTrack processed_track_from_samples(M_Arena *arena, - F32 *samples, U32 sample_count, - U32 sample_frequency, + F32 *samples, U64 sample_count, + U64 sample_frequency, F32 *band_freq_hz, U32 band_count){ M_ArenaTemp scratch = m_get_scratch(&arena, 1); @@ -1249,7 +1252,7 @@ WinMain(HINSTANCE hInstance, // load input audio F32 **speaker_mixed = push_array(scratch.arena, F32*, speaker_count); - U32 *speaker_sample_count = push_array(scratch.arena, U32, speaker_count); + U64 *speaker_sample_count = push_array(scratch.arena, U64, speaker_count); for (U32 speaker_i = 0; speaker_i < speaker_count; speaker_i += 1){ Speaker *speaker = speakers + speaker_i; Track track = track_from_file_path(scratch.arena, speaker->audio_path); @@ -1260,7 +1263,7 @@ WinMain(HINSTANCE hInstance, failed_to_load = true; } - U32 sample_count = track.sample_count; + U64 sample_count = track.sample_count; F32 *mixed = push_array(scratch.arena, F32, sample_count); { F32 *out = mixed; @@ -1278,7 +1281,7 @@ WinMain(HINSTANCE hInstance, // master track { - U32 master_track_sample_count = 0; + U64 master_track_sample_count = 0; for (U32 speaker_i = 0; speaker_i < speaker_count; speaker_i += 1){ master_track_sample_count = Max(master_track_sample_count, speaker_sample_count[speaker_i]); @@ -1287,7 +1290,7 @@ WinMain(HINSTANCE hInstance, push_array_zero(scratch.arena, F32, master_track_sample_count); for (U32 speaker_i = 0; speaker_i < speaker_count; speaker_i += 1){ F32 *mixed = speaker_mixed[speaker_i]; - U32 sample_count = speaker_sample_count[speaker_i]; + U64 sample_count = speaker_sample_count[speaker_i]; for (U32 i = 0; i < sample_count; i += 1){ master_track[i] += mixed[i]; } @@ -1304,7 +1307,7 @@ WinMain(HINSTANCE hInstance, // process input audio for (U32 speaker_i = 0; speaker_i < speaker_count; speaker_i += 1){ F32 *mixed = speaker_mixed[speaker_i]; - U32 sample_count = speaker_sample_count[speaker_i]; + U64 sample_count = speaker_sample_count[speaker_i]; processed_tracks[speaker_i] = processed_track_from_samples(arena, mixed, sample_count, sample_frequency, diff --git a/src/podcastoscope.h b/src/podcastoscope.h index c34f15a..f937e10 100644 --- a/src/podcastoscope.h +++ b/src/podcastoscope.h @@ -9,11 +9,11 @@ // types struct Track{ F32 *channels[2]; - U32 sample_count; + U64 sample_count; }; struct SpeakerMarker{ - U32 frame_idx; + U64 frame_idx; U32 speaker_idx; B32 begin; }; @@ -57,12 +57,12 @@ decibel_from_linear(F32 r); function Array_F32 db_per_frame_from_samples(M_Arena *arena, - F32 *samples, U32 sample_count, - U32 sample_frequency); + F32 *samples, U64 sample_count, + U64 sample_frequency); function void speaker_marker_push(M_Arena *arena, SpeakerMarkerList *list, - U32 frame_idx, U32 speaker_idx, B32 begin); + U64 frame_idx, U32 speaker_idx, B32 begin); function SpeakerMarkerArray speaker_marker_array_from_list(M_Arena *arena, SpeakerMarkerList *list); @@ -141,7 +141,7 @@ struct Speaker{ }; struct ProcessedTrack{ - U32 frame_count; + U64 frame_count; F32 *max_level_db_per_frame; F32 *band_level_db_per_frame[MAX_BAND_COUNT]; U32 band_count; @@ -155,8 +155,8 @@ struct SpeakerState{ // functions function ProcessedTrack processed_track_from_samples(M_Arena *arena, - F32 *samples, U32 sample_count, - U32 sample_frequency, + F32 *samples, U64 sample_count, + U64 sample_frequency, F32 *band_freq_hz, U32 band_count); //////////////////////////////// @@ -196,7 +196,7 @@ struct RectList{ }; struct AvatarParams{ - U32 frame_counter; + U64 frame_counter; F32 radius; F32 sat_mul; F32 val_mul;