diff --git a/fdSTFTPass/CMakeLists.txt b/fdSTFTPass/CMakeLists.txt new file mode 100755 index 0000000..0830062 --- /dev/null +++ b/fdSTFTPass/CMakeLists.txt @@ -0,0 +1,120 @@ +####### original SC Cmake file starts here +cmake_minimum_required (VERSION 3.1) +get_filename_component(PROJECT ${CMAKE_SOURCE_DIR} NAME_WE) #automatically sets project name from the filename +message(STATUS "Project name is ${PROJECT}") +project (${PROJECT}) + +####### added the eingenmf +set(FLUID_DECOMP_DIR ~/fluid_decomposition) +set(FILENAME "fdSTFTPass.cpp") #specify the .cpp file here + +set(CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED ON) + +add_library( +${PROJECT} +MODULE +${FILENAME} +"${FLUID_DECOMP_DIR}/3rdparty/HISSTools_FFT/HISSTools_FFT.cpp" +) + +add_custom_command( + TARGET + ${PROJECT} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "../../release-packaging/${PROJECT}/plugins" + COMMAND ${CMAKE_COMMAND} -E copy $ "../../release-packaging/${PROJECT}/plugins" +) + +include_directories( + "${FLUID_DECOMP_DIR}" + "${FLUID_DECOMP_DIR}/include" + "${FLUID_DECOMP_DIR}/3rdparty" +) + + +include_directories(${SC_PATH}/include/plugin_interface) +include_directories(${SC_PATH}/include/common) +include_directories(${SC_PATH}/common) + +set(CMAKE_SHARED_MODULE_PREFIX "") +if(APPLE OR WIN32) +set(CMAKE_SHARED_MODULE_SUFFIX ".scx") +endif() + +option(SUPERNOVA "Build plugins for supernova" OFF) +if (SUPERNOVA) + include_directories(${SC_PATH}/external_libraries/nova-tt) + # actually just boost.atomic + include_directories(${SC_PATH}/external_libraries/boost) + include_directories(${SC_PATH}/external_libraries/boost_lockfree) + include_directories(${SC_PATH}/external_libraries/boost-lockfree) +endif() + +option(CPP11 "Build with c++11." ON) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_COMPILER_IS_CLANG 1) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) + add_definitions(-fvisibility=hidden) + + include (CheckCCompilerFlag) + include (CheckCXXCompilerFlag) + + CHECK_C_COMPILER_FLAG(-msse HAS_SSE) + CHECK_CXX_COMPILER_FLAG(-msse HAS_CXX_SSE) + + if (HAS_SSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse") + endif() + if (HAS_CXX_SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse") + endif() + + CHECK_C_COMPILER_FLAG(-msse2 HAS_SSE2) + CHECK_CXX_COMPILER_FLAG(-msse2 HAS_CXX_SSE2) + + if (HAS_SSE2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") + endif() + if (HAS_CXX_SSE2) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2") + endif() + + CHECK_C_COMPILER_FLAG(-mfpmath=sse HAS_FPMATH_SSE) + CHECK_CXX_COMPILER_FLAG(-mfpmath=sse HAS_CXX_FPMATH_SSE) + + if (HAS_FPMATH_SSE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse") + endif() + if (HAS_CXX_FPMATH_SSE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse") + endif() + + if(NATIVE) + add_definitions(-march=native) + endif() + + if(CPP11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + if(CMAKE_COMPILER_IS_CLANG) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + endif() + endif() +endif() +if(MINGW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mstackrealign") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mstackrealign") +endif() + +####### added the fluid_decomposition + +if(SUPERNOVA) + add_library(${PROJECT}_supernova MODULE ${FILENAME}) + set_property(TARGET ${PROJECT}_supernova + PROPERTY COMPILE_DEFINITIONS SUPERNOVA) +endif() + +target_link_libraries (${PROJECT} "-framework Accelerate") diff --git a/fdSTFTPass/fdSTFTPass.cpp b/fdSTFTPass/fdSTFTPass.cpp new file mode 100644 index 0000000..6a5d2a1 --- /dev/null +++ b/fdSTFTPass/fdSTFTPass.cpp @@ -0,0 +1,113 @@ + +// A tool from the FluCoMa project, funded by the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 725899) + +#include "SC_PlugIn.hpp" +#include "data/FluidTensor.hpp" +#include "clients/rt/BaseSTFTClient.hpp" + +//Using statements for fluidtensor +using fluid::FluidTensor; +using fluid::FluidTensorView; +using fluid::audio::BaseSTFTClient; + + +static InterfaceTable *ft; + +using audio_client = BaseSTFTClient; +using audio_signal_wrapper = audio_client::AudioSignal; +using scalar_signal_wrapper = audio_client::ScalarSignal; +using signal_wrapper = audio_client::Signal; + +class FDSTFTPass: public SCUnit +{ +public: + FDSTFTPass() + { + //Order of args + //Window size, Hop size, FFT Size + + //Get the window size + const float window_size = in0(1); + const float hop_size = in0(2); + const float fft_size = in0(3); + + //Oh NO! Heap allocation! Make client object + //This will do argument checking + m_client = new audio_client(window_size, hop_size, fft_size); + + //and we can post strings back about the argument checking + //Params get checked and adjusted during construction, we can pass on warning messages: + std::istringstream param_feedback(m_client->getFeedbackString()); + std::string message; + + while(std::getline(param_feedback, message, '\n')) + Print(message.c_str()); + + m_client->set_host_buffer_size(bufferSize()); + m_client->reset(); + + //Work out what signals we need. For now keep it simple: + //in 0 => only audio + //out 0 => only audio + //out 1 => only audio (and only internal, used for OLA gain compensation) + input_signals[0] = new audio_signal_wrapper(); + output_signals[0] = new audio_signal_wrapper(); + output_signals[1] = new audio_signal_wrapper(); + + m_normalise = new float[bufferSize()]; + + +// set_calc_function(); + mCalcFunc = make_calc_function(); + + Unit* unit = this; + ClearUnitOutputs(unit,1); + + } + + ~FDSTFTPass() + { + delete[] m_normalise; + delete input_signals[0]; + + delete output_signals[0]; + delete output_signals[1]; + + delete m_client; + } + +private: + + void next(int numsamples) + { + //TODO: Remove const_cast code smell by making input_signal type for const + const float* input = in(0); + const float inscalar = in0(0); + float* output = out(0); + + input_signals[0]->set(const_cast(input), inscalar); + + output_signals[0]->set(out(0), out0(0)); + output_signals[1]->set(m_normalise,0); + + m_client->do_process(input_signals,output_signals,numsamples,1,2); + + //We need to normalise *after* the overlap add, because of the way we do it + std::transform(output, output + numsamples, m_normalise, output, std::divides()); + + } + + audio_client* m_client; + signal_wrapper* input_signals[1]; + signal_wrapper* output_signals[2]; + float* m_normalise; +}; + +PluginLoad(BoringMixer2UGens) { + ft = inTable; + registerUnit(ft, "FDSTFTPass"); +} + + + + diff --git a/release-packaging/fdSTFTPass/HelpSource/Classes/FDSTFTPass.schelp b/release-packaging/fdSTFTPass/HelpSource/Classes/FDSTFTPass.schelp new file mode 100644 index 0000000..fc74486 --- /dev/null +++ b/release-packaging/fdSTFTPass/HelpSource/Classes/FDSTFTPass.schelp @@ -0,0 +1,2 @@ +//Ar modulator +{FDSTFTPass.ar(SinOsc.ar(440),1024,256,2048)}.play diff --git a/release-packaging/fdSTFTPass/classes/fdSTFTPass.sc b/release-packaging/fdSTFTPass/classes/fdSTFTPass.sc new file mode 100644 index 0000000..c4a3e8e --- /dev/null +++ b/release-packaging/fdSTFTPass/classes/fdSTFTPass.sc @@ -0,0 +1,5 @@ +FDSTFTPass : UGen { + *ar { arg in = 0, windowsize=1024, hopsize=256, fftsize=windowsize; + ^this.multiNew('audio', in.asAudioRateInput(this),windowsize, hopsize, fftsize) + } +}