#include #include #include #include "glad/glad.h" #include #include "tinydir.h" #include "imgui/imgui.h" #include "imgui/imgui_impl_glfw.h" #include "imgui/imgui_impl_opengl3.h" typedef struct SoundDataListEntry { ClownAudio_SoundData *sound_data; struct SoundDataListEntry *next; } SoundDataListEntry; typedef struct SoundListEntry { ClownAudio_SoundID sound_id; float master_volume; float volume_left; float volume_right; struct SoundListEntry *next; } SoundListEntry; static SoundDataListEntry *sound_data_list_head; static SoundListEntry *sound_list_head; int main(int argc, char *argv[]) { const char *file_directory = argc > 1 ? argv[1] : "."; ///////////////////// // Initialise GLFW // ///////////////////// if (glfwInit()) { const char *glsl_version = "#version 150 core"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); GLFWwindow *window = glfwCreateWindow(800, 600, "clownaudio test program", NULL, NULL); if (window != NULL) { glfwMakeContextCurrent(window); glfwSwapInterval(1); if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { // Check if the platform supports OpenGL 3.2 if (GLAD_GL_VERSION_3_2) { /////////////////////////// // Initialise Dear ImGui // /////////////////////////// IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); /////////////////////////// // Initialise clownaudio // /////////////////////////// if (ClownAudio_Init()) { ClownAudio_SoundDataConfig data_config; ClownAudio_InitSoundDataConfig(&data_config); ClownAudio_SoundConfig sound_config; ClownAudio_InitSoundConfig(&sound_config); SoundDataListEntry *selected_sound_data = NULL; SoundListEntry *selected_sound = NULL; int intro_file = 0; int loop_file = 0; // tinydir stuff tinydir_dir dir; tinydir_open_sorted(&dir, file_directory); tinydir_file *files = (tinydir_file*)malloc(sizeof(tinydir_file) * dir.n_files); size_t files_total = 0; for (size_t i = 0; i < dir.n_files; ++i) { tinydir_readfile_n(&dir, &files[files_total], i); if (!files[files_total].is_dir) ++files_total; } tinydir_close(&dir); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); ImGui::Begin("Sound Data Creation", NULL, ImGuiWindowFlags_AlwaysAutoResize); struct FuncHolder { static bool ItemGetter(void* data, int idx, const char** out_str) { if (idx == 0) { *out_str = "No file"; } else { tinydir_file *files = (tinydir_file*)data; *out_str = files[idx - 1].name; } return true; } }; ImGui::Combo("Intro file", &intro_file, &FuncHolder::ItemGetter, files, files_total + 1); ImGui::Combo("Loop file", &loop_file, &FuncHolder::ItemGetter, files, files_total + 1); ImGui::Spacing(); ImGui::Checkbox("Predecode", &data_config.predecode); ImGui::Checkbox("Must predecode", &data_config.must_predecode); ImGui::Checkbox("Dynamic sample rate", &data_config.dynamic_sample_rate); ImGui::Spacing(); if (ImGui::Button("Load sound data")) { ClownAudio_SoundData *sound_data = ClownAudio_LoadSoundDataFromFiles(intro_file == 0 ? NULL : files[intro_file - 1].path, loop_file == 0 ? NULL : files[loop_file - 1].path, &data_config); if (sound_data != NULL) { SoundDataListEntry *new_entry = (SoundDataListEntry*)malloc(sizeof(SoundDataListEntry)); new_entry->sound_data = sound_data; new_entry->next = NULL; SoundDataListEntry **entry = &sound_data_list_head; while (*entry != NULL) entry = &(*entry)->next; *entry = new_entry; if (selected_sound_data == NULL) selected_sound_data = new_entry; } } ImGui::End(); ImGui::Begin("Sound Creation", NULL, ImGuiWindowFlags_AlwaysAutoResize); if (selected_sound_data == NULL) { ImGui::Text("No sound data selected..."); } else { ImGui::Checkbox("Loop", &sound_config.loop); ImGui::Checkbox("Do not free when done", &sound_config.do_not_free_when_done); ImGui::Checkbox("Dynamic sample rate", &sound_config.dynamic_sample_rate); ImGui::Spacing(); if (ImGui::Button("Create sound")) { ClownAudio_SoundID sound_id = ClownAudio_CreateSound(selected_sound_data->sound_data, &sound_config); if (sound_id != 0) { SoundListEntry *new_entry = (SoundListEntry*)malloc(sizeof(SoundListEntry)); new_entry->sound_id = sound_id; new_entry->master_volume = 1.0f; new_entry->volume_left = 1.0f; new_entry->volume_right = 1.0f; new_entry->next = NULL; SoundListEntry **entry = &sound_list_head; while (*entry != NULL) entry = &(*entry)->next; *entry = new_entry; if (selected_sound == NULL) selected_sound = new_entry; } } } ImGui::End(); ImGui::Begin("Sound Data", NULL); for (SoundDataListEntry *entry = sound_data_list_head; entry != NULL; entry = entry->next) { char name[32]; sprintf(name, "Sound data %p", entry->sound_data); if (ImGui::Selectable(name, selected_sound_data == entry)) selected_sound_data = entry; } if (selected_sound_data != NULL) { ImGui::Spacing(); if (ImGui::Button("Destroy")) { ClownAudio_UnloadSoundData(selected_sound_data->sound_data); for (SoundDataListEntry **entry = &sound_data_list_head; *entry != NULL; entry = &(*entry)->next) { if (*entry == selected_sound_data) { SoundDataListEntry *next_sound_data = (*entry)->next; free(*entry); *entry = next_sound_data; selected_sound_data = *entry == NULL ? NULL : *entry; break; } } } } ImGui::End(); ImGui::Begin("Sounds", NULL); for (SoundListEntry *entry = sound_list_head; entry != NULL; entry = entry->next) { int status = ClownAudio_GetSoundStatus(entry->sound_id); char name[32]; switch (status) { case 0: sprintf(name, "Sound %u - Playing", entry->sound_id); break; case 1: sprintf(name, "Sound %u - Paused", entry->sound_id); break; case -1: sprintf(name, "Sound %u - Freed", entry->sound_id); break; } if (ImGui::Selectable(name, selected_sound == entry)) selected_sound = entry; } if (selected_sound != NULL) { ImGui::Spacing(); if (ImGui::Button("Destroy")) { ClownAudio_DestroySound(selected_sound->sound_id); for (SoundListEntry **entry = &sound_list_head; *entry != NULL; entry = &(*entry)->next) { if (*entry == selected_sound) { SoundListEntry *next_sound = (*entry)->next; free(*entry); *entry = next_sound; break; } } selected_sound = NULL; } } ImGui::End(); ImGui::Begin("Sound Controls", NULL, ImGuiWindowFlags_AlwaysAutoResize); if (selected_sound == NULL) { ImGui::Text("No sound selected..."); } else { int status = ClownAudio_GetSoundStatus(selected_sound->sound_id); if (status == -1) { ImGui::Text("Selected sound has been freed..."); } else { if (status == 0) { if (ImGui::Button("Pause")) ClownAudio_PauseSound(selected_sound->sound_id); } else { if (ImGui::Button("Unpause")) ClownAudio_UnpauseSound(selected_sound->sound_id); } ImGui::SameLine(); if (ImGui::Button("Rewind")) ClownAudio_RewindSound(selected_sound->sound_id); ImGui::Spacing(); if (ImGui::Button("Fade-out")) ClownAudio_FadeOutSound(selected_sound->sound_id, 5 * 1000); ImGui::SameLine(); if (ImGui::Button("Fade-in")) ClownAudio_FadeInSound(selected_sound->sound_id, 5 * 1000); ImGui::SameLine(); if (ImGui::Button("Cancel fade")) ClownAudio_CancelFade(selected_sound->sound_id); ImGui::Spacing(); if (ImGui::SliderFloat("Master volume", &selected_sound->master_volume, 0.0f, 1.0f, "%.3f", 2.0f)) ClownAudio_SetSoundVolume(selected_sound->sound_id, selected_sound->master_volume * selected_sound->volume_left * 0x100, selected_sound->master_volume * selected_sound->volume_right * 0x100); if (ImGui::SliderFloat("Left volume", &selected_sound->volume_left, 0.0f, 1.0f, "%.3f", 2.0f)) ClownAudio_SetSoundVolume(selected_sound->sound_id, selected_sound->master_volume * selected_sound->volume_left * 0x100, selected_sound->master_volume * selected_sound->volume_right * 0x100); if (ImGui::SliderFloat("Right volume", &selected_sound->volume_right, 0.0f, 1.0f, "%.3f", 2.0f)) ClownAudio_SetSoundVolume(selected_sound->sound_id, selected_sound->master_volume * selected_sound->volume_left * 0x100, selected_sound->master_volume * selected_sound->volume_right * 0x100); ImGui::Spacing(); static int sample_rate = 0; ImGui::InputInt("Sample rate", &sample_rate, 0); if (ImGui::Button("Apply sample rate")) ClownAudio_SetSoundSampleRate(selected_sound->sound_id, sample_rate, sample_rate); } } ImGui::End(); ImGui::ShowDemoWindow(); ImGui::Render(); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } free(files); ClownAudio_Deinit(); } } } } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwDestroyWindow(window); glfwTerminate(); } return 0; }