diff --git a/release-packaging/Classes/FluidHPSS.sc b/release-packaging/Classes/FluidHPSS.sc index c0040fa..7633063 100644 --- a/release-packaging/Classes/FluidHPSS.sc +++ b/release-packaging/Classes/FluidHPSS.sc @@ -1,12 +1,20 @@ FluidHPSS : MultiOutUGen { - *ar { arg in = 0, percussiveFilterSize = 17, harmonicFilterSize = 17, percussiveThreshold = 50, harmonicThreshold = 50, windowSize= 1024, hopSize= 256, fftSize= -1; - ^this.multiNew('audio', in.asAudioRateInput(this),harmonicFilterSize,percussiveFilterSize,percussiveThreshold,harmonicThreshold,windowSize, hopSize, fftSize) + *ar { arg in = 0, percussiveFilterSize = 17, harmonicFilterSize=17, harmonicBinaryMask=0, percussiveBinaryMask=0, + percussiveThreshFreq1=0, percussiveThreshAmp1=0,percussiveThreshFreq2=1.0, percussiveThreshAmp2=0, + harmonicThreshFreq1=0, harmonicThreshAmp1=0, harmonicThreshFreq2=1.0, harmonicThreshAmp2=0, + windowSize= 1024, hopSize= 256, fftSize= -1; + ^this.multiNew('audio', in.asAudioRateInput(this), percussiveFilterSize, harmonicFilterSize, + harmonicBinaryMask,percussiveBinaryMask, + percussiveThreshFreq1, percussiveThreshAmp1,percussiveThreshFreq2, percussiveThreshAmp2, + harmonicThreshFreq1, harmonicThreshAmp1, harmonicThreshFreq2, harmonicThreshAmp2, + windowSize, hopSize, fftSize) } init { arg ... theInputs; inputs = theInputs; channels = [ OutputProxy(rate, this, 0), - OutputProxy(rate, this, 1) + OutputProxy(rate, this, 1), + OutputProxy(rate, this, 2) ]; ^channels } diff --git a/src/FluidHPSS/FluidHPSS.cpp b/src/FluidHPSS/FluidHPSS.cpp index f097e7c..9f193c3 100644 --- a/src/FluidHPSS/FluidHPSS.cpp +++ b/src/FluidHPSS/FluidHPSS.cpp @@ -12,31 +12,25 @@ namespace hpss{ { using AudioSignalWrapper = hpss::HPSSClient::AudioSignal; using SignalWrapper = hpss::HPSSClient::Signal; - - // using SignalPointer = std::unique_ptr; + using SignalPointer = std::unique_ptr; + using ClientPointer = std::unique_ptr>; + template + using SignalArray = std::array; public: FDRTHPSS() { //Order of args //psize hszie pthresh hthresh Window size, Hop size, FFT Size - - //Get the window size -// const float hfilter_size = in0(1); -// const float pfilter_size = in0(2); -// const float window_size = in0(3); -// const float hop_size = in0(4); -// const float fft_size = in0(5); - - + //Oh NO! Heap allocation! Make client object - m_client = new hpss::HPSSClient(65536); + mClient = ClientPointer(new hpss::HPSSClient(65536)); setParams(true); bool isOK; std::string feedback; - std::tie(isOK, feedback) = m_client->sanityCheck(); + std::tie(isOK, feedback) = mClient->sanityCheck(); if(!isOK) { Print("fdRTHPSS Error: %s",feedback.c_str()); @@ -44,37 +38,30 @@ namespace hpss{ } - m_client->set_host_buffer_size(bufferSize()); - m_client->reset(); + mClient->set_host_buffer_size(bufferSize()); + mClient->reset(); //Work out what signals we need. For now keep it simple: - //in 0 => only audio - //out 0 => only audio - input_signals[0] = new AudioSignalWrapper(); - output_signals[0] = new AudioSignalWrapper(); - output_signals[1] = new AudioSignalWrapper(); + input_signals[0] = SignalPointer(new AudioSignalWrapper()); + output_signals[0] = SignalPointer(new AudioSignalWrapper()); + output_signals[1] = SignalPointer(new AudioSignalWrapper()); + output_signals[2] = SignalPointer(new AudioSignalWrapper()); mCalcFunc = make_calc_function(); Unit* unit = this; ClearUnitOutputs(unit,1); } - ~FDRTHPSS() - { - delete input_signals[0]; - delete output_signals[0]; - delete output_signals[1]; - delete m_client; - } + ~FDRTHPSS() {} private: void setParams(bool instantiation) { - assert(m_client); - for(size_t i = 0; i < m_client->getParams().size(); ++i) + assert(mClient); + for(size_t i = 0; i < mClient->getParams().size(); ++i) { - parameter::Instance& p = m_client->getParams()[i]; + parameter::Instance& p = mClient->getParams()[i]; if(!instantiation && p.getDescriptor().instantiation()) continue; switch(p.getDescriptor().getType()) @@ -84,8 +71,25 @@ namespace hpss{ p.checkRange(); break; case parameter::Type::Float: + { + + //We need to constrain threshold (normalised) frequency pairs at runtime. + std::string attrname = p.getDescriptor().getName(); + auto constraint = paramConstraints.find(attrname); + + if(constraint != paramConstraints.end()) + { + double limit = parameter::lookupParam(constraint->second.param, mClient->getParams()).getFloat(); + + if(!constraint->second.condition(in0(i+1),limit)) + { + return; + } + } + p.setFloat(in0(i+1)); p.checkRange(); + } break; case parameter::Type::Buffer: // p.setBuffer( in0(i+1)); @@ -104,12 +108,26 @@ namespace hpss{ input_signals[0]->set(const_cast(input), inscalar); output_signals[0]->set(out(0), out0(0)); output_signals[1]->set(out(1), out0(1)); - m_client->do_process(std::begin(input_signals),std::end(input_signals),std::begin(output_signals), std::end(output_signals),numsamples,1,2); + output_signals[2]->set(out(2), out0(2)); + mClient->do_process(std::begin(input_signals),std::end(input_signals),std::begin(output_signals), std::end(output_signals),numsamples,1,3); } - hpss::HPSSClient* m_client; - SignalWrapper* input_signals[1]; - SignalWrapper* output_signals[2]; + struct Constraint{ + std::string param; + std::function condition; + }; + + std::map paramConstraints{ + {"pthreshf1",{"pthreshf2", std::less()}}, + {"hthreshf1",{"hthreshf2", std::less()}}, + {"pthreshf2",{"pthreshf1", std::greater()}}, + {"hthreshf2",{"hthreshf1", std::greater()}} + }; + + + ClientPointer mClient; + SignalArray<1> input_signals; + SignalArray<3> output_signals; }; } }