Skip to content

Commit

Permalink
Extend fake processing algorithms in ARATestPlugIn with mono- and pol…
Browse files Browse the repository at this point in the history
…yphonic versions
  • Loading branch information
sgretscher committed Jun 13, 2024
1 parent fbf188f commit 029fdb5
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 39 deletions.
4 changes: 2 additions & 2 deletions TestPlugIn/ARATestDocumentController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class AlgorithmPropertiesWrapper
private:
AlgorithmPropertiesWrapper (const TestProcessingAlgorithm* algorithm)
: _algorithm { algorithm },
_algorithmProperties { _algorithm->getIdentifier ().c_str (), _algorithm->getName ().c_str () }
_algorithmProperties { _algorithm->getIdentifier (), _algorithm->getName () }
{}

public:
Expand Down Expand Up @@ -476,7 +476,7 @@ bool ARATestDocumentController::doRestoreObjectsFromArchive (ARA::PlugIn::HostAr
cancelAnalysisOfAudioSource (testAudioSource);

// set the algorithm from the restored persistent ID
const auto algorithm { TestProcessingAlgorithm::getAlgorithmWithIdentifier (algorithmID) };
const auto algorithm { TestProcessingAlgorithm::getAlgorithmWithIdentifier (algorithmID.c_str ()) };
ARA_INTERNAL_ASSERT (algorithm != nullptr); // if we ever add or remove algorithms, we need some proper migration here
testAudioSource->setProcessingAlgorithm (algorithm);

Expand Down
97 changes: 64 additions & 33 deletions TestPlugIn/TestAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <chrono>
#include <thread>
#include <cmath>
#include <cstring>

// The test plug-in pretends to be able to do a kARAContentTypeNotes analysis:
// To simulate this, it reads all samples and creates a note with invalid pitch for each range of
Expand Down Expand Up @@ -96,23 +97,11 @@ std::unique_ptr<TestNoteContent> decodeTestNoteContent (TestUnarchiver& unarchiv

/*******************************************************************************/

class DefaultProcessingAlgorithm : public TestProcessingAlgorithm
class PseudoAnalysisProcessingAlgorithm : public TestProcessingAlgorithm
{
public:
using TestProcessingAlgorithm::TestProcessingAlgorithm;

const std::string& getName () const override
{
static const std::string name { "default algorithm" };
return name;
}

const std::string& getIdentifier () const override
{
static const std::string identifier { "org.ara-audio.examples.testplugin.algorithm.default" };
return identifier;
}

std::unique_ptr<TestNoteContent> analyzeNoteContent (TestAnalysisCallbacks* analysisCallbacks, const int64_t sampleCount, const double sampleRate, const uint32_t channelCount) const noexcept override
{
analysisCallbacks->notifyAnalysisProgressStarted ();
Expand Down Expand Up @@ -175,8 +164,8 @@ class DefaultProcessingAlgorithm : public TestProcessingAlgorithm
// found end of note - construct note
const double noteStartTime { static_cast<double> (lastNoteStartIndex) / sampleRate };
const double noteDuration { static_cast<double> (index - lastNoteStartIndex) / sampleRate };
TestNote foundNote { ARA::kARAInvalidFrequency, volume, noteStartTime, noteDuration };
foundNotes.push_back (foundNote);
addNotesForSignalRange (foundNotes, volume, noteStartTime, noteDuration);

volume = 0.0f;
}
else
Expand Down Expand Up @@ -209,34 +198,79 @@ class DefaultProcessingAlgorithm : public TestProcessingAlgorithm
// last note continued until the end of the audio source - construct last note
const double noteStartTime { static_cast<double> (lastNoteStartIndex) / sampleRate };
const double noteDuration { static_cast<double> (sampleCount - lastNoteStartIndex) / sampleRate };
TestNote foundNote { ARA::kARAInvalidFrequency, volume, noteStartTime, noteDuration };
foundNotes.push_back (foundNote);
addNotesForSignalRange (foundNotes, volume, noteStartTime, noteDuration);
}

// complete analysis and store result
analysisCallbacks->notifyAnalysisProgressCompleted ();
return std::make_unique<TestNoteContent> (foundNotes);
}

protected:
virtual void addNotesForSignalRange (TestNoteContent& foundNotes, const float volume, const double startTime, const double duration) const = 0;
};

/*******************************************************************************/

class SingleNoteProcessingAlgorithm : public TestProcessingAlgorithm
static const
class PercussiveProcessingAlgorithm : public PseudoAnalysisProcessingAlgorithm
{
public:
using TestProcessingAlgorithm::TestProcessingAlgorithm;
PercussiveProcessingAlgorithm ()
: PseudoAnalysisProcessingAlgorithm { "Percussive", "org.ara-audio.examples.testplugin.algorithm.percussive" }
{}

const std::string& getName () const override
protected:
void addNotesForSignalRange (TestNoteContent& foundNotes, const float volume, const double startTime, const double duration) const override
{
static const std::string name { "single note algorithm" };
return name;
foundNotes.emplace_back (TestNote { ARA::kARAInvalidFrequency, volume, startTime, duration });
}
} percussiveAlgorithm;

/*******************************************************************************/

const std::string& getIdentifier () const override
static const
class MonophonicProcessingAlgorithm : public PseudoAnalysisProcessingAlgorithm
{
public:
MonophonicProcessingAlgorithm ()
: PseudoAnalysisProcessingAlgorithm { "Monophonic", "org.ara-audio.examples.testplugin.algorithm.monophonic" }
{}

protected:
void addNotesForSignalRange (TestNoteContent& foundNotes, const float volume, const double startTime, const double duration) const override
{
static const std::string identifier { "org.ara-audio.examples.testplugin.algorithm.singlenote" };
return identifier;
foundNotes.emplace_back (TestNote { 440.0f, volume, startTime, duration }); // standard tuning A
}
} monophonicAlgorithm;

/*******************************************************************************/

static const
class PolyphonicProcessingAlgorithm : public PseudoAnalysisProcessingAlgorithm
{
public:
PolyphonicProcessingAlgorithm ()
: PseudoAnalysisProcessingAlgorithm { "Polyphonic", "org.ara-audio.examples.testplugin.algorithm.polyphonic" }
{}

protected:
void addNotesForSignalRange (TestNoteContent& foundNotes, const float volume, const double startTime, const double duration) const override
{
foundNotes.emplace_back (TestNote { 523.2511f, volume, startTime, duration }); // standard tuning C
foundNotes.emplace_back (TestNote { 659.2551f, volume, startTime, duration }); // standard tuning E
}
} polyphonicAlgorithm;

/*******************************************************************************/

static const
class SingleNoteProcessingAlgorithm : public TestProcessingAlgorithm
{
public:
SingleNoteProcessingAlgorithm ()
: TestProcessingAlgorithm { "Single Note", "org.ara-audio.examples.testplugin.algorithm.singlenote" }
{}

std::unique_ptr<TestNoteContent> analyzeNoteContent (TestAnalysisCallbacks* analysisCallbacks, const int64_t sampleCount, const double sampleRate, uint32_t /*channelCount*/) const override
{
Expand Down Expand Up @@ -265,29 +299,26 @@ class SingleNoteProcessingAlgorithm : public TestProcessingAlgorithm
analysisCallbacks->notifyAnalysisProgressCompleted ();
return std::make_unique<TestNoteContent> (std::vector<TestNote> { foundNote });
}
};
} singleNoteAlgorithm;

/*******************************************************************************/

static const DefaultProcessingAlgorithm defaultAlgorithm;
static const SingleNoteProcessingAlgorithm singleNoteAlgorithm;

std::vector<const TestProcessingAlgorithm*> const& TestProcessingAlgorithm::getAlgorithms ()
{
static const std::vector<const TestProcessingAlgorithm*> algorithms { &defaultAlgorithm, &singleNoteAlgorithm };
static const std::vector<const TestProcessingAlgorithm*> algorithms { &percussiveAlgorithm, &monophonicAlgorithm, &polyphonicAlgorithm, &singleNoteAlgorithm };
return algorithms;
}

const TestProcessingAlgorithm* TestProcessingAlgorithm::getDefaultAlgorithm ()
{
return getAlgorithmWithIdentifier (defaultAlgorithm.getIdentifier ());
return &percussiveAlgorithm;
}

const TestProcessingAlgorithm* TestProcessingAlgorithm::getAlgorithmWithIdentifier (const std::string& identifier)
const TestProcessingAlgorithm* TestProcessingAlgorithm::getAlgorithmWithIdentifier (const char* identifier)
{
const auto begin { getAlgorithms ().begin () };
const auto end { getAlgorithms ().end () };
const auto it { std::find_if (begin, end, [identifier] (const TestProcessingAlgorithm* algorithm)
{ return algorithm->getIdentifier ().compare (identifier) == 0; } ) };
{ return std::strcmp (algorithm->getIdentifier (), identifier) == 0; } ) };
return (it != end) ? *it : nullptr;
}
15 changes: 11 additions & 4 deletions TestPlugIn/TestAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,24 @@ class TestAnalysisCallbacks
class TestProcessingAlgorithm
{
protected:
inline TestProcessingAlgorithm () = default;
TestProcessingAlgorithm (const char* name, const char* identifier)
: _name { name },
_identifier { identifier }
{}

public:
virtual ~TestProcessingAlgorithm () = default;

static std::vector<const TestProcessingAlgorithm*> const& getAlgorithms ();
static const TestProcessingAlgorithm* getDefaultAlgorithm ();
static const TestProcessingAlgorithm* getAlgorithmWithIdentifier (const std::string& identifier);
static const TestProcessingAlgorithm* getAlgorithmWithIdentifier (const char* identifier);

virtual const std::string& getName () const = 0;
virtual const std::string& getIdentifier () const = 0;
const char* getName () const { return _name; }
const char* getIdentifier () const { return _identifier; }

virtual std::unique_ptr<TestNoteContent> analyzeNoteContent (TestAnalysisCallbacks* analysisCallbacks, int64_t sampleCount, double sampleRate, uint32_t channelCount) const = 0;

private:
const char* _name;
const char* _identifier;
};

0 comments on commit 029fdb5

Please sign in to comment.