44 if (isThreadRunning())
46 signalThreadShouldExit();
49 if (!isTimerRunning())
94 if (threadShouldExit())
105 AudioBuffer<float>* buffer =
dynamic_cast<AudioBuffer<float>*
>(
this);
108 AudioBuffer<float> mono;
109 mono.setSize(1, getNumSamples());
110 mono.copyFrom(0, 0, *buffer, 0, 0, getNumSamples());
111 if (buffer->getNumChannels() == 2)
113 mono.addFrom(0, 0, *buffer, 1, 0, getNumSamples());
114 mono.applyGain(0, getNumSamples(), 0.5f);
116 float* start = mono.getWritePointer(0);
117 int size = mono.getNumSamples();
119 std::vector<float> bufferVector(start, start +
size);
125 std::vector<float> signalBufferMono)
130 std::vector<std::vector<float>> timeDomainSlices;
132 for (
int i = 0; i < onsetPositions.size(); i++)
134 startSample = onsetPositions.at(i);
135 if (i < onsetPositions.size() - 1)
136 finishSample = onsetPositions.at(i + 1) - 1;
138 finishSample =
static_cast<int>(signalBufferMono.size());
140 std::vector<float> subVector(signalBufferMono.begin() + startSample,
141 signalBufferMono.begin() + finishSample);
142 timeDomainSlices.push_back(subVector);
145 return timeDomainSlices;
149 std::vector<float> bufferVector,
150 std::size_t window_length)
153 std::vector<std::vector<float>> timeDomainSlices;
154 const auto N = bufferVector.size();
155 for (
auto onset : onsetPositions)
157 const auto start_sample = onset;
158 const auto end_sample = std::min(start_sample + window_length,
161 std::vector<float> clip(bufferVector.begin() + start_sample, bufferVector.begin() + end_sample);
162 timeDomainSlices.push_back(clip);
164 return timeDomainSlices;
168 std::size_t hop_length)
170 std::vector<int> onsets;
171 if (bufferVector.size() > window_length)
173 for (
size_t i = 0; i < bufferVector.size() - window_length; i += hop_length)
175 onsets.push_back(
static_cast<int>(i));
193 auto envFollower = std::make_unique<EnvelopeFollowerSPD>(samplerate);
195 auto slopeGenerator = std::make_unique<SlopeGenerator>();
197 auto onsetDetector = std::make_unique<OnsetDetector>(samplerate);
208 std::vector<float> signalEnvelope = envFollower.get()->filterVector(bufferVector);
209 std::vector<float> normalisedEnvelope = envFollower.get()->normaliseEnvelope(signalEnvelope);
212 auto slopeVector = slopeGenerator.get()->createSlopeVectorFromEnvelope(normalisedEnvelope);
215 auto onsetPositions = onsetDetector.get()->calculateOnsetsGlobal(slopeVector, normalisedEnvelope);
218 if (onsetPositions.empty())
220 onsetPositions.push_back(0);
222 return onsetPositions;
228 auto filterBank = std::make_unique<MusicScaleFilterBank>(sampleRate);
230 const int analysisFrameSize{2048};
231 const int hopSize = 221;
233 auto m_stft = std::make_unique<ShortTimeFourierTransform>(
238 AudioBuffer<float>* buffer =
dynamic_cast<AudioBuffer<float>*
>(
this);
240 auto spectralFrames = m_stft.get()->stft(*buffer);
243 auto filteredSpec = filterBank.get()->filterSpectrum(spectralFrames);
246 auto onsetDetector = std::make_unique<SuperFluxOnsetDetection>(filteredSpec, sampleRate, hopSize);
249 onsetDetector.get()->setParametersMS(
258 auto onsetPositions = onsetDetector.get()->findOnsetsInSamples();
260 return onsetPositions;
264 const std::vector<std::vector<float>>& timeDomainSlices,
const std::vector<int>& onsetPositions)
268 std::vector<AudioDescriptor> descriptorsTime;
270 for (
int i = 0; i < onsetPositions.size(); i++)
273 grainDescription.
audioIndex = onsetPositions.at(i);
277 static_cast<float>(timeDomainSlices.at(i).
size());
279 descriptorsTime.push_back(grainDescription);
281 return descriptorsTime;
285 std::vector<std::vector<float>>& timeDomainSlices,
const std::vector<int>& onsetPositions)
288 const int analysisFrameSize{2048};
289 const int hopSize{1024};
291 auto m_stft = std::make_unique<ShortTimeFourierTransform>(
296 auto freqAnalysisFramework = std::make_unique<FrequencyDomainAnalysisFramework>(
299 const auto n_features = freqAnalysisFramework.get()->getNumberOfMelFrequencyCepstralCoefficients();
300 std::vector<std::vector<float>> features;
301 std::vector<float> mfcc(n_features, 0.0f);
303 for (
int i = 0; i < onsetPositions.size(); i++)
305 float* dataPtrs[1] = {timeDomainSlices.at(i).data()};
306 AudioBuffer<float> bufferSlice(dataPtrs, 1,
static_cast<int>(timeDomainSlices.at(i).size()));
307 auto spectralFrames = m_stft.get()->stft(bufferSlice);
309 for (
int j = 0; j < spectralFrames.size(); j++)
312 freqAnalysisFramework->setSpectralFrame(spectralFrames.at(j));
315 std::vector<float> mfccTemp = freqAnalysisFramework->getMFCC();
317 transform(mfcc.begin(), mfcc.end(), mfccTemp.begin(), mfcc.begin(), std::plus<float>());
321 transform(mfcc.begin(), mfcc.end(), mfcc.begin(),
322 [=](
float j) { return (j / static_cast<float>(spectralFrames.size())); });
323 features.push_back(mfcc);
325 fill(mfcc.begin(), mfcc.end(), 0.0f);
331 std::vector<std::vector<float>>& timeDomainSlices)
333 std::vector<std::vector<float>> features;
335 for (
const auto& segment : timeDomainSlices)
338 float temporal_centroid = 0.f;
340 for (
size_t i = 0; i < segment.size(); ++i)
342 const auto value = (segment[i] * segment[i]);
343 temporal_centroid += (i * value);
346 const auto level = 10.f * log10(std::max(ss / segment.size(), 1e-6f));
347 temporal_centroid /= std::max(ss, 1e-5f);
348 features.emplace_back(std::initializer_list<float>{temporal_centroid, level, 1.f, level});
354 std::vector<std::vector<float>>& timeDomainSlices)
356 std::vector<std::vector<float>> features;
358 const int analysisFrameSize{2048};
359 const int hopSize{1024};
362 auto m_stft = std::make_unique<ShortTimeFourierTransform>(
367 auto timeAnalysisFramework = std::make_unique<TimeDomainAnalysisFramework>(
371 auto freqAnalysisFramework = std::make_unique<FrequencyDomainAnalysisFramework>(
373 freqAnalysisFramework.get()->setFrequencyVector(
376 for (
const auto& segment : timeDomainSlices)
381 timeAnalysisFramework->setSignalFrame(segment);
383 float RMS = timeAnalysisFramework->getRMS();
388 AudioSampleBuffer segmentBuffer(1,
static_cast<int>(segment.size()));
389 segmentBuffer.copyFrom(0, 0, segment.data(),
static_cast<int>(segment.size()));
390 auto spectralFrames = m_stft.get()->stft(segmentBuffer);
392 float centroid = 0.0f;
394 for (
const auto& spectralSegment : spectralFrames)
397 freqAnalysisFramework->setSpectralFrame(spectralSegment);
400 centroid += freqAnalysisFramework->getSpectralCentroid();
404 float avgCentroid = centroid / spectralFrames.size();
406 features.emplace_back(std::initializer_list<float>{avgCentroid, RMS, 1.f, 1.f});
408 segmentBuffer.clear();
415 std::vector<std::vector<float>>& timeDomainSlices)
417 std::vector<std::vector<float>> features;
419 const int analysisFrameSize{2048};
420 const int hopSize{1024};
423 auto m_stft = std::make_unique<ShortTimeFourierTransform>(
428 auto timeAnalysisFramework = std::make_unique<TimeDomainAnalysisFramework>(
432 auto freqAnalysisFramework = std::make_unique<FrequencyDomainAnalysisFramework>(
434 freqAnalysisFramework.get()->setFrequencyVector(
437 for (
const auto& segment : timeDomainSlices)
442 timeAnalysisFramework->setSignalFrame(segment);
444 float RMS = timeAnalysisFramework->getRMS();
449 AudioSampleBuffer segmentBuffer(1,
static_cast<int>(segment.size()));
450 segmentBuffer.copyFrom(0, 0, segment.data(),
static_cast<int>(segment.size()));
451 auto spectralFrames = m_stft.get()->stft(segmentBuffer);
453 float centroid = 0.0f;
455 for (
const auto& spectralSegment : spectralFrames)
458 freqAnalysisFramework->setSpectralFrame(spectralSegment);
461 centroid += freqAnalysisFramework->getSpectralFlatness();
465 float avgCentroid = centroid / spectralFrames.size();
467 features.emplace_back(std::initializer_list<float>{avgCentroid, RMS, 1.f, 1.f});
469 segmentBuffer.clear();
476 std::vector<std::vector<float>>& timeDomainSlices)
478 std::vector<std::vector<float>> features;
480 const int analysisFrameSize{2048};
483 std::unique_ptr<ERB_FFTSpectrogram> m_erb = std::make_unique<ERB_FFTSpectrogram>();
487 auto timeAnalysisFramework = std::make_unique<TimeDomainAnalysisFramework>(
491 auto freqAnalysisFramework = std::make_unique<FrequencyDomainAnalysisFramework>(
493 freqAnalysisFramework.get()->setFrequencyVector(m_erb.get()->getERBSpace());
495 for (
auto& segment : timeDomainSlices)
500 timeAnalysisFramework->setSignalFrame(segment);
502 float RMS = timeAnalysisFramework->getRMS();
507 auto erbFrames = m_erb.get()->filterSpectrum(segment);
509 float centroid = 0.0f;
511 for (
const auto& spectralSegment : erbFrames)
514 freqAnalysisFramework->setSpectralFrame(spectralSegment);
517 centroid += freqAnalysisFramework->getSpectralCentroid();
521 float avgCentroid = centroid / erbFrames.size();
523 features.emplace_back(std::initializer_list<float>{avgCentroid, RMS, 1.f, 1.f});
530 std::vector<std::vector<float>>& timeDomainSlices)
532 std::vector<std::vector<float>> features;
534 const int analysisFrameSize{2048};
537 std::unique_ptr<ERB_FFTSpectrogram> m_erb = std::make_unique<ERB_FFTSpectrogram>();
541 auto freqAnalysisFramework = std::make_unique<FrequencyDomainAnalysisFramework>(
543 freqAnalysisFramework.get()->setFrequencyVector(m_erb.get()->getERBSpace());
545 for (
auto& segment : timeDomainSlices)
550 auto erbFrames = m_erb.get()->filterSpectrum(segment);
552 float centroid = 0.0f;
553 float flatness = 0.0f;
555 for (
const auto& spectralSegment : erbFrames)
558 freqAnalysisFramework->setSpectralFrame(spectralSegment);
563 centroid += freqAnalysisFramework->getSpectralCentroid();
566 flatness += freqAnalysisFramework->getSpectralFlatness();
570 float avgCentroid = centroid / erbFrames.size();
573 float avgFlatness = flatness / erbFrames.size();
576 features.emplace_back(std::initializer_list<float>{avgCentroid, avgFlatness, 1.f, 1.f});
583 std::vector<std::vector<float>>& timeDomainSlices)
585 std::vector<std::vector<float>> features;
587 for (
const auto& segment : timeDomainSlices)
591 auto timeAnalysisFramework = std::make_unique<TimeDomainAnalysisFramework>(
596 timeAnalysisFramework->setSignalFrame(segment);
598 float RMS = timeAnalysisFramework->getRMS();
600 float pitch = timeAnalysisFramework->getPitchAutocorrelation();
602 float peakEnergy = timeAnalysisFramework->getPeakEnergy();
605 features.emplace_back(std::initializer_list<float>{pitch, peakEnergy, RMS, 1.f});
607 timeAnalysisFramework.release();
614 std::vector<std::vector<float>>& timeDomainSlices)
636 for (
auto& timeSlice : timeDomainSlices)
638 auto harmonicPair = harmonicRep->processSignal(timeSlice);
642 return timeDomainSlices;
648 for (
const auto& feature : features)
654 for (
size_t i = 0; i < features.size(); ++i)
661 std::vector<AudioDescriptor>& descriptorsTime)
664 for (
const auto& feature : features)
666 descriptorsTime.at(i).principalX = feature.at(0);
667 descriptorsTime.at(i).principalY = feature.at(1);
668 descriptorsTime.at(i).principalZ = feature.at(2);
669 descriptorsTime.at(i).principalQ = feature.at(3);
680 std::sort(descriptorsTime.begin(), descriptorsTime.end(),
686 m_nnSearch = std::make_unique<krotos::KDTree>();
687 for (
auto& grain : descriptorsTime)
689 m_nnSearch->addDatasetItem(grain.principalX, grain.principalY);
696 m_nnSearch = std::make_unique<krotos::KDTree>();
697 for (
auto& grain : descriptorsTime)
699 m_nnSearch->addDatasetItem(grain.principalX, grain.principalY, grain.principalZ);
712 if (descriptorsTime.size() > 0)
739 if (threadShouldExit())
742 if (this->
size() <= 4)
757 if (threadShouldExit())
774 int analysisFrameSize =
static_cast<int>(powf(2.0f, exponent)) * 512;
776 if (hopFactor <= 0.1f)
779 int hopSizeSamples =
static_cast<int>(
static_cast<float>(analysisFrameSize) * hopFactor);
792 const auto hop_length = window_length / 2;
809 if (threadShouldExit())
813 std::vector<std::vector<float>> features;
864 if (threadShouldExit())
870 if (threadShouldExit())
875 if (threadShouldExit())
906 const auto retval = result - 1;
930 const auto retval = result - 1;
956 auto grain = size_t(grainPhase);
957 double phase = grainPhase - double(grain);
965 auto grain = size_t(grainPhase);
966 double phase = grainPhase -
static_cast<double>(grain);
967 auto nextGrain = grain + 1;
ProgressTracker & getProgressTracker()
Get a reference to this buffer's ProgressTracker.
Definition KrotosAudioBufferDSP.cpp:24
void run() override
Definition KrotosAudioBufferDSP.cpp:71
ProgressTracker m_progressTracker
Definition KrotosAudioBufferDSP.h:562
void timerCallback() override
Definition KrotosAudioBufferDSP.cpp:26
std::vector< std::vector< float > > erbSpecCentroidRMS_FeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:475
std::vector< int > chunk(const std::vector< float > &bufferVector, std::size_t window_length, std::size_t hop_length)
Definition KrotosAudioBufferDSP.cpp:167
std::vector< std::vector< float > > mfccFeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices, const std::vector< int > &onsetPositions)
Definition KrotosAudioBufferDSP.cpp:284
std::unique_ptr< PCA > m_principalComponentAnalysis
Definition KrotosAudioBufferDSP.h:581
const int ANALYSIS_TIMER_PERIOD
Definition KrotosAudioBufferDSP.h:509
std::unique_ptr< KDTree > m_nnSearch
Definition KrotosAudioBufferDSP.h:579
std::vector< int > m_onsetPositions
Definition KrotosAudioBufferDSP.h:590
AnalysisScheme getAnalysisScheme()
Definition KrotosAudioBufferDSP.h:500
SegmentationMethod m_segmentationMethod
Definition KrotosAudioBufferDSP.h:556
bool analysisResultsAreValid()
Definition KrotosAudioBufferDSP.h:422
std::vector< std::vector< float > > pitchPeakRMSFeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:582
double getFrequencyFromGrainPhase(double grainPhase)
Definition KrotosAudioBufferDSP.cpp:963
void setFeaturesAndNormalise(const std::vector< std::vector< float > > &features, std::vector< AudioDescriptor > &descriptorsTime)
Definition KrotosAudioBufferDSP.cpp:660
void generalScheme()
Definition KrotosAudioBufferDSP.cpp:737
std::vector< std::vector< float > > erbSpecCentroidFlatness_FeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:529
AnalysisCoefficients & getAnalysisCoefficients()
Definition KrotosAudioBufferDSP.cpp:979
std::vector< AudioDescriptor > m_descriptorsTime
Definition KrotosAudioBufferDSP.h:591
std::vector< int > envelopeOnsetDetection(const std::vector< float > &bufferVector, float samplerate)
Definition KrotosAudioBufferDSP.cpp:188
std::vector< AudioDescriptor > getDescriptorsTime(const std::vector< std::vector< float > > &timeDomainSlices, const std::vector< int > &onsetPositions)
Definition KrotosAudioBufferDSP.cpp:263
void validate()
Definition KrotosAudioBufferDSP.h:416
volatile std::atomic< bool > m_requestDisplayCacheRegeneration
Definition KrotosAudioBufferDSP.h:569
void buildKNNIndex(const std::vector< AudioDescriptor > &descriptorsTime)
Definition KrotosAudioBufferDSP.cpp:684
std::vector< std::vector< float > > specCntrRMS_FeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:353
std::vector< std::vector< float > > m_timeDomainSlices
Definition KrotosAudioBufferDSP.h:589
void analyse()
analyse Analyses the audio waveform stored in the buffer according to the selected scheme This method...
Definition KrotosAudioBufferDSP.cpp:35
void invalidate()
Definition KrotosAudioBufferDSP.h:414
bool shouldRegenerateDisplayCache()
Definition KrotosAudioBufferDSP.cpp:28
AudioDescriptor & audioIndexToDescriptor(int audioIndex)
Definition KrotosAudioBufferDSP.cpp:895
std::vector< int > superFluxOnsetDetection(float samplerate)
Definition KrotosAudioBufferDSP.cpp:225
int size()
Definition KrotosAudioBufferDSP.h:394
std::vector< AudioDescriptor > m_grainDescriptionByFrequency
Definition KrotosAudioBufferDSP.h:572
KrotosAudioBufferDSP()
Definition KrotosAudioBufferDSP.cpp:18
std::vector< std::vector< float > > specFlatnessRMS_FeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:414
std::vector< std::vector< float > > temporalFeatureExtraction(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:330
@ Harmonic_PitchEstimation
@ ERBSpCentroid_ERBSpFlatness
void buildKNNIndexWithZ(const std::vector< AudioDescriptor > &descriptorsTime)
Definition KrotosAudioBufferDSP.cpp:694
AnalysisCoefficients m_AnalysisCoefficients
Definition KrotosAudioBufferDSP.h:560
void cleanupAnalysis()
Definition KrotosAudioBufferDSP.cpp:721
std::vector< AudioDescriptor > m_grainDescriptionByTime
Definition KrotosAudioBufferDSP.h:575
AudioDescriptor & audioFrequencyToDescriptor(float frequency)
Definition KrotosAudioBufferDSP.cpp:919
StereoSample getSampleFromGrainPhase(double grainPhase)
Definition KrotosAudioBufferDSP.cpp:949
AudioDescriptor & audioPercentToDescriptor(float audioPercent)
Definition KrotosAudioBufferDSP.cpp:974
std::vector< std::vector< float > > segmentChunks(std::vector< int > onsetPositions, std::vector< float > signalBufferMono, std::size_t window_length)
Definition KrotosAudioBufferDSP.cpp:148
void applyPCA(std::vector< std::vector< float > > &features, const std::size_t &n_components)
Definition KrotosAudioBufferDSP.cpp:645
FeatureExtrMethod m_featureMethod
Definition KrotosAudioBufferDSP.h:557
std::vector< std::vector< float > > harmonicPitchEstimation(std::vector< std::vector< float > > &timeDomainSlices)
Definition KrotosAudioBufferDSP.cpp:613
void clampGrainDescriptionByTimeIndex(size_t &index)
Definition KrotosAudioBufferDSP.cpp:943
std::vector< float > averageBufferToMono()
Definition KrotosAudioBufferDSP.cpp:102
std::vector< std::vector< float > > segmentOnsetSlices(std::vector< int > onsetPositions, std::vector< float > signalBufferMono)
Definition KrotosAudioBufferDSP.cpp:124
void analysePhase()
Definition KrotosAudioBufferDSPPhaseDetection.cpp:298
void sortByZ(const std::vector< AudioDescriptor > &descriptorsTime)
Definition KrotosAudioBufferDSP.cpp:704
std::vector< AudioDescriptor > m_grainDescriptionByZ
Definition KrotosAudioBufferDSP.h:577
float getSourceSampleRate(void)
Definition KrotosAudioBuffer.cpp:510
StereoSample getInterpolatedSample(double index)
Get a stereo sample from the audio buffer.
Definition KrotosAudioBuffer.cpp:318
ProgressTracker - a class to help with display of a progresas bar during audio analysis.
Definition KrotosAudioBufferDSP.h:64
void setNumStages(int numStages)
Definition KrotosAudioBufferDSP.h:73
void end(String finalMessage)
Definition KrotosAudioBufferDSP.h:91
void stage(String message)
Definition KrotosAudioBufferDSP.h:83
Definition KrotosAudioBuffer.h:16
Definition AirAbsorptionFilter.cpp:2
void normaliseAudioDescriptorFeature(std::vector< AudioDescriptor > &decriptors, Functor functor, float border=0.f)
Normalise a chosen field within a vector of AudioDescriptors.
Definition KrotosAudioBufferDSP.h:197
static bool compareByAudioIndex(const AudioDescriptor &a, const AudioDescriptor &b)
Definition KrotosAudioBufferDSP.cpp:885
void normaliseAndInvertAudioDescriptorFeature(std::vector< AudioDescriptor > &decriptors, Functor2 functor, float border=0.f)
Normalise then invert a chosen field within a vector of AudioDescriptors.
Definition KrotosAudioBufferDSP.h:240
static bool compareByAudioFrequency(const AudioDescriptor &a, const AudioDescriptor &b)
Definition KrotosAudioBufferDSP.cpp:890
AnalysisCoefficients - A class containing attributes used during analysis of audio.
Definition KrotosAudioBufferDSP.h:42
float coeff0
Definition KrotosAudioBufferDSP.h:43
float coeff1
Definition KrotosAudioBufferDSP.h:44
float coeff7
Definition KrotosAudioBufferDSP.h:50
float coeff3
Definition KrotosAudioBufferDSP.h:46
float coeff2
Definition KrotosAudioBufferDSP.h:45
float coeff4
Definition KrotosAudioBufferDSP.h:47
A class to contains any attributes we want to store for the described audio.
Definition KrotosAudioBufferDSP.h:177
float principalQ
Definition KrotosAudioBufferDSP.h:186
float principalZ
Definition KrotosAudioBufferDSP.h:185
int audioIndex
Definition KrotosAudioBufferDSP.h:180
float principalX
Definition KrotosAudioBufferDSP.h:183
float principalY
Definition KrotosAudioBufferDSP.h:184
float frequency
Definition KrotosAudioBufferDSP.h:178
float grainSize
Definition KrotosAudioBufferDSP.h:181