Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
198 lines (151 sloc) 7.89 KB
/*
* 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 "FreesoundSfxDescriptors.h"
using namespace std;
using namespace essentia;
using namespace essentia::streaming;
using namespace std;
const string FreesoundSfxDescriptors::nameSpace="sfx.";
// TODO: normalization of centroids requires array size or duration,
// not directly available in streaming mode.
// Can be done at the client for the moment
void FreesoundSfxDescriptors::createNetwork(SourceBase& source, Pool& pool) {
AlgorithmFactory& factory = AlgorithmFactory::instance();
// Envelope
Algorithm* envelope = factory.create("Envelope");
source >> envelope->input("signal");
// Temporal Statistics
Algorithm* decrease = factory.create("Decrease");
Algorithm* accu = factory.create("RealAccumulator");
envelope->output("signal") >> accu->input("data");
accu->output("array") >> decrease->input("array");
decrease->output("decrease") >> PC(pool, nameSpace + "temporal_decrease");
// Audio Central Moments Statistics
Algorithm* cm = factory.create("CentralMoments");
Algorithm* ds = factory.create("DistributionShape");
accu->output("array") >> cm->input("array");
cm->output("centralMoments") >> ds->input("centralMoments");
ds->output("kurtosis") >> PC(pool, nameSpace + "temporal_kurtosis");
ds->output("spread") >> PC(pool, nameSpace + "temporal_spread");
ds->output("skewness") >> PC(pool, nameSpace + "temporal_skewness");
// Temporal Centroid
Algorithm* centroid = factory.create("Centroid");
accu->output("array") >> centroid->input("array");
centroid->output("centroid") >> PC(pool, nameSpace + "temporal_centroid");
// Duration
Algorithm* duration = factory.create("Duration");
source >> duration->input("signal");
duration->output("duration") >> PC(pool, nameSpace + "duration");
// Effective Duration
Algorithm* effective_duration = factory.create("EffectiveDuration","thresholdRatio",0.1);
accu->output("array") >> effective_duration->input("signal");
effective_duration->output("effectiveDuration") >> PC(pool, nameSpace + "effective_duration");
// Log Attack Time
Algorithm* log = factory.create("LogAttackTime");
accu->output("array") >> log->input("signal");
log->output("logAttackTime") >> PC(pool, nameSpace + "logattacktime");
log->output("attackStart") >> NOWHERE;
log->output("attackStop") >> NOWHERE;
// Strong Decay
Algorithm* decay = factory.create("StrongDecay");
envelope->output("signal") >> decay->input("signal");
decay->output("strongDecay") >> PC(pool, nameSpace + "strongdecay");
// Flatness
Algorithm* flatness = factory.create("FlatnessSFX");
accu->output("array") >> flatness->input("envelope");
flatness->output("flatness") >> PC(pool, nameSpace + "flatness");
// Morphological Descriptors
Algorithm* max1 = factory.create("MaxToTotal");
envelope->output("signal") >> max1->input("envelope");
max1->output("maxToTotal") >> PC(pool, nameSpace + "max_to_total");
Algorithm* tc = factory.create("TCToTotal");
envelope->output("signal") >> tc->input("envelope");
tc->output("TCToTotal") >> PC(pool, nameSpace + "tc_to_total");
Algorithm* der = factory.create("DerivativeSFX");
accu->output("array") >> der->input("envelope");
der->output("derAvAfterMax") >> PC(pool, nameSpace + "der_av_after_max");
der->output("maxDerBeforeMax") >> PC(pool, nameSpace + "max_der_before_max");
}
void FreesoundSfxDescriptors::createPitchNetwork(VectorInput<Real>& pitch, Pool& pool) {
AlgorithmFactory& factory = AlgorithmFactory::instance();
Algorithm* maxtt = factory.create("MaxToTotal");
pitch >> maxtt->input("envelope"); // TODO: should we use Envelope?
maxtt->output("maxToTotal") >> PC(pool, nameSpace + "pitch_max_to_total");
Algorithm* mintt = factory.create("MinToTotal");
pitch >> mintt->input("envelope"); // TODO: should we use Envelope?
mintt->output("minToTotal") >> PC(pool, nameSpace + "pitch_min_to_total");
Algorithm* accu = factory.create("RealAccumulator");
pitch >> accu->input("data");
Algorithm* pc = factory.create("Centroid");
accu->output("array") >> pc->input("array");
pc->output("centroid") >> PC(pool, nameSpace + "pitch_centroid");
Algorithm* amt = factory.create("AfterMaxToBeforeMaxEnergyRatio");
pitch >> amt->input("pitch");
amt->output("afterMaxToBeforeMaxEnergyRatio") >> PC(pool, nameSpace + "pitch_after_max_to_before_max_energy_ratio");
}
void FreesoundSfxDescriptors::createHarmonicityNetwork(SourceBase& source, Pool& pool){
AlgorithmFactory& factory = AlgorithmFactory::instance();
// using the same parameters as for other low-level descriptors
//Real sampleRate = options.value<Real>("analysisSampleRate");
int frameSize = int(options.value<Real>("lowlevel.frameSize"));
int hopSize = int(options.value<Real>("lowlevel.hopSize"));
int zeroPadding = int(options.value<Real>("lowlevel.zeroPadding"));
string silentFrames = options.value<string>("lowlevel.silentFrames");
string windowType = options.value<string>("lowlevel.windowType");
// FrameCutter
Algorithm* fc = factory.create("FrameCutter",
"frameSize", frameSize,
"hopSize", hopSize,
"silentFrames", silentFrames);
source >> fc->input("signal");
// Windowing
Algorithm* w = factory.create("Windowing",
"type", windowType,
"zeroPadding", zeroPadding);
fc->output("frame") >> w->input("frame");
// Spectrum
Algorithm* spec = factory.create("Spectrum");
w->output("frame") >> spec->input("frame");
Algorithm* harmPeaks = factory.create("HarmonicPeaks");
Algorithm* peaks = factory.create("SpectralPeaks",
"orderBy", "frequency","minFrequency", 20);
spec->output("spectrum") >> peaks->input("spectrum");
// Pitch Detection
Algorithm* pitch = factory.create("PitchYinFFT",
"frameSize", frameSize);
spec->output("spectrum") >> pitch->input("spectrum");
pitch->output("pitchConfidence") >> NOWHERE;
peaks->output("frequencies") >> harmPeaks->input("frequencies");
peaks->output("magnitudes") >> harmPeaks->input("magnitudes");
pitch->output("pitch") >> harmPeaks->input("pitch");
Algorithm* odd2even = factory.create("OddToEvenHarmonicEnergyRatio");
Algorithm* tristimulus = factory.create("Tristimulus");
Algorithm* inharmonicity = factory.create("Inharmonicity");
// inputs
harmPeaks->output("harmonicFrequencies") >> tristimulus->input("frequencies");
harmPeaks->output("harmonicMagnitudes") >> tristimulus->input("magnitudes");
harmPeaks->output("harmonicFrequencies") >> odd2even->input("frequencies");
harmPeaks->output("harmonicMagnitudes") >> odd2even->input("magnitudes");
harmPeaks->output("harmonicFrequencies") >> inharmonicity->input("frequencies");
harmPeaks->output("harmonicMagnitudes") >> inharmonicity->input("magnitudes");
// outputs
inharmonicity->output("inharmonicity") >> PC(pool, nameSpace + "inharmonicity");
odd2even->output("oddToEvenHarmonicEnergyRatio") >> PC(pool, nameSpace + "oddtoevenharmonicenergyratio");
tristimulus->output("tristimulus") >> PC(pool, nameSpace + "tristimulus");
}
You can’t perform that action at this time.