diff --git a/.gitignore b/.gitignore index 8871e10..d91243a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,4 @@ -# jukebox specific -resources/data/config/* -resources/data/save/* -resources/editor/export/* - # User Specific Generated Files **/.vs/* **/.vscode/* @@ -67,5 +62,3 @@ compile_commands.json # This is the default naming convention use for generating cmake builds. # If the user did not configure there project properly then this is here to prevent an accidental push of these files cmake-build-*/ - -*.xm diff --git a/app/src/Application.cpp b/app/src/Application.cpp index 1105fb3..0b3e04c 100644 --- a/app/src/Application.cpp +++ b/app/src/Application.cpp @@ -7,7 +7,7 @@ namespace juke { Application::Application() { if (!m_engine) { throw std::runtime_error{"Failed to create Engine"}; } - auto window = gvdi::Context::create_window({400.0f, 200.0f}, "Jukebox"); + auto window = gvdi::Context::create_window({400.0f, 400.0f}, "Jukebox"); if (!window) { throw std::runtime_error{"Failed to create window"}; } glfwSetWindowUserPointer(window.get(), this); diff --git a/app/src/MediaPlayer.cpp b/app/src/MediaPlayer.cpp index 7712368..7071205 100644 --- a/app/src/MediaPlayer.cpp +++ b/app/src/MediaPlayer.cpp @@ -20,22 +20,55 @@ void MediaPlayer::handle_input() { ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove; if (ImGui::Begin("Player", nullptr, flags)) { + /* ImGui variables */ static auto looping{true}; + static auto spatialized{false}; + static auto gain{1.f}; + static auto pan{0.f}; + static auto pitch{1.f}; + static float pos[] = {0.f, 0.f, 0.f}; + + /* Metadata & Info */ + ImGui::Text("File Name: "); + ImGui::SameLine(); + m_jukebox.has_file() ? ImGui::TextColored(colors::blue, "%s", m_jukebox.get_filename().c_str()) : ImGui::TextColored(colors::grey, ""); + ImGui::Text("Media Status: %s", m_jukebox.is_playing() ? "playing" : "paused"); + + ImGui::Separator(); + /* Control Buttons */ if (ImGui::Button("play")) { m_jukebox.play(looping); } ImGui::SameLine(); if (ImGui::Button("pause")) { m_jukebox.pause(); } ImGui::SameLine(); if (ImGui::Button("stop")) { m_jukebox.stop(); } - ImGui::SameLine(); - ImGui::Checkbox("loop", &looping); - ImGui::Separator(); + if (ImGui::TreeNode("advanced", "advanced")) { - /* Metadata & Info */ - ImGui::Text("File Name: "); - ImGui::SameLine(); - m_jukebox.has_file() ? ImGui::TextColored(colors::blue, "%s", m_jukebox.get_filename().c_str()) : ImGui::TextColored(colors::grey, ""); - ImGui::Text("Media Status: %s", m_jukebox.is_playing() ? "playing" : "paused"); + if (ImGui::Button("reset")) { + gain = 1.f; + pitch = 1.f; + pan = 0.f; + } + + ImGui::Checkbox("loop", &looping); + + ImGui::SliderFloat("volume", &gain, 0.f, 1.f); + ImGui::SliderFloat("pitch", &pitch, 0.f, 2.f); + ImGui::SliderFloat("pan", &pan, -1.f, 1.f); + m_jukebox.set_gain(gain); + m_jukebox.set_pitch(pitch); + m_jukebox.set_pan(pan); + + ImGui::Checkbox("spatialized", &spatialized); + m_jukebox.set_spatialized(spatialized); + if (m_jukebox.is_spatialized()) { + ImGui::Separator(); + ImGui::SliderFloat3("position", pos, -1.f, 1.f, "%.1f"); + m_jukebox.set_position(capo::Vec3f{pos[0], pos[1], pos[2]}); + if (ImGui::Button("reset")) { pos[0] = pos[1] = pos[2] = 0.f; } + } + ImGui::TreePop(); + } } ImGui::End(); } diff --git a/examples/bossanova.xm b/examples/bossanova.xm new file mode 100644 index 0000000..992aa2e Binary files /dev/null and b/examples/bossanova.xm differ diff --git a/examples/glitchified.xm b/examples/glitchified.xm new file mode 100644 index 0000000..333ba81 Binary files /dev/null and b/examples/glitchified.xm differ diff --git a/examples/honkytonk.xm b/examples/honkytonk.xm new file mode 100644 index 0000000..cdc98e5 Binary files /dev/null and b/examples/honkytonk.xm differ diff --git a/library/include/juke/juke.hpp b/library/include/juke/juke.hpp index 731e1dd..dcff637 100644 --- a/library/include/juke/juke.hpp +++ b/library/include/juke/juke.hpp @@ -28,6 +28,26 @@ class Jukebox { /// \brief Stop audio and set cursor to beginning. This does not work for XM format. void stop(); + /* capo API wrapper functions */ + + // setters + void set_gain(float gain) { m_source->set_gain(gain); } + void set_pitch(float pitch) { m_source->set_pitch(pitch); } + void set_pan(float pan) { m_source->set_pan(pan); } + void set_fade_in(std::chrono::duration duration, float gain) { m_source->set_fade_in(duration, gain); } + void set_fade_out(std::chrono::duration duration) { m_source->set_fade_out(duration); } + void set_position(capo::Vec3f pos) { m_source->set_position(pos); } + void set_spatialized(bool spatialized) { m_source->set_spatialized(spatialized); } + + //getters + [[nodiscard]] auto get_gain() const -> float { return m_source->get_gain(); } + [[nodiscard]] auto get_pitch() const -> float { return m_source->get_pitch(); } + [[nodiscard]] auto get_pan() const -> float { return m_source->get_pan(); } + [[nodiscard]] auto get_position() const -> capo::Vec3f { return m_source->get_position(); } + [[nodiscard]] auto is_spatialized() const -> bool { return m_source->is_spatialized(); } + + /* -------------------------- */ + /// \brief Get the name of the loaded file as a string. [[nodiscard]] auto get_filename() const& -> std::string { return m_media_file->get_filename(); }