Open nvssynthesis opened 2 years ago
update: the function throwing the exception is
inline void checkType(const std::type_info& received,
const std::type_info& expected) const
in types.h. A closer look shows that for some reason, while the nameOfType() of both received and expected match (both are essentia::Pool), their addresses differ. Screenshot attached. What could cause this?
Alright, a bit more detail and simplification. Regarding the following function:
template<typename timing_t = unsigned int> // int for frameSize & hopSize to be in samples, floating point to be in ms
void analyzeMini(const std::string filename = "/Users/nicholassolem/development/audio for analysis/smooth transition/sinish to saw 440hz.wav",
const essentia::Real sampleRate = 44100.f,
const timing_t frameSize = 512U,
const timing_t hopSize = 2000U,
const unsigned short aFlags = 0){
using namespace essentia::standard;
essentia::init();
AlgorithmFactory& factory = AlgorithmFactory::instance();
// USE AudioLoader INSTEAD TO GET SAMPLE RATE AUTOMATICALLY AND ALSO ALLOW MULTICHANNEL
Algorithm* audio = factory.create("MonoLoader", "filename", filename, "sampleRate", sampleRate);
Algorithm* fc = factory.create("FrameCutter",
"frameSize", frameSize,
"hopSize", hopSize);
Algorithm* w = factory.create("Windowing",
"type", "blackmanharris92", "size", frameSize);
Algorithm* spec = factory.create("Spectrum",
"size", frameSize);
Algorithm* entropy = factory.create("Entropy");
// std::unique_ptr<essentia::Pool> pool = std::make_unique<essentia::Pool>();
Algorithm* poolAggr = factory.create("PoolAggregator");
Algorithm* yamlOut = AlgorithmFactory::create("YamlOutput",
"filename", "/Users/nicholassolem/development/audio for analysis/thingTest.yaml");
// Audio -> FrameCutter
essentia::Pool *p = new essentia::Pool /*= *pool*/;
std::vector<essentia::Real> audioBuffer, frame;
essentia::Real entropyVal;
audio->output("audio").set(audioBuffer);
fc->input("signal").set(audioBuffer); // frame creator
fc->output("frame").set(frame);
w->input("frame").set(frame);
w->output("frame").set(frame);
spec->input("frame").set(frame);
spec->output("spectrum").set(frame);
entropy->input("array").set(frame);
entropy->output("entropy").set(entropyVal);
poolAggr->input("input").set(*p);
poolAggr->output("output").set(*p);
yamlOut->input("pool").set(*p);
audio->compute();
int m = 0;
while (true) {
fc->compute();
if (!(frame.size())) {
break;
}
w->compute();
spec->compute();
entropy->compute();
p->add("lowlevel.entropy", entropyVal);
m++;
}
yamlOut->compute();
delete entropy;
delete spec;
delete w;
delete fc;
delete audio;
essentia::shutdown();
// return pool;
}
When I have a command line program that runs this function, everything is fine. However, once I try to use this function in a JUCE GUI application, the above mentioned problem occurs. I simplified the structure even more than above, so that analyzeMini() just lives in the MainComponent class. I will link to my application soon so others can try to reproduce the problem. Is it possible to do a workaround by making a custom checkType that checks based on nameOfType rather than their addresses? The address mismatch of essentia::Pool is what trips it up.
This is my first github 'issue' post, so I hope I'm formatting it alright & including the right amount of information. I am writing a GUI application using essentia and juce. The program uses a few separate steps of loading in an audio file (truly just getting an absolute path to a .wav), passing that file path to a massive analysis function, and exporting the analysis in YAML format. I will be making use of a flag enum specific to these needs, so I put these functions in a struct with all static methods (nothing depends on any struct instance, no method is private, and it has no plain old data other than the flags enum). The function declarations in question are:
I believe I am doing standard essentia stuff in analyze() and exportAnalysis(), perhaps other than wrapping the pool in a unique_ptr. Maybe it is also suspect that analyze() calls essentia::shutdown() before returning the pool, and then exportAnalysis needs to re-call
so that it can then use
However, once we arrive at
yamlOutput->input("pool").set(*pool);
I get the following error:This error makes no sense to me, because it basically says that it is expecting the same type that it in fact did receive, and somehow this throws an exception. Also, when I inspect the contents of the pool I am trying to pass, it looks valid, containing all of the data from the prior analysis.
Any thoughts/suggestions?