Spacial audio, draw_line, vector procs
This commit is contained in:
parent
c34319796f
commit
c6bf5bc8bb
11 changed files with 288 additions and 33 deletions
7
TODO
7
TODO
|
@ -1,7 +1,6 @@
|
|||
|
||||
- Audio
|
||||
- Player volume control
|
||||
- Spatial audio
|
||||
- Optimize
|
||||
- Spam simd
|
||||
- Concurrent jobs for players?
|
||||
|
@ -20,11 +19,6 @@
|
|||
- 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
|
||||
|
||||
- Juice
|
||||
- draw_line
|
||||
- vx_length
|
||||
- Occlude quads out of view
|
||||
|
||||
- General bugs & issues
|
||||
- Release freeze in run_tests
|
||||
|
||||
|
@ -32,3 +26,4 @@
|
|||
- Audio format channel conversions
|
||||
- sample rate downsampling
|
||||
- non stereo or mono audio
|
||||
- Audio spacialization on anything that's not stereo
|
6
build.c
6
build.c
|
@ -3,6 +3,8 @@
|
|||
///
|
||||
// Build config stuff
|
||||
|
||||
#define OOGABOOGA_DEV 1
|
||||
|
||||
#define INITIAL_PROGRAM_MEMORY_SIZE MB(5)
|
||||
|
||||
typedef struct Context_Extra {
|
||||
|
@ -26,13 +28,13 @@ typedef struct Context_Extra {
|
|||
//
|
||||
|
||||
// This is a minimal starting point for new projects. Copy & rename to get started
|
||||
#include "oogabooga/examples/minimal_game_loop.c"
|
||||
// #include "oogabooga/examples/minimal_game_loop.c"
|
||||
|
||||
// #include "oogabooga/examples/text_rendering.c"
|
||||
// #include "oogabooga/examples/custom_logger.c"
|
||||
// #include "oogabooga/examples/renderer_stress_test.c"
|
||||
// #include "oogabooga/examples/tile_game.c"
|
||||
// #include "oogabooga/examples/audio_test.c"
|
||||
#include "oogabooga/examples/audio_test.c"
|
||||
|
||||
// This is where you swap in your own project!
|
||||
// #include "entry_yourepicgamename.c"
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
## v0.01.001 - Spacial audio,
|
||||
- Audio
|
||||
- Implemented spacial audio playback
|
||||
Simply set player->position (it's in ndc space (-1 to 1), see audio_test.c)
|
||||
Save some computation with player->disable_spacialization = true
|
||||
- Added position overloads for play_one_clip
|
||||
play_one_audio_clip_source_at_position(source, pos)
|
||||
play_one_audio_clip_at_position(path, pos)
|
||||
- Renderer
|
||||
- Added draw_line(p0, p1, width, color)
|
||||
- Implemented culling of quads out of view
|
||||
|
||||
- Misc
|
||||
- Added some useful Vector procedures:
|
||||
vx_length()
|
||||
vx_normalize()
|
||||
vx_average()
|
||||
vx_dot()
|
||||
vx_abs()
|
||||
vx_cross()
|
||||
|
||||
## v0.01.000 - AUDIO!
|
||||
- Added audio sources
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
void play_one_audio_clip_source(Audio_Source source);
|
||||
void play_one_audio_clip(string path);
|
||||
void play_one_audio_clip_source_at_position(Audio_Source source, Vector3 pos);
|
||||
void play_one_audio_clip_at_position(string path, Vector3 pos);
|
||||
|
||||
Playing audio (with players):
|
||||
|
||||
|
@ -25,6 +27,7 @@
|
|||
float64 audio_player_get_current_progression_factor(Audio_Player *p);
|
||||
void audio_player_set_source(Audio_Player *p, Audio_Source src, bool retain_progression_factor);
|
||||
void audio_player_clear_source(Audio_Player *p);
|
||||
void audio_player_clear_source(Audio_Player *p);
|
||||
void audio_player_set_looping(Audio_Player *p, bool looping);
|
||||
|
||||
*/
|
||||
|
@ -1154,10 +1157,14 @@ typedef struct Audio_Player {
|
|||
u64 fade_frames;
|
||||
u64 fade_frames_total;
|
||||
bool release_when_done;
|
||||
|
||||
// I think we only need to sync when audio thread samples the source, which should be
|
||||
// very quick and low contention, hence a spinlock.
|
||||
Spinlock sample_lock;
|
||||
|
||||
// These can be set safely
|
||||
Vector3 position; // ndc space -1 to 1
|
||||
bool disable_spacialization;
|
||||
|
||||
} Audio_Player;
|
||||
#define AUDIO_PLAYERS_PER_BLOCK 128
|
||||
typedef struct Audio_Player_Block {
|
||||
|
@ -1325,14 +1332,20 @@ Hash_Table just_audio_clips;
|
|||
bool just_audio_clips_initted = false;
|
||||
|
||||
void
|
||||
play_one_audio_clip_source(Audio_Source source) {
|
||||
play_one_audio_clip_source_at_position(Audio_Source source, Vector3 pos) {
|
||||
Audio_Player *p = audio_player_get_one();
|
||||
audio_player_set_source(p, source, false);
|
||||
audio_player_set_state(p, AUDIO_PLAYER_STATE_PLAYING);
|
||||
p->position = pos;
|
||||
p->release_when_done = true;
|
||||
}
|
||||
|
||||
void inline
|
||||
play_one_audio_clip_source(Audio_Source source) {
|
||||
play_one_audio_clip_source_at_position(source, v3(0, 0, 0));
|
||||
}
|
||||
void
|
||||
play_one_audio_clip(string path) {
|
||||
play_one_audio_clip_at_position(string path, Vector3 pos) {
|
||||
if (!just_audio_clips_initted) {
|
||||
just_audio_clips_initted = true;
|
||||
just_audio_clips = make_hash_table(string, Audio_Source, get_heap_allocator());
|
||||
|
@ -1340,7 +1353,7 @@ play_one_audio_clip(string path) {
|
|||
|
||||
Audio_Source *src_ptr = hash_table_find(&just_audio_clips, path);
|
||||
if (src_ptr) {
|
||||
play_one_audio_clip_source(*src_ptr);
|
||||
play_one_audio_clip_source_at_position(*src_ptr, pos);
|
||||
} else {
|
||||
Audio_Source new_src;
|
||||
bool ok = audio_open_source_load(&new_src, path, get_heap_allocator());
|
||||
|
@ -1349,8 +1362,13 @@ play_one_audio_clip(string path) {
|
|||
return;
|
||||
}
|
||||
hash_table_add(&just_audio_clips, path, new_src);
|
||||
play_one_audio_clip_source(new_src);
|
||||
play_one_audio_clip_source_at_position(new_src, pos);
|
||||
}
|
||||
|
||||
}
|
||||
void inline
|
||||
play_one_audio_clip(string path) {
|
||||
play_one_audio_clip_at_position(path, v3(0, 0, 0));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1406,6 +1424,131 @@ audio_apply_fade_out(void *frames, u64 number_of_frames, Audio_Format format,
|
|||
}
|
||||
}
|
||||
|
||||
void spacialize_audio_mono(void* frames, Audio_Format format, u64 number_of_frames, Vector3 pos) {
|
||||
// No idea if this actually gives the perception of audio being positioned.
|
||||
// I also don't have a mono audio device to test it.
|
||||
float* audio_data = (float*)frames;
|
||||
|
||||
float distance = sqrtf(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
|
||||
float attenuation = 1.0f / (1.0f + distance);
|
||||
|
||||
float alpha = 0.1f;
|
||||
float prev_sample = 0.0f;
|
||||
|
||||
u64 comp_size = get_audio_bit_width_byte_size(format.bit_width);
|
||||
u64 frame_size = comp_size * format.channels;
|
||||
|
||||
for (u64 i = 0; i < number_of_frames; ++i) {
|
||||
float sample = audio_data[i];
|
||||
convert_one_component(
|
||||
&sample,
|
||||
AUDIO_BITS_32,
|
||||
(u8*)frames+i*frame_size,
|
||||
format.bit_width
|
||||
);
|
||||
|
||||
sample *= attenuation;
|
||||
|
||||
sample = alpha * sample + (1.0f - alpha) * prev_sample;
|
||||
prev_sample = sample;
|
||||
|
||||
convert_one_component(
|
||||
(u8*)frames+i*frame_size,
|
||||
format.bit_width,
|
||||
&sample,
|
||||
AUDIO_BITS_32
|
||||
);
|
||||
}
|
||||
}
|
||||
void spacialize_audio(void* frames, Audio_Format format, u64 number_of_frames, Vector3 pos) {
|
||||
|
||||
if (format.channels == 1) {
|
||||
spacialize_audio_mono(frames, format, number_of_frames, pos);
|
||||
}
|
||||
|
||||
float distance = sqrtf(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
|
||||
float attenuation = 1.0f / (1.0f + distance);
|
||||
|
||||
float left_right_pan = (pos.x + 1.0f) * 0.5f;
|
||||
float up_down_pan = (pos.y + 1.0f) * 0.5f;
|
||||
float front_back_pan = (pos.z + 1.0f) * 0.5f;
|
||||
|
||||
u64 comp_size = get_audio_bit_width_byte_size(format.bit_width);
|
||||
u64 frame_size = comp_size * format.channels;
|
||||
|
||||
float high_pass_coeff = 0.8f + 0.2f * up_down_pan;
|
||||
float low_pass_coeff = 1.0f - high_pass_coeff;
|
||||
|
||||
// Apply gains to each frame
|
||||
for (u64 i = 0; i < number_of_frames; ++i) {
|
||||
for (u64 c = 0; c < format.channels; ++c) {
|
||||
// Convert whatever to float -1 to 1
|
||||
float sample;
|
||||
convert_one_component(
|
||||
&sample,
|
||||
AUDIO_BITS_32,
|
||||
(u8*)frames+i*frame_size+c*comp_size,
|
||||
format.bit_width
|
||||
);
|
||||
float gain = 1.0f / format.channels;
|
||||
|
||||
if (format.channels == 2) {
|
||||
|
||||
// time delay and phase shift for vertical position
|
||||
float time_delay = (up_down_pan - 0.5f) * 0.0005f; // 0.5ms delay range
|
||||
float phase_shift = (up_down_pan - 0.5f) * 0.5f; // 0.5 radians phase shift range
|
||||
|
||||
// Stereo
|
||||
if (c == 0) {
|
||||
gain = (1.0f - left_right_pan) * attenuation;
|
||||
sample = sample * cos(phase_shift) - sample * sin(phase_shift);
|
||||
} else if (c == 1) {
|
||||
gain = left_right_pan * attenuation;
|
||||
sample = sample * cos(phase_shift) + sample * sin(phase_shift);
|
||||
}
|
||||
} else if (format.channels == 4) {
|
||||
// Quadraphonic sound (left-right, front-back)
|
||||
if (c == 0) {
|
||||
gain = (1.0f - left_right_pan) * (1.0f - front_back_pan) * attenuation;
|
||||
} else if (c == 1) {
|
||||
gain = left_right_pan * (1.0f - front_back_pan) * attenuation;
|
||||
} else if (c == 2) {
|
||||
gain = (1.0f - left_right_pan) * front_back_pan * attenuation;
|
||||
} else if (c == 3) {
|
||||
gain = left_right_pan * front_back_pan * attenuation;
|
||||
}
|
||||
} else if (format.channels == 6) {
|
||||
// 5.1 surround sound (left, right, center, LFE, rear left, rear right)
|
||||
if (c == 0) {
|
||||
gain = (1.0f - left_right_pan) * attenuation;
|
||||
} else if (c == 1) {
|
||||
gain = left_right_pan * attenuation;
|
||||
} else if (c == 2) {
|
||||
gain = (1.0f - front_back_pan) * attenuation;
|
||||
} else if (c == 3) {
|
||||
gain = 0.5f * attenuation; // LFE (subwoofer) channel
|
||||
} else if (c == 4) {
|
||||
gain = (1.0f - left_right_pan) * front_back_pan * attenuation;
|
||||
} else if (c == 5) {
|
||||
gain = left_right_pan * front_back_pan * attenuation;
|
||||
}
|
||||
} else {
|
||||
// No idea what device this is, just distribute equally
|
||||
gain = attenuation / format.channels;
|
||||
}
|
||||
|
||||
sample *= gain;
|
||||
// Convert back to whatever
|
||||
convert_one_component(
|
||||
(u8*)frames+i*frame_size+c*comp_size,
|
||||
format.bit_width,
|
||||
&sample,
|
||||
AUDIO_BITS_32
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is supposed to be called by OS layer audio thread whenever it wants more audio samples
|
||||
void
|
||||
do_program_audio_sample(u64 number_of_output_frames, Audio_Format out_format,
|
||||
|
@ -1581,6 +1724,10 @@ do_program_audio_sample(u64 number_of_output_frames, Audio_Format out_format,
|
|||
assert(converted == number_of_output_frames);
|
||||
}
|
||||
|
||||
if (!p->disable_spacialization) {
|
||||
spacialize_audio(mix_buffer, out_format, number_of_output_frames, p->position);
|
||||
}
|
||||
|
||||
mix_frames(output, mix_buffer, number_of_output_frames, out_format);
|
||||
|
||||
mutex_release(&src.mutex_for_destroy);
|
||||
|
|
|
@ -127,12 +127,23 @@ void pop_z_layer() {
|
|||
draw_frame.z_count -= 1;
|
||||
}
|
||||
|
||||
Draw_Quad _nil_quad = {0};
|
||||
Draw_Quad *draw_quad_projected(Draw_Quad quad, Matrix4 world_to_clip) {
|
||||
quad.bottom_left = m4_transform(world_to_clip, v4(v2_expand(quad.bottom_left), 0, 1)).xy;
|
||||
quad.top_left = m4_transform(world_to_clip, v4(v2_expand(quad.top_left), 0, 1)).xy;
|
||||
quad.top_right = m4_transform(world_to_clip, v4(v2_expand(quad.top_right), 0, 1)).xy;
|
||||
quad.bottom_right = m4_transform(world_to_clip, v4(v2_expand(quad.bottom_right), 0, 1)).xy;
|
||||
|
||||
bool should_cull =
|
||||
(quad.bottom_left.x < -1 || quad.bottom_left.x > 1 || quad.bottom_left.y < -1 || quad.bottom_left.y > 1)
|
||||
&& (quad.top_left.x < -1 || quad.top_left.x > 1 || quad.top_left.y < -1 || quad.top_left.y > 1)
|
||||
&& (quad.top_right.x < -1 || quad.top_right.x > 1 || quad.top_right.y < -1 || quad.top_right.y > 1)
|
||||
&& (quad.bottom_right.x < -1 || quad.bottom_right.x > 1 || quad.bottom_right.y < -1 || quad.bottom_right.y > 1);
|
||||
|
||||
if (should_cull) {
|
||||
return &_nil_quad;
|
||||
}
|
||||
|
||||
quad.image_min_filter = GFX_FILTER_MODE_NEAREST;
|
||||
quad.image_mag_filter = GFX_FILTER_MODE_NEAREST;
|
||||
|
||||
|
@ -272,6 +283,16 @@ Gfx_Text_Metrics draw_text_and_measure(Gfx_Font *font, string text, u32 raster_h
|
|||
return measure_text(font, text, raster_height, scale);
|
||||
}
|
||||
|
||||
void draw_line(Vector2 p0, Vector2 p1, float line_width, Vector4 color) {
|
||||
Vector2 dir = v2(p1.x - p0.x, p1.y - p0.y);
|
||||
float length = sqrt(dir.x * dir.x + dir.y * dir.y);
|
||||
float r = atan2(-dir.y, dir.x);
|
||||
Matrix4 line_xform = m4_scalar(1);
|
||||
line_xform = m4_translate(line_xform, v3(p0.x, p0.y, 0));
|
||||
line_xform = m4_rotate_z(line_xform, r);
|
||||
line_xform = m4_translate(line_xform, v3(0, -line_width/2, 0));
|
||||
draw_rect_xform(line_xform, v2(length, line_width), color);
|
||||
}
|
||||
|
||||
#define COLOR_RED ((Vector4){1.0, 0.0, 0.0, 1.0})
|
||||
#define COLOR_GREEN ((Vector4){0.0, 1.0, 0.0, 1.0})
|
||||
|
|
|
@ -57,8 +57,13 @@ int entry(int argc, char **argv) {
|
|||
draw_frame.projection = m4_make_orthographic_projection(window.pixel_width * -0.5, window.pixel_width * 0.5, window.pixel_height * -0.5, window.pixel_height * 0.5, -1, 10);
|
||||
|
||||
if (is_key_just_pressed(MOUSE_BUTTON_RIGHT)) {
|
||||
float mx = input_frame.mouse_x;
|
||||
float my = input_frame.mouse_y;
|
||||
// Easy mode (when you don't care and just want to play a clip)
|
||||
play_one_audio_clip(STR("oogabooga/examples/block.wav"));
|
||||
Vector3 p = v3(mx/(f32)window.width*2.0-1, my/(f32)window.height*2.0-1, 0);
|
||||
log("%f, %f", p.x, p.y);
|
||||
play_one_audio_clip_at_position(STR("oogabooga/examples/block.wav"), p);
|
||||
// Or just play_one_audio_clip if you don't care about spacialization
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,12 @@ int entry(int argc, char **argv) {
|
|||
|
||||
draw_rect(v2(sin(now), -.8), v2(.5, .25), COLOR_RED);
|
||||
|
||||
float aspect = (f32)window.width/(f32)window.height;
|
||||
float mx = (input_frame.mouse_x/(f32)window.width * 2.0 - 1.0)*aspect;
|
||||
float my = input_frame.mouse_y/(f32)window.height * 2.0 - 1.0;
|
||||
|
||||
draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);
|
||||
|
||||
os_update();
|
||||
gfx_update();
|
||||
}
|
||||
|
|
|
@ -127,22 +127,81 @@ inline Vector4 v4_divf(LMATH_ALIGN Vector4 a, float32 s) {
|
|||
return v4_div(a, v4(s, s, s, s));
|
||||
}
|
||||
|
||||
|
||||
// #Simd
|
||||
inline float32 v2_length(LMATH_ALIGN Vector2 a) {
|
||||
return sqrt(a.x*a.x + a.y*a.y);
|
||||
}
|
||||
inline Vector2 v2_normalize(LMATH_ALIGN Vector2 a) {
|
||||
float32 length = sqrt(a.x * a.x + a.y * a.y);
|
||||
float32 length = v2_length(a);
|
||||
if (length == 0) {
|
||||
return (Vector2){0, 0};
|
||||
}
|
||||
return v2_divf(a, length);
|
||||
}
|
||||
|
||||
inline float v2_dot_product(LMATH_ALIGN Vector2 a, LMATH_ALIGN Vector2 b) {
|
||||
inline float32 v2_average(LMATH_ALIGN Vector2 a) {
|
||||
return (a.x+a.y)/2.0;
|
||||
}
|
||||
inline Vector2 v2_abs(LMATH_ALIGN Vector2 a) {
|
||||
return v2(fabsf(a.x), fabsf(a.y));
|
||||
}
|
||||
inline float32 v2_cross(LMATH_ALIGN Vector2 a, LMATH_ALIGN Vector2 b) {
|
||||
return (a.x * b.y) - (a.y * b.x);
|
||||
}
|
||||
inline float v2_dot(LMATH_ALIGN Vector2 a, LMATH_ALIGN Vector2 b) {
|
||||
return simd_dot_product_float32_64((float*)&a, (float*)&b);
|
||||
}
|
||||
inline float v3_dot_product(LMATH_ALIGN Vector3 a, LMATH_ALIGN Vector3 b) {
|
||||
|
||||
inline float32 v3_length(LMATH_ALIGN Vector3 a) {
|
||||
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
|
||||
}
|
||||
|
||||
inline Vector3 v3_normalize(LMATH_ALIGN Vector3 a) {
|
||||
float32 length = v3_length(a);
|
||||
if (length == 0) {
|
||||
return (Vector3){0, 0, 0};
|
||||
}
|
||||
return v3_divf(a, length);
|
||||
}
|
||||
|
||||
inline float32 v3_average(LMATH_ALIGN Vector3 a) {
|
||||
return (a.x + a.y + a.z) / 3.0;
|
||||
}
|
||||
|
||||
inline Vector3 v3_abs(LMATH_ALIGN Vector3 a) {
|
||||
return v3(fabsf(a.x), fabsf(a.y), fabsf(a.z));
|
||||
}
|
||||
|
||||
|
||||
inline Vector3 v3_cross(LMATH_ALIGN Vector3 a, LMATH_ALIGN Vector3 b) {
|
||||
return (Vector3){
|
||||
(a.y * b.z) - (a.z * b.y),
|
||||
(a.z * b.x) - (a.x * b.z),
|
||||
(a.x * b.y) - (a.y * b.x)
|
||||
};
|
||||
}
|
||||
inline float v3_dot(LMATH_ALIGN Vector3 a, LMATH_ALIGN Vector3 b) {
|
||||
return simd_dot_product_float32_96((float*)&a, (float*)&b);
|
||||
}
|
||||
inline float v4_dot_product(LMATH_ALIGN Vector4 a, LMATH_ALIGN Vector4 b) {
|
||||
inline float32 v4_length(LMATH_ALIGN Vector4 a) {
|
||||
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w);
|
||||
}
|
||||
|
||||
inline Vector4 v4_normalize(LMATH_ALIGN Vector4 a) {
|
||||
float32 length = v4_length(a);
|
||||
if (length == 0) {
|
||||
return (Vector4){0, 0, 0, 0};
|
||||
}
|
||||
return v4_divf(a, length);
|
||||
}
|
||||
|
||||
inline float32 v4_average(LMATH_ALIGN Vector4 a) {
|
||||
return (a.x + a.y + a.z + a.w) / 4.0;
|
||||
}
|
||||
|
||||
inline Vector4 v4_abs(LMATH_ALIGN Vector4 a) {
|
||||
return v4(fabsf(a.x), fabsf(a.y), fabsf(a.z), fabsf(a.w));
|
||||
}
|
||||
inline float v4_dot(LMATH_ALIGN Vector4 a, LMATH_ALIGN Vector4 b) {
|
||||
return simd_dot_product_float32_128_aligned((float*)&a, (float*)&b);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
|
||||
#define OGB_VERSION_MAJOR 0
|
||||
#define OGB_VERSION_MINOR 1
|
||||
#define OGB_VERSION_PATCH 0
|
||||
#define OGB_VERSION_PATCH 1
|
||||
|
||||
#define OGB_VERSION (OGB_VERSION_MAJOR*1000000+OGB_VERSION_MINOR*1000+OGB_VERSION_PATCH)
|
||||
|
||||
|
|
|
@ -1011,13 +1011,13 @@ void test_linmath() {
|
|||
assert(mixed_v4_result.x == 1.0f && mixed_v4_result.y == 2.0f && mixed_v4_result.z == 3.0f && mixed_v4_result.w == 4.0f, "Mixed Vector4 scalar multiplication failed");
|
||||
|
||||
|
||||
float v2_dot = v2_dot_product(v2(2, 7), v2(3, 2));
|
||||
float v3_dot = v3_dot_product(v3(2, 7, 2), v3(3, 2, 9));
|
||||
float v4_dot = v4_dot_product(v4(2, 7, 6, 1), v4(3, 2, 1, 4));
|
||||
float v2_dot_product = v2_dot(v2(2, 7), v2(3, 2));
|
||||
float v3_dot_product = v3_dot(v3(2, 7, 2), v3(3, 2, 9));
|
||||
float v4_dot_product = v4_dot(v4(2, 7, 6, 1), v4(3, 2, 1, 4));
|
||||
|
||||
assert(floats_roughly_match(v2_dot, 20), "Failed: v2_dot_product");
|
||||
assert(floats_roughly_match(v3_dot, 38), "Failed: v3_dot_product");
|
||||
assert(floats_roughly_match(v4_dot, 30), "Failed: v4_dot_product");
|
||||
assert(floats_roughly_match(v2_dot_product, 20), "Failed: v2_dot");
|
||||
assert(floats_roughly_match(v3_dot_product, 38), "Failed: v3_dot");
|
||||
assert(floats_roughly_match(v4_dot_product, 30), "Failed: v4_dot");
|
||||
}
|
||||
void test_hash_table() {
|
||||
Hash_Table table = make_hash_table(string, int, get_heap_allocator());
|
||||
|
|
8
oogabooga/third_party/stb_vorbis.c
vendored
8
oogabooga/third_party/stb_vorbis.c
vendored
|
@ -12,7 +12,7 @@
|
|||
|
||||
- All FILE * stdio procedures are replaced with the equivalent for the oogabooga
|
||||
file API.
|
||||
|
||||
- all draw_line -> stb_vorbis_draw_line
|
||||
|
||||
*/
|
||||
|
||||
|
@ -2125,7 +2125,7 @@ static float inverse_db_table[256] =
|
|||
int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB
|
||||
#endif
|
||||
|
||||
static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n)
|
||||
static __forceinline void stb_vorbis_draw_line(float *output, int x0, int y0, int x1, int y1, int n)
|
||||
{
|
||||
int dy = y1 - y0;
|
||||
int adx = x1 - x0;
|
||||
|
@ -3186,13 +3186,13 @@ static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *f
|
|||
int hy = finalY[j] * g->floor1_multiplier;
|
||||
int hx = g->Xlist[j];
|
||||
if (lx != hx)
|
||||
draw_line(target, lx,ly, hx,hy, n2);
|
||||
stb_vorbis_draw_line(target, lx,ly, hx,hy, n2);
|
||||
CHECK(f);
|
||||
lx = hx, ly = hy;
|
||||
}
|
||||
}
|
||||
if (lx < n2) {
|
||||
// optimization of: draw_line(target, lx,ly, n,ly, n2);
|
||||
// optimization of: stb_vorbis_draw_line(target, lx,ly, n,ly, n2);
|
||||
for (j=lx; j < n2; ++j)
|
||||
LINE_OP(target[j], inverse_db_table[ly]);
|
||||
CHECK(f);
|
||||
|
|
Reference in a new issue