From e0d6d59ce9aa956a1bb093c27c2da67991fafc1f Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 14 Jan 2022 20:11:58 +0000 Subject: [PATCH] Start file list for audiofile module --- .github/workflows/build.yml | 9 ++ plugins/Cardinal/src/AudioFile.cpp | 145 ++++++++++++++++++++++++++++- plugins/Makefile | 6 +- 3 files changed, 156 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d61f916..3cc0c7d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -323,6 +323,9 @@ jobs: - name: Build for modduo run: | make modduo HEADLESS=true WITH_LTO=true -j $(nproc) + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" - name: Pack binaries run: | tar -c -h --hard-dereference -z -f ${{ github.event.repository.name }}-modduo-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}.tar.gz -C bin $(ls bin | grep lv2) @@ -358,6 +361,9 @@ jobs: - name: Build for modduox run: | make modduox HEADLESS=true WITH_LTO=true -j $(nproc) + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" - name: Pack binaries run: | tar -c -h --hard-dereference -z -f ${{ github.event.repository.name }}-modduox-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}.tar.gz -C bin $(ls bin | grep lv2) @@ -393,6 +399,9 @@ jobs: - name: Build for moddwarf run: | make moddwarf HEADLESS=true WITH_LTO=true -j $(nproc) + - name: Set sha8 + id: slug + run: echo "::set-output name=sha8::$(echo ${{ github.sha }} | cut -c1-8)" - name: Pack binaries run: | tar -c -h --hard-dereference -z -f ${{ github.event.repository.name }}-moddwarf-${{ github.event.pull_request.number || steps.slug.outputs.sha8 }}.tar.gz -C bin $(ls bin | grep lv2) diff --git a/plugins/Cardinal/src/AudioFile.cpp b/plugins/Cardinal/src/AudioFile.cpp index d2530c4..fad1ae8 100644 --- a/plugins/Cardinal/src/AudioFile.cpp +++ b/plugins/Cardinal/src/AudioFile.cpp @@ -1,6 +1,6 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021 Filipe Coelho + * Copyright (C) 2021-2022 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +22,11 @@ #include "CarlaNativePlugin.h" +#ifndef HEADLESS +# include "ImGuiWidget.hpp" +# include "ghc/filesystem.hpp" +#endif + #define BUFFER_SIZE 128 // generates a warning if this is defined as anything else @@ -81,6 +86,8 @@ struct CarlaInternalPluginModule : Module, Thread { float* dataOutPtr[NUM_OUTPUTS]; unsigned audioDataFill = 0; int64_t lastBlockFrame = -1; + bool fileChanged = false; + std::string currentFile; struct { float preview[108]; @@ -316,6 +323,126 @@ static intptr_t host_dispatcher(const NativeHostHandle handle, const NativeHostD // -------------------------------------------------------------------------------------------------------------------- #ifndef HEADLESS +struct AudioFileListWidget : ImGuiWidget { + CarlaInternalPluginModule* const module; + + bool showError = false; + String errorMessage; + + struct ghcFile { std::string full, base; }; + std::string currentDirectory; + std::vector currentFiles; + size_t selectedFile = (size_t)-1; + + AudioFileListWidget(CarlaInternalPluginModule* const m) + : ImGuiWidget(), + module(m) + { + if (module->fileChanged) + reloadDir(); + } + + void drawImGui() override + { + const float scaleFactor = getScaleFactor(); + + const int flags = ImGuiWindowFlags_NoSavedSettings + | ImGuiWindowFlags_NoTitleBar + | ImGuiWindowFlags_NoResize + | ImGuiWindowFlags_NoCollapse + | ImGuiWindowFlags_NoScrollbar + | ImGuiWindowFlags_NoScrollWithMouse; + + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor)); + + if (ImGui::Begin("Plugin List", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize)) + { + if (showError) + { + showError = false; + ImGui::OpenPopup("Audio File Error"); + } + + if (ImGui::BeginPopupModal("Audio File Error", nullptr, flags)) + { + ImGui::TextWrapped("Failed to load audio file, error was:\n%s", errorMessage.buffer()); + + ImGui::Separator(); + + if (ImGui::Button("Ok")) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); + } + else if (ImGui::BeginTable("pluginlist", 1, ImGuiTableFlags_NoSavedSettings)) + { + for (size_t i=0, count=currentFiles.size(); i < count; ++i) + { + bool wasSelected = selectedFile == i; + bool selected = wasSelected; + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Selectable(currentFiles[i].base.c_str(), &selected); + + if (selected && ! wasSelected) + { + selectedFile = i; + module->currentFile = currentFiles[i].full; + module->fCarlaPluginDescriptor->set_custom_data(module->fCarlaPluginHandle, "file", currentFiles[i].full.c_str()); + } + } + + ImGui::EndTable(); + } + } + + ImGui::End(); + } + + void step() override + { + if (module->fileChanged) + reloadDir(); + + ImGuiWidget::step(); + } + + void reloadDir() + { + module->fileChanged = false; + + static constexpr const char* const supportedExtensions[] = { + #ifdef HAVE_SNDFILE + ".aif",".aifc",".aiff",".au",".bwf",".flac",".htk",".iff",".mat4",".mat5",".oga",".ogg;" + ".paf",".pvf",".pvf5",".sd2",".sf",".snd",".svx",".vcc",".w64",".wav",".xi", + #endif + ".mp3" + }; + + using namespace ghc::filesystem; + currentDirectory = path(module->currentFile).parent_path().string(); + currentFiles.clear(); + + directory_iterator it(currentDirectory); + for (directory_iterator itb = begin(it), ite=end(it); itb != ite; ++itb) + { + if (! itb->is_regular_file()) + continue; + const path filepath = itb->path(); + const path extension = filepath.extension(); + for (size_t i=0; i(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addOutput(createOutput(Vec(box.size.x - RACK_GRID_WIDTH * 5/2, - RACK_GRID_HEIGHT - RACK_GRID_WIDTH - padding * 1), + RACK_GRID_HEIGHT - RACK_GRID_WIDTH - padding * 2), module, 0)); addOutput(createOutput(Vec(box.size.x - RACK_GRID_WIDTH * 5/2, - RACK_GRID_HEIGHT - RACK_GRID_WIDTH - padding * 2), + RACK_GRID_HEIGHT - RACK_GRID_WIDTH - padding * 1), module, 1)); + + if (m != nullptr) + { + AudioFileListWidget* const listw = new AudioFileListWidget(m); + listw->box.pos.x = 0; + listw->box.pos.y = 36; + listw->box.size.x = box.size.x; + listw->box.size.y = box.size.y / 2 - 20; + addChild(listw); + } } void draw(const DrawArgs& args) override @@ -457,6 +594,8 @@ struct AudioFileWidget : ModuleWidget { if (path == nullptr) return; + module->currentFile = path; + module->fileChanged = true; module->fCarlaPluginDescriptor->set_custom_data(module->fCarlaPluginHandle, "file", path); std::free(path); }); diff --git a/plugins/Makefile b/plugins/Makefile index cf4e79e..9f526f1 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -734,7 +734,7 @@ BASE_FLAGS += -I../src BASE_FLAGS += -I../src/Rack/include BASE_FLAGS += -I../src/Rack/include/dsp BASE_FLAGS += -I../src/Rack/dep/include -# # BASE_FLAGS += -I../src/Rack/dep/filesystem/include +BASE_FLAGS += -I../src/Rack/dep/filesystem/include # # BASE_FLAGS += -I../src/Rack/dep/fuzzysearchdatabase/src BASE_FLAGS += -I../src/Rack/dep/glfw/include BASE_FLAGS += -I../src/Rack/dep/nanosvg/src @@ -771,6 +771,10 @@ ifeq ($(NOPLUGINS),true) BASE_FLAGS += -DNOPLUGINS endif +ifeq ($(shell $(PKG_CONFIG) --exists sndfile && echo true),true) +BASE_FLAGS += -DHAVE_SNDFILE +endif + BUILD_C_FLAGS += -std=gnu11 BUILD_C_FLAGS += -fno-finite-math-only BUILD_CXX_FLAGS += -fno-finite-math-only