Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance/slicer detection curves #114

Merged
merged 17 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions include/algorithms/public/Envelope.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Part of the Fluid Corpus Manipulation Project (http://www.flucoma.org/)
Copyright 2017-2019 University of Huddersfield.
Licensed under the BSD-3 License.
See license.md file in the project root for full license information.
This project has received funding from the European Research Council (ERC)
under the European Union’s Horizon 2020 research and innovation programme
(grant agreement No 725899).
*/

#pragma once

#include "../util/ButterworthHPFilter.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../util/SlideUDFilter.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/TensorTypes.hpp"
#include <Eigen/Core>
#include <cmath>

namespace fluid {
namespace algorithm {

class Envelope
{

using ArrayXd = Eigen::ArrayXd;

public:
void init(double floor, double hiPassFreq)
{
mFastSlide.init(floor);
mSlowSlide.init(floor);
initFilters(hiPassFreq);
mHiPassFreq = hiPassFreq;
mInitialized = true;
}

double processSample(const double in,
double floor, index fastRampUpTime, index slowRampUpTime,
index fastRampDownTime, index slowRampDownTime,
double hiPassFreq)
{
using namespace std;
assert(mInitialized);
mFastSlide.updateCoeffs(fastRampUpTime, fastRampDownTime);
mSlowSlide.updateCoeffs(slowRampUpTime, slowRampDownTime);
double filtered = in;
if (hiPassFreq != mHiPassFreq)
{
initFilters(hiPassFreq);
mHiPassFreq = hiPassFreq;
}
if (mHiPassFreq > 0){
filtered = mHiPass2.processSample(mHiPass1.processSample(in));
}
double rectified = abs(filtered);
double dB = 20 * log10(rectified);
double clipped = max(dB, floor);
double fast = mFastSlide.processSample(clipped);
double slow = mSlowSlide.processSample(clipped);
return fast - slow;
}

bool initialized() { return mInitialized; }

private:
void initFilters(double cutoff)
{
mHiPass1.init(cutoff);
mHiPass2.init(cutoff);
}

double mHiPassFreq{0};
bool mInitialized{false};

ButterworthHPFilter mHiPass1;
ButterworthHPFilter mHiPass2;
SlideUDFilter mFastSlide;
SlideUDFilter mSlowSlide;
};
} // namespace algorithm
} // namespace fluid
82 changes: 45 additions & 37 deletions include/algorithms/public/EnvelopeSegmentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ under the European Union’s Horizon 2020 research and innovation programme

#pragma once

#include "Envelope.hpp"
#include "../util/ButterworthHPFilter.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../util/SlideUDFilter.hpp"
Expand All @@ -29,40 +30,46 @@ class EnvelopeSegmentation
public:
void init(double floor, double hiPassFreq)
{
mFastSlide.init(floor);
mSlowSlide.init(floor);
// mFastSlide.init(floor);
// mSlowSlide.init(floor);
mEnvelope.init(floor,hiPassFreq);
mDebounceCount = 1;
initFilters(hiPassFreq);
mHiPassFreq = hiPassFreq;
// initFilters(hiPassFreq);
// mHiPassFreq = hiPassFreq;
mPrevValue = 0;
mState = false;
mInitialized = true;
// mInitialized = true;
}

double processSample(const double in, double onThreshold, double offThreshold,
double floor, index fastRampUpTime, index slowRampUpTime,
index fastRampDownTime, index slowRampDownTime,
double hiPassFreq, index debounce)
{
using namespace std;
assert(mInitialized);
mFastSlide.updateCoeffs(fastRampUpTime, fastRampDownTime);
mSlowSlide.updateCoeffs(slowRampUpTime, slowRampDownTime);
double filtered = in;
if (hiPassFreq != mHiPassFreq)
{
initFilters(hiPassFreq);
mHiPassFreq = hiPassFreq;
}
if (mHiPassFreq > 0){
filtered = mHiPass2.processSample(mHiPass1.processSample(in));
}
double rectified = abs(filtered);
double dB = 20 * log10(rectified);
double clipped = max(dB, floor);
double fast = mFastSlide.processSample(clipped);
double slow = mSlowSlide.processSample(clipped);
double value = fast - slow;
// using namespace std;
// assert(mInitialized);
// mFastSlide.updateCoeffs(fastRampUpTime, fastRampDownTime);
// mSlowSlide.updateCoeffs(slowRampUpTime, slowRampDownTime);
// double filtered = in;
// if (hiPassFreq != mHiPassFreq)
// {
// initFilters(hiPassFreq);
// mHiPassFreq = hiPassFreq;
// }
// if (mHiPassFreq > 0){
// filtered = mHiPass2.processSample(mHiPass1.processSample(in));
// }
// double rectified = abs(filtered);
// double dB = 20 * log10(rectified);
// double clipped = max(dB, floor);
// double fast = mFastSlide.processSample(clipped);
// double slow = mSlowSlide.processSample(clipped);
// double value = fast - slow;


double value =
mEnvelope.processSample(in, floor, fastRampUpTime, slowRampUpTime,
fastRampDownTime, slowRampUpTime, hiPassFreq);
double detected = 0;

if (!mState && value > onThreshold && mPrevValue < onThreshold &&
Expand All @@ -81,25 +88,26 @@ class EnvelopeSegmentation
return detected;
}

bool initialized() { return mInitialized; }
bool initialized() { return mEnvelope.initialized(); }

private:
void initFilters(double cutoff)
{
mHiPass1.init(cutoff);
mHiPass2.init(cutoff);
}

double mHiPassFreq{0};
// void initFilters(double cutoff)
// {
// mHiPass1.init(cutoff);
// mHiPass2.init(cutoff);
// }

Envelope mEnvelope;
// double mHiPassFreq{0};
index mDebounceCount{1};
double mPrevValue{0};
bool mInitialized{false};
// bool mInitialized{false};
bool mState{false};

ButterworthHPFilter mHiPass1;
ButterworthHPFilter mHiPass2;
SlideUDFilter mFastSlide;
SlideUDFilter mSlowSlide;
// ButterworthHPFilter mHiPass1;
// ButterworthHPFilter mHiPass2;
// SlideUDFilter mFastSlide;
// SlideUDFilter mSlowSlide;
};
} // namespace algorithm
} // namespace fluid
62 changes: 62 additions & 0 deletions include/algorithms/public/NoveltyFeature.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Part of the Fluid Corpus Manipulation Project (http://www.flucoma.org/)
Copyright 2017-2019 University of Huddersfield.
Licensed under the BSD-3 License.
See license.md file in the project root for full license information.
This project has received funding from the European Research Council (ERC)
under the European Union’s Horizon 2020 research and innovation programme
(grant agreement No 725899).
*/

#pragma once

#include "../util/FluidEigenMappings.hpp"
#include "../util/Novelty.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/TensorTypes.hpp"
#include <Eigen/Core>

namespace fluid {
namespace algorithm {

class NoveltyFeature
{

public:
using ArrayXd = Eigen::ArrayXd;

NoveltyFeature(index maxKernelSize, index maxFilterSize)
: mFilterBufferStorage(maxFilterSize), mNovelty(maxKernelSize)
{}

void init(index kernelSize, index filterSize, index nDims)
{
assert(kernelSize % 2);
mNovelty.init(kernelSize, nDims);
mFilterBuffer = mFilterBufferStorage.segment(0, filterSize);
mFilterBuffer.setZero();
}

double processFrame(const RealVectorView input)
{
double novelty = mNovelty.processFrame(_impl::asEigen<Eigen::Array>(input));
index filterSize = mFilterBuffer.size();

if (filterSize > 1)
{
mFilterBuffer.segment(0, filterSize - 1) =
mFilterBuffer.segment(1, filterSize - 1);
}

mFilterBuffer(filterSize - 1) = novelty;

return mFilterBuffer.mean();
}

private:
ArrayXd mFilterBuffer;
ArrayXd mFilterBufferStorage;
Novelty mNovelty;
};
} // namespace algorithm
} // namespace fluid
29 changes: 9 additions & 20 deletions include/algorithms/public/NoveltySegmentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ under the European Union’s Horizon 2020 research and innovation programme

#pragma once

#include "NoveltyFeature.hpp"
#include "../util/FluidEigenMappings.hpp"
#include "../util/Novelty.hpp"
#include "../../data/FluidIndex.hpp"
#include "../../data/TensorTypes.hpp"
#include <Eigen/Core>
Expand All @@ -26,32 +26,23 @@ class NoveltySegmentation
using ArrayXd = Eigen::ArrayXd;

NoveltySegmentation(index maxKernelSize, index maxFilterSize)
: mFilterBufferStorage(maxFilterSize), mNovelty(maxKernelSize)
: mNovelty(maxFilterSize, maxKernelSize)
{}

void init(index kernelSize, index filterSize, index nDims)
{
assert(kernelSize % 2);
mNovelty.init(kernelSize, nDims);
mFilterBuffer = mFilterBufferStorage.segment(0, filterSize);
mFilterBuffer.setZero();
mNovelty.init(kernelSize, filterSize, nDims);
mDebounceCount = 1;
}

double processFrame(const RealVectorView input, double threshold,
index minSliceLength)
{
double novelty = mNovelty.processFrame(_impl::asEigen<Eigen::Array>(input));
double detected = 0.;
index filterSize = mFilterBuffer.size();
if (filterSize > 1)
{
mFilterBuffer.segment(0, filterSize - 1) =
mFilterBuffer.segment(1, filterSize - 1);
}

mPeakBuffer.segment(0, 2) = mPeakBuffer.segment(1, 2);
mFilterBuffer(filterSize - 1) = novelty;
mPeakBuffer(2) = mFilterBuffer.mean();
mPeakBuffer(2) = mNovelty.processFrame(input);

if (mPeakBuffer(1) > mPeakBuffer(0) && mPeakBuffer(1) > mPeakBuffer(2) &&
mPeakBuffer(1) > threshold && mDebounceCount == 0)
{
Expand All @@ -66,11 +57,9 @@ class NoveltySegmentation
}

private:
ArrayXd mFilterBuffer;
ArrayXd mFilterBufferStorage;
ArrayXd mPeakBuffer{3};
Novelty mNovelty;
index mDebounceCount{1};
NoveltyFeature mNovelty;
ArrayXd mPeakBuffer{3};
index mDebounceCount{1};
};
} // namespace algorithm
} // namespace fluid
Loading