diff --git a/.github/workflows/plugins_build_7.yml b/.github/workflows/plugins_build_7.yml index 989c4e05..b118242c 100644 --- a/.github/workflows/plugins_build_7.yml +++ b/.github/workflows/plugins_build_7.yml @@ -19,7 +19,7 @@ on: workflow_dispatch: env: - CSOUND_VERSION: 7.0.0-beta.18 + CSOUND_VERSION: 7.0.0 FAUST_VERSION: 2.88.0 VCPKG_BINARY_SOURCES: "clear;files,${{ github.workspace }}/vcpkg-cache,readwrite" diff --git a/7.x/CMakeLists.txt b/7.x/CMakeLists.txt index 734f933d..07eb007c 100644 --- a/7.x/CMakeLists.txt +++ b/7.x/CMakeLists.txt @@ -335,3 +335,29 @@ add_subdirectory(./src/CUDA) add_subdirectory(./src/OpenCL) add_subdirectory(./src/stk) add_subdirectory(./src/faustcsound) + +# Exercise the native loader as well as compilation against the Csound headers. +if(NOT WASM AND (TARGET chua OR TARGET linear_algebra OR TARGET fluidOpcodes)) + find_package(GTest QUIET) + if(GTest_FOUND) + add_executable(plugin_load_tests tests/plugin_load_test.cpp) + set_target_properties(plugin_load_tests PROPERTIES + CXX_STANDARD 14 + CXX_STANDARD_REQUIRED ON) + target_include_directories(plugin_load_tests PRIVATE ${CSOUND_INCLUDE_DIRS}) + target_link_libraries(plugin_load_tests PRIVATE GTest::gtest_main ${CSOUND_LIBRARY}) + foreach(plugin IN ITEMS chua linear_algebra fluidOpcodes) + if(TARGET ${plugin}) + if(plugin STREQUAL "fluidOpcodes") + set(test_name FLUID) + else() + string(TOUPPER "${plugin}" test_name) + endif() + target_compile_definitions(plugin_load_tests PRIVATE + CSOUND_TEST_${test_name}="$") + add_dependencies(plugin_load_tests ${plugin}) + endif() + endforeach() + add_test(NAME plugin_load_tests COMMAND plugin_load_tests) + endif() +endif() diff --git a/7.x/src/chua/ChuaOscillator.cpp b/7.x/src/chua/ChuaOscillator.cpp index 9d7a42ce..1da760c4 100644 --- a/7.x/src/chua/ChuaOscillator.cpp +++ b/7.x/src/chua/ChuaOscillator.cpp @@ -611,6 +611,8 @@ OENTRY oentries[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }}; +PUBLIC int32_t csoundModuleInfo(void) { return CSOUND_MODULE_INFO; } + PUBLIC int32_t csoundModuleCreate(CSOUND *csound) { return 0; } PUBLIC int32_t csoundModuleInit(CSOUND *csound) { diff --git a/7.x/src/fluidOpcodes/fluidOpcodes.cpp b/7.x/src/fluidOpcodes/fluidOpcodes.cpp index 666f76ee..4cf568b4 100644 --- a/7.x/src/fluidOpcodes/fluidOpcodes.cpp +++ b/7.x/src/fluidOpcodes/fluidOpcodes.cpp @@ -283,7 +283,7 @@ class FluidLoad : public csound::OpcodeBase { soundFontId = -1; toa(csound, iFluidSynth, fluidSynth); listPresets = (int32_t)*iListPresets; - CS_TYPE *argType = GetTypeForArg(iFilename); + const CS_TYPE *argType = GetTypeForArg(iFilename); if (strcmp("S", argType->varTypeName) == 0) { filename = csound->Strdup(csound, ((STRINGDAT *)iFilename)->data); } else { diff --git a/7.x/src/linear_algebra/linear_algebra.cpp b/7.x/src/linear_algebra/linear_algebra.cpp index ca9dfa82..ac6eaea4 100644 --- a/7.x/src/linear_algebra/linear_algebra.cpp +++ b/7.x/src/linear_algebra/linear_algebra.cpp @@ -3926,6 +3926,8 @@ class la_k_qr_sym_eigen_mc_t : public OpcodeBase { extern "C" { +PUBLIC int32_t csoundModuleInfo(void) { return CSOUND_MODULE_INFO; } + PUBLIC int32_t csoundModuleCreate(CSOUND *csound) { return 0; } PUBLIC int32_t csoundModuleInit(CSOUND *csound) { diff --git a/7.x/tests/plugin_load_test.cpp b/7.x/tests/plugin_load_test.cpp new file mode 100644 index 00000000..88711d4f --- /dev/null +++ b/7.x/tests/plugin_load_test.cpp @@ -0,0 +1,70 @@ +#include "csound.h" +#include "gtest/gtest.h" +#include + +class PluginLoadTests : public ::testing::Test { +protected: + CSOUND *csound = nullptr; + + void SetUp() override { + // Skip the default plugin directories; rc files may still add libraries. + csound = csoundCreate(nullptr, ""); + ASSERT_NE(csound, nullptr); + csoundCreateMessageBuffer(csound, 0); + } + + void TearDown() override { + csoundDestroy(csound); + } + + std::string messages() { + std::string result; + while (csoundGetMessageCnt(csound)) { + result += csoundGetFirstMessage(csound); + csoundPopFirstMessage(csound); + } + return result; + } + + void compile(const char *plugin, const char *orchestra) { + std::string option = std::string("--opcode-lib=\"") + plugin + "\""; + ASSERT_EQ(csoundSetOption(csound, option.c_str()), 0); + const int result = csoundCompileOrc(csound, orchestra, 0); + const std::string log = messages(); + EXPECT_EQ(result, 0) << log; + // An installed copy can supply the opcodes if the requested library fails. + const std::string loaded = std::string("\nloaded ") + plugin + "\n"; + EXPECT_NE(("\n" + log).find(loaded), std::string::npos) << log; + } +}; + +#ifdef CSOUND_TEST_CHUA +TEST_F(PluginLoadTests, ChuaRegistersItsOpcode) { + compile(CSOUND_TEST_CHUA, R"( + instr 1 + a1, a2, a3 chuap 0.00945, 7.5, 2e-7, 0.00105, 0, -0.00121, 1.76e-5, 1.5e-8, 0, -0.1, 0.1, 5e-6 + endin + )"); +} +#endif + +#ifdef CSOUND_TEST_LINEAR_ALGEBRA +TEST_F(PluginLoadTests, LinearAlgebraRegistersItsOpcodes) { + compile(CSOUND_TEST_LINEAR_ALGEBRA, R"( + instr 1 + ivector la_i_vr_create 3 + endin + )"); +} +#endif + +#ifdef CSOUND_TEST_FLUID +TEST_F(PluginLoadTests, FluidRegistersItsOpcodes) { + compile(CSOUND_TEST_FLUID, R"( + instr 1 + iengine fluidEngine + aleft, aright fluidOut iengine + endin + )"); +} +#endif