#include "./pke-test-audio.h" #include "ecs.hpp" #include "game-settings.hpp" #include "math-helpers.hpp" #include "physics.hpp" #include "pk.h" #include "audio-types.hpp" #include "audio.hpp" #include "asset-manager.hpp" #include "pke-test-stubs.h" #include "thread-pool.hpp" #include "window.hpp" #include #include #include static pk_membucket *bkt = nullptr; #define PKE_TEST_AUDIO_SLEEP_DUR_NS 10 void pke_test_audio_spinup() { pke_test_stub_init_vulkan(); // pk_funcinstr_init(); pkeSettings.isSimulationPaused = true; bkt = pk_mem_bucket_create("pke_test_audio", PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE); pk_mem_bucket_set_client_mem_bucket(bkt); pk_ev_init(bkt); PkeThreads_Init(); AM_Init(); Physics_Init(); ECS_Init(); pke_audio_init(); pke_audio_mstr.master_volume = 0.125; // pk_funcinstr_teardown(); }; void pke_test_audio_teardown() { // pk_funcinstr_init(); pke_audio_teardown(); ECS_Teardown(); Physics_Teardown(); AM_Teardown(); PkeThreads_Teardown(); pk_ev_teardown(); pk_mem_bucket_destroy(bkt); pk_mem_bucket_set_client_mem_bucket(nullptr); bkt = nullptr; // pk_funcinstr_teardown(); pke_test_stub_teardown_vulkan(); }; int pke_test_audio_001() { uint32_t i; try { UBO.model = glm::translate(glm::mat4(1.f), glm::vec3(0, 0, 0)); float *zip_bop_bytes = pk_new_arr(PKE_AUDIO_BITRATE, bkt); float phase = 0.0f; float phase_increment = 440.f / float(PKE_AUDIO_BITRATE); for (i = 0; i < PKE_AUDIO_BITRATE; ++i) { zip_bop_bytes[i] = 2.f * (phase - floor(phase + 0.5f)); phase += phase_increment; if (phase >= 1.f) phase -= 1.f; } const AssetKey ak_sawtooth {"sawthooth"}; AssetHandle ah_sawtooth = AM_Register(ak_sawtooth, PKE_ASSET_TYPE_AUDIO, zip_bop_bytes, sizeof(float) * PKE_AUDIO_BITRATE, 64); pk_delete_arr(zip_bop_bytes, PKE_AUDIO_BITRATE, bkt); pke_audio_play(ah_sawtooth, pke_audio_source_music, pke_audio_flag_none, glm::vec3(0)); while (pke_audio_mstr.playing_objects.next > 0) { pke_audio_tick(0.001f); std::this_thread::sleep_for(std::chrono::nanoseconds(PKE_TEST_AUDIO_SLEEP_DUR_NS)); } AM_Release(ah_sawtooth); } catch (const std::exception &ex) { throw; } return 0; } int pke_test_audio_002() { uint32_t i, k; try { UBO.model = glm::translate(glm::mat4(1.f), glm::vec3(0, 0, 0)); AssetHandle ahs[3]; const AssetKey aks[3] {"sawtooth", "sawtooth2", "sawtooth3"}; float freqs[3] = {440.f, 110.f, 330.f}; glm::vec3 src_poss[3] = { glm::vec3(-1, 0, 3), glm::vec3( 0, 0, 0), glm::vec3( 1, 0, 0), }; for(k = 0; k < 3; ++k) { float *zip_bop_bytes = pk_new_arr(PKE_AUDIO_BITRATE, bkt); float phase = 0.0f; float phase_increment = freqs[k] / float(PKE_AUDIO_BITRATE); for (i = 0; i < PKE_AUDIO_BITRATE; ++i) { zip_bop_bytes[i] = 2.f * (phase - floor(phase + 0.5f)); phase += phase_increment; if (phase >= 1.f) phase -= 1.f; } ahs[k] = AM_Register(aks[k], PKE_ASSET_TYPE_AUDIO, zip_bop_bytes, sizeof(float) * PKE_AUDIO_BITRATE, 64); pk_delete_arr(zip_bop_bytes, PKE_AUDIO_BITRATE, bkt); } std::chrono::milliseconds(1); for(k = 0; k < 3; ++k) { pke_audio_play(ahs[k], pke_audio_source_music, pke_audio_flag_pos_spatial, src_poss[k]); } while (pke_audio_mstr.playing_objects.next > 0) { pke_audio_tick(0.001f); std::this_thread::sleep_for(std::chrono::nanoseconds(PKE_TEST_AUDIO_SLEEP_DUR_NS)); } for(k = 0; k < 3; ++k) { AM_Release(ahs[k]); } } catch (const std::exception &ex) { throw; } return 0; } int pke_test_audio_003() { uint64_t i, k; try { UBO.model = glm::translate(glm::mat4(1.f), glm::vec3(0, 0, 0)); InstPos inst_pos{}; Entity_Base *ent = ECS_CreateGenericEntity(); CompInstance *inst = ECS_CreateInstance(ent, pk_uuid_zed, nullptr, &inst_pos); 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, 0), }; for(k = 0; k < 1; ++k) { float *zip_bop_bytes = pk_new_arr(total_frames, bkt); float phase = 0.0f; float phase_increment = freqs[k] / float(PKE_AUDIO_BITRATE); for (i = 0; i < total_frames; ++i) { zip_bop_bytes[i] = 2.f * (phase - floor(phase + 0.5f)); phase += phase_increment; if (phase >= 1.f) phase -= 1.f; } ahs[k] = AM_Register(aks[k], PKE_ASSET_TYPE_AUDIO, zip_bop_bytes, sizeof(float) * total_frames, 64); pk_delete_arr(zip_bop_bytes, total_frames, bkt); } for(k = 0; k < 1; ++k) { pke_audio_play(ahs[k], pke_audio_source_music, pke_audio_flag_pos_spatial, src_poss[k], inst->instanceHandle); } float delta = 0.f; float delta_elapsed = 0.f; btTransform trfm{}; std::chrono::time_point ts = std::chrono::steady_clock::now(); std::chrono::time_point now = std::chrono::steady_clock::now(); while (pke_audio_mstr.playing_objects.next > 0) { now = std::chrono::steady_clock::now(); auto ts_diff = now - ts; delta = ts_diff.count() / 1000000000.f; ts = now; delta_elapsed += delta; pke_audio_tick(delta); 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); // fprintf(stdout, "%f,%f,%f\n", rot_pos.x, rot_pos.y, rot_pos.z); std::this_thread::sleep_for(std::chrono::nanoseconds(PKE_TEST_AUDIO_SLEEP_DUR_NS)); } for(k = 0; k < 1; ++k) { AM_Release(ahs[k]); } } catch (const std::exception &ex) { throw; } return 0; } struct pk_test_group *pke_test_audio_get_group() { static const uint64_t test_count = 3; static struct pk_test tests[test_count] = { { .title = "test 001", .func = pke_test_audio_001, .expected_result = 0, }, { .title = "test 002", .func = pke_test_audio_002, .expected_result = 0, }, { .title = "test 003", .func = pke_test_audio_003, .expected_result = 0, }, }; static struct pk_test_group group = {}; group.title = "audio"; group.group_setup = nullptr; group.group_teardown = nullptr; group.test_setup = pke_test_audio_spinup; group.test_teardown = pke_test_audio_teardown; group.n_tests = test_count; group.tests = &tests[0]; return &group; }