<commit_before>/*
 * Copyright (C) 2006-2016  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "humdetector.h"
#include <algorithm> // sort
#include "essentiamath.h"

using namespace std;

#include "poolstorage.h"

namespace essentia {
namespace streaming {

const char* HumDetector::name = essentia::standard::HumDetector::name;
const char* HumDetector::category = essentia::standard::HumDetector::category;
const char* HumDetector::description = essentia::standard::HumDetector::description;


template< typename T >
typename std::vector<T>::iterator 
   HumDetector::insertSorted( std::vector<T> & vec, T const& item )
{
    return vec.insert
        ( 
            std::upper_bound( vec.begin(), vec.end(), item ),
            item 
        );
}

template <typename T>
vector<size_t> HumDetector::sort_indexes(const vector<T> &v) {

  // initialize original index locations
  vector<size_t> idx(v.size());
  iota(idx.begin(), idx.end(), 0);

  // sort indexes based on comparing values in v
  sort(idx.begin(), idx.end(),
       [&v](size_t i1, size_t i2) {return v[i1] < v[i2];});

  return idx;
}


Real HumDetector::centBinToFrequency(Real cent, Real reff, Real binsInOctave) {
  return pow(2.f, (cent - reff) / binsInOctave);
}


HumDetector::HumDetector() : AlgorithmComposite() {
  AlgorithmFactory& factory = AlgorithmFactory::instance();
  _decimator                = factory.create("Resample");
  _lowPass                  = factory.create("LowPass");
  _frameCutter              = factory.create("FrameCutter");
  _welch                    = factory.create("Welch");
  _Smoothing                = standard::AlgorithmFactory::create("MedianFilter");
  _spectralPeaks            = standard::AlgorithmFactory::create("SpectralPeaks");
  _pitchSalienceFunction    = standard::AlgorithmFactory::create("PitchSalienceFunction");
  _pitchSalienceFunctionPeaks = standard::AlgorithmFactory::create("PitchSalienceFunctionPeaks");
  _pitchContours            = standard::AlgorithmFactory::create("PitchContours");

  declareInput(_signal, 4096, "signal", "the input audio signal");
  declareOutput(_rMatrix, "r", "the quantile ratios matrix");
  declareOutput(_frequencies, "frequencies", "humming tones frequencies");
  declareOutput(_saliences, "saliences", "humming tones saliences");
  declareOutput(_starts, "starts", "humming tones starts");
  declareOutput(_ends, "ends", "humming tones ends");


  // connect input proxy
  _signal >> _decimator->input("signal");

  _decimator->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _decimator->output("signal") >> _lowPass->input("signal");

  _lowPass->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _lowPass->output("signal") >> _frameCutter->input("signal");

  _frameCutter->output("frame") >> _welch->input("frame");


  _welch->output("psd") >> PC(_pool, "psd");

  _network = new scheduler::Network(_decimator);
}

HumDetector::~HumDetector() {
  delete _network;
}


void HumDetector::configure() {

  _outSampleRate = 2000.f;
  _sampleRate = parameter("sampleRate").toReal();
  _hopSize = int(round(parameter("hopSize").toReal() * _outSampleRate));
  uint frameSize = int(round(parameter("frameSize").toReal() * _outSampleRate));
  _frameSize = nextPowerTwo(frameSize);
  _timeWindow = int(round(parameter("timeWindow").toReal() * _outSampleRate / _hopSize));
  _Q0 = parameter("Q0").toReal();
  _Q1 = parameter("Q1").toReal();
  _maximumFrequency = parameter("maximumFrequency").toReal();
  _minDuration = parameter("minimumDuration").toReal() * 1000.f;
  _timeContinuity = parameter("timeContinuity").toReal() * 1000.f;
  _minimumFrequency = parameter("minimumFrequency").toReal();
  _numberHarmonics = parameter("numberHarmonics").toInt();
  _detectionThreshold = parameter("detectionThreshold").toReal();

  _medianFilterSize = _frameSize * 60 / (_outSampleRate);
  _medianFilterSize += (_medianFilterSize + 1) % 2;

  _decimator->configure("inputSampleRate", _sampleRate,
                        "outputSampleRate", _outSampleRate);

  // Resample buffers have to be resized everytime it is configured 
  // as it resets the sizes to the default each time.
  _decimator->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _lowPass->configure("sampleRate",_outSampleRate,
                      "cutoffFrequency", _maximumFrequency);

  _frameCutter->configure("frameSize",frameSize,
                          "hopSize", _hopSize,
                          "silentFrames", "keep");

  _welch->configure("fftSize",_frameSize,
                    "frameSize", frameSize,
                    "averagingFrames", 2,
                    "windowType", "blackmanharris92");

  _spectralPeaks->configure("sampleRate", _outSampleRate,
                            "minFrequency", _minimumFrequency,<commit_msg>HumDetector. Reduce resampler quality This allows the algorithm to run faster.<commit_after>/*
 * Copyright (C) 2006-2016  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "humdetector.h"
#include <algorithm> // sort
#include "essentiamath.h"

using namespace std;

#include "poolstorage.h"

namespace essentia {
namespace streaming {

const char* HumDetector::name = essentia::standard::HumDetector::name;
const char* HumDetector::category = essentia::standard::HumDetector::category;
const char* HumDetector::description = essentia::standard::HumDetector::description;


template< typename T >
typename std::vector<T>::iterator 
   HumDetector::insertSorted( std::vector<T> & vec, T const& item )
{
    return vec.insert
        ( 
            std::upper_bound( vec.begin(), vec.end(), item ),
            item 
        );
}

template <typename T>
vector<size_t> HumDetector::sort_indexes(const vector<T> &v) {

  // initialize original index locations
  vector<size_t> idx(v.size());
  iota(idx.begin(), idx.end(), 0);

  // sort indexes based on comparing values in v
  sort(idx.begin(), idx.end(),
       [&v](size_t i1, size_t i2) {return v[i1] < v[i2];});

  return idx;
}


Real HumDetector::centBinToFrequency(Real cent, Real reff, Real binsInOctave) {
  return pow(2.f, (cent - reff) / binsInOctave);
}


HumDetector::HumDetector() : AlgorithmComposite() {
  AlgorithmFactory& factory = AlgorithmFactory::instance();
  _decimator                = factory.create("Resample");
  _lowPass                  = factory.create("LowPass");
  _frameCutter              = factory.create("FrameCutter");
  _welch                    = factory.create("Welch");
  _Smoothing                = standard::AlgorithmFactory::create("MedianFilter");
  _spectralPeaks            = standard::AlgorithmFactory::create("SpectralPeaks");
  _pitchSalienceFunction    = standard::AlgorithmFactory::create("PitchSalienceFunction");
  _pitchSalienceFunctionPeaks = standard::AlgorithmFactory::create("PitchSalienceFunctionPeaks");
  _pitchContours            = standard::AlgorithmFactory::create("PitchContours");

  declareInput(_signal, 4096, "signal", "the input audio signal");
  declareOutput(_rMatrix, "r", "the quantile ratios matrix");
  declareOutput(_frequencies, "frequencies", "humming tones frequencies");
  declareOutput(_saliences, "saliences", "humming tones saliences");
  declareOutput(_starts, "starts", "humming tones starts");
  declareOutput(_ends, "ends", "humming tones ends");


  // connect input proxy
  _signal >> _decimator->input("signal");

  _decimator->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _decimator->output("signal") >> _lowPass->input("signal");

  _lowPass->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _lowPass->output("signal") >> _frameCutter->input("signal");

  _frameCutter->output("frame") >> _welch->input("frame");


  _welch->output("psd") >> PC(_pool, "psd");

  _network = new scheduler::Network(_decimator);
}

HumDetector::~HumDetector() {
  delete _network;
}


void HumDetector::configure() {

  _outSampleRate = 2000.f;
  _sampleRate = parameter("sampleRate").toReal();
  _hopSize = int(round(parameter("hopSize").toReal() * _outSampleRate));
  uint frameSize = int(round(parameter("frameSize").toReal() * _outSampleRate));
  _frameSize = nextPowerTwo(frameSize);
  _timeWindow = int(round(parameter("timeWindow").toReal() * _outSampleRate / _hopSize));
  _Q0 = parameter("Q0").toReal();
  _Q1 = parameter("Q1").toReal();
  _maximumFrequency = parameter("maximumFrequency").toReal();
  _minDuration = parameter("minimumDuration").toReal() * 1000.f;
  _timeContinuity = parameter("timeContinuity").toReal() * 1000.f;
  _minimumFrequency = parameter("minimumFrequency").toReal();
  _numberHarmonics = parameter("numberHarmonics").toInt();
  _detectionThreshold = parameter("detectionThreshold").toReal();

  _medianFilterSize = _frameSize * 60 / (_outSampleRate);
  _medianFilterSize += (_medianFilterSize + 1) % 2;

  _decimator->configure("inputSampleRate", _sampleRate,
                        "outputSampleRate", _outSampleRate,
                        "quality", 2);

  // Resample buffers have to be resized everytime it is configured 
  // as it resets the sizes to the default each time.
  _decimator->output("signal").setBufferType(BufferUsage::forLargeAudioStream);

  _lowPass->configure("sampleRate",_outSampleRate,
                      "cutoffFrequency", _maximumFrequency);

  _frameCutter->configure("frameSize",frameSize,
                          "hopSize", _hopSize,
                          "silentFrames", "keep");

  _welch->configure("fftSize",_frameSize,
                    "frameSize", frameSize,
                    "averagingFrames", 2,
                    "windowType", "blackmanharris92");

  _spectralPeaks->configure("sampleRate", _outSampleRate,
                            "minFrequency", _minimumFrequency,
{'fraction_non_alphanumeric': 0.12922802320392682, 'fraction_numerical': 0.007764390896921017, 'mean_word_length': 4.138010087116002, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1205658', 'n_tokens_mistral': 3437, 'n_tokens_neox': 3193, 'n_words': 769}