diff options
| -rw-r--r-- | src/audio.cpp | 59 | ||||
| -rw-r--r-- | tests/pke-test-audio.cpp | 6 |
2 files changed, 37 insertions, 28 deletions
diff --git a/src/audio.cpp b/src/audio.cpp index e42d7e0..2743f82 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -143,7 +143,7 @@ void pke_audio_process_frames(int64_t frame_count) { uint32_t i, ii, c; int64_t i_frame; float *dst; - float val, vol, vol2; + float val, vol, vol2, dot, dot2; glm::vec3 listener_origin; glm::vec3 audio_dir = glm::vec3(0); float *spatial_volumes = nullptr; @@ -156,11 +156,11 @@ void pke_audio_process_frames(int64_t frame_count) { frame_count = PK_MIN(frame_count, (pke_audio_mstr.buffer_size / stride) - pke_audio_mstr.buffer_frames); // init - spatial_volumes = pk_new<float>(pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - spatial_normals = pk_new<glm::vec3>(pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - params_reverb = pk_new<pke_audio_fx_params_reverb>(pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - params_delay = pk_new<pke_audio_fx_params_delay>(pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - params_low_pass_filter = pk_new<pke_audio_fx_params_low_pass_filter>(pke_audio_mstr.channel_count, pke_audio_mstr.bkt); + spatial_volumes = pk_new<float>(pke_audio_mstr.channel_count, pkeSettings.mem_bkt.game_transient); + spatial_normals = pk_new<glm::vec3>(pke_audio_mstr.channel_count, pkeSettings.mem_bkt.game_transient); + params_reverb = pk_new<pke_audio_fx_params_reverb>(pke_audio_mstr.channel_count, pkeSettings.mem_bkt.game_transient); + params_delay = pk_new<pke_audio_fx_params_delay>(pke_audio_mstr.channel_count, pkeSettings.mem_bkt.game_transient); + params_low_pass_filter = pk_new<pke_audio_fx_params_low_pass_filter>(pke_audio_mstr.channel_count, pkeSettings.mem_bkt.game_transient); dst = pke_audio_mstr.buffer + (pke_audio_mstr.buffer_frames * pke_audio_mstr.channel_count); @@ -244,22 +244,38 @@ void pke_audio_process_frames(int64_t frame_count) { break; } } - float dot_dir = glm::dot(spatial_normals[c], audio_dir); - if (!glm::isnan(dot_dir) && dot_dir < 0.0) { - // fprintf(stderr, "[pw] dot: %f\n", dot_dir); + dot = glm::dot(glm::vec3(0.f, 0.f, 1.f), audio_dir); + dot2 = glm::dot(spatial_normals[c], audio_dir); - // 20k max, 500 min - params_low_pass_filter[c].cutoff_freq = log_interp(500.f, 20000.f, abs(dot_dir)); - } else { - params_low_pass_filter[c].cutoff_freq = 0.f; - } + params_low_pass_filter[c].cutoff_freq = 0.f; params_reverb[c].reverb_strength = 0.f; // TODO params_delay[c].delay_frames = 0; // TODO - // spatial_volumes[c] = glm::clamp(dot_dir, 0.f, 1.f); - spatial_volumes[c] = lerp(0.f, 1.f, dot_dir + 0.85f); - - if (isnan(spatial_volumes[c]) || spatial_volumes[c] == 0.0f) { + spatial_volumes[c] = PK_CLAMP(dot2, 0.f, 1.f); + if (pke_audio_mstr.channel_count == 2) { + /* 2025-07-15 JCB + * I changed this to always calculate for "forward". + * I believe this is only needed if channel_count == 2; this is to simulate surround through stereo (headphones). + * If the user is actually using surround sound, their own ears will do this. + */ + if (!glm::isnan(dot)) { + val = (dot + 1.f) / 2.f; // padding lerp val + spatial_volumes[c] = PK_CLAMP(dot2 + lerp(0.5, 1.f, val) + 0.05, 0.0f, 1.f); + if (dot < 0.0) { + // 20k max, 500 min + params_low_pass_filter[c].cutoff_freq = log_interp(40000.f, 500.f, abs(dot)); + } + } + } + /* + fprintf(stdout, "[pw] normal: % 02.0f,% 02.0f, audio_dir: % 02.6f,% 02.6f, dot: % 02.6f, dot2: % 02.6f, dot3: % 02.6f, cutoff: % 5.6f, spatial_volumes:% 02.6f\n", + spatial_normals[c].x, spatial_normals[c].z, + audio_dir.x, audio_dir.z, + dot, dot2, dot + dot2, params_low_pass_filter[c].cutoff_freq, spatial_volumes[c]); + */ + + if (isnan(spatial_volumes[c])) { /* + * || spatial_volumes[c] == 0.0f fprintf(stderr, "[pw] NaN or 0: chan: %i, norm: %f,%f,%f, src: %f,%f,%f, origin: %f,%f,%f\n", c, audio_dir.x, audio_dir.y, audio_dir.z, @@ -356,12 +372,5 @@ void pke_audio_process_frames(int64_t frame_count) { memset(dst, 0, sizeof(float) * frame_count * pke_audio_mstr.channel_count); } - // cleanup (reverse order) - pk_delete<pke_audio_fx_params_low_pass_filter>(params_low_pass_filter, pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - pk_delete<pke_audio_fx_params_delay>(params_delay, pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - pk_delete<pke_audio_fx_params_reverb>(params_reverb, pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - pk_delete<glm::vec3>(spatial_normals, pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - pk_delete<float>(spatial_volumes, pke_audio_mstr.channel_count, pke_audio_mstr.bkt); - pke_audio_mstr.buffer_frames += frame_count; } diff --git a/tests/pke-test-audio.cpp b/tests/pke-test-audio.cpp index 4607033..3299576 100644 --- a/tests/pke-test-audio.cpp +++ b/tests/pke-test-audio.cpp @@ -140,13 +140,13 @@ int pke_test_audio_003() { Entity_Base *ent = ECS_CreateGenericEntity(); CompInstance *inst = ECS_CreateInstance(ent, pk_uuid_zed, nullptr, &inst_pos); - uint64_t dur_seconds = 2; + uint64_t dur_seconds = 4; uint64_t total_frames = PKE_AUDIO_BITRATE * dur_seconds; AssetHandle ahs[1]; const AssetKey aks[1] {"sawtooth"}; float freqs[1] = {2000.f}; glm::vec3 src_poss[1] = { - glm::vec3(5, 0, 5), + glm::vec3(-5, 0, 0), }; for(k = 0; k < 1; ++k) { @@ -179,7 +179,7 @@ int pke_test_audio_003() { delta_elapsed += delta; pke_audio_tick(delta); - glm::vec3 rot_pos = glm::rotate(glm::mat4(1.f), glm::radians(360.f) * delta_elapsed, glm::vec3(0.f, 1.f, 0.f)) * glm::vec4(5.f, 0.f, 5.f, 1.f); + glm::vec3 rot_pos = glm::rotate(glm::mat4(1.f), glm::radians(180.f) * delta_elapsed, glm::vec3(0.f, 1.f, 0.f)) * glm::vec4(src_poss[0], 1.f); GlmToBullet(rot_pos, trfm.getOrigin()); // NOTE: fine for a test, but prefer ECS_UpdateInstance() inst->bt.rigidBody->setWorldTransform(trfm); |
