1
Fork 0

bug fixes: switch to 64-bit integers for sample counts and related values to avoid truncation in arithmetic on large inputs

main
Allen Webster 2023-04-19 20:49:29 -07:00
parent c3f163ed77
commit 7de0634e97
3 changed files with 40 additions and 35 deletions

View File

@ -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

View File

@ -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,

View File

@ -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;