Commit e48589eb authored by Joseph Larralde's avatar Joseph Larralde
Browse files

minor updates

parent 0f3b33d6
...@@ -81,25 +81,27 @@ bool xmmTool<SingleClassModel, Model>::train(const rapidmix::trainingData& newTr ...@@ -81,25 +81,27 @@ bool xmmTool<SingleClassModel, Model>::train(const rapidmix::trainingData& newTr
template <class SingleClassModel, class Model> template <class SingleClassModel, class Model>
Json::Value xmmTool<SingleClassModel, Model>::toJSON(/*std::string modelType*/) { Json::Value xmmTool<SingleClassModel, Model>::toJSON(/*std::string modelType*/) {
Json::Value root; Json::Value root;
Json::Value metadata;
Json::Value modelSet;
metadata["creator"] = "Rapid API C++"; root["docType"] = "rapid-mix:ml-model";
metadata["version"] = "v0.1.1"; //TODO: This should be a macro someplace root["docVersion"] = RAPIDMIX_JSON_DOC_VERSION;
metadata["family"] = "xmm";
root["metadata"] = metadata;
modelSet.append(model.toJson()); Json::Value target;
root["modelSet"] = modelSet;
target["name"] = "xmm";
target["version"] = "v1.0.0";
root["target"] = target;
root["payload"] = model.toJson();
return root; return root;
} }
template <class SingleClassModel, class Model> template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::fromJSON(Json::Value &jm) { bool xmmTool<SingleClassModel, Model>::fromJSON(Json::Value &jm) {
if (jm["metadata"]["family"].asString().compare("xmm") == 0 && if (jm["docType"].asString().compare("rapid-mix:ml-model") == 0 &&
jm["modelSet"].size() > 0) { jm["target"]["name"].asString().compare("xmm") == 0 &&
model.fromJson(jm["modelSet"][0]); jm["payload"].size() > 0) {
model.fromJson(jm["payload"]);
model.reset(); model.reset();
return true; return true;
} }
......
...@@ -107,7 +107,7 @@ int main() { ...@@ -107,7 +107,7 @@ int main() {
std::vector<float> f({ 1, 2, 3 }); std::vector<float> f({ 1, 2, 3 });
spHost.frames(0, 1, &f[0], 1, 1); spHost.frames(0, 1, &f[0], 1, 1);
} }
std::cout << "pipo passed" << std::endl; std::cout << "pipo passed." << std::endl;
/////////////////////////////////////Test rapidStream signal processing /////////////////////////////////////Test rapidStream signal processing
......
...@@ -17,6 +17,22 @@ ...@@ -17,6 +17,22 @@
#define MAX_PATH_SIZE 256 #define MAX_PATH_SIZE 256
void doSomething(double time, double weight, PiPoValue *values, unsigned int size)
{
std::cout << time << std::endl;
}
class Stuff {
public:
Stuff() {}
~Stuff() {}
void doSomething(double time, double weight, PiPoValue *values, unsigned int size)
{
std::cout << time << std::endl;
}
};
//=============================== ONSEG TEST =================================// //=============================== ONSEG TEST =================================//
SCENARIO("Test rapidPiPoHost", "[signalProcessing]") SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
...@@ -24,23 +40,29 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -24,23 +40,29 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
GIVEN("A rapidPiPoHost class with a rapidPiPo chain and an audio file") GIVEN("A rapidPiPoHost class with a rapidPiPo chain and an audio file")
{ {
maxiSample buffer; maxiSample buffer;
Stuff stuff;
// in XCode this gives the path to DerivedData folder // in XCode this gives the path to DerivedData folder
// char pathStrBuf[MAX_PATH_SIZE]; // char pathStrBuf[MAX_PATH_SIZE];
// char *cwd = getcwd(pathStrBuf, sizeof(pathStrBuf)); // char *cwd = getcwd(pathStrBuf, sizeof(pathStrBuf));
// std::cout << std::string(cwd) << std::endl; // std::cout << std::string(cwd) << std::endl;
// but here we just add the file to the Copy File(s) Build Phase // but here we just add the file to the Copy File(s) Build Phase
buffer.load("./data/DnB-loop-175BPM.wav", 0); buffer.load("./data/DnB-loop-175BPM.wav", 0);
// ( source : http://freesound.org/people/yewbic/sounds/40107/ ) // ( source : http://freesound.org/people/yewbic/sounds/40107/ )
buffer.reset(); // (no real need to do this here) buffer.reset(); // (no real need to do this here)
//====================================================================// //====================================================================//
// instantiate PiPo related classes here : // instantiate PiPo related classes here :
rapidmix::signalProcessingHost host; // -> this class is located in rapidPiPoTools rapidmix::signalProcessingHost host;
// host.setFrameCallback(doSomething);
// host.setFrameCallback(stuff.doSomething);
// host.setFrameCallback(dynamic_cast<frameCallback>(std::bind(&Stuff::doSomething, stuff)));
// host.setFrameCallback(dynamic_cast<frameCallback>(Stuff::* doSomething));
// if we want to add some custom PiPos to our collection : // if we want to add some custom PiPos to our collection :
// #include "myCustomPiPo.h" // #include "myCustomPiPo.h"
// PiPoCollection::addToCollection("myCustomPiPo", new PiPoCreator<myCustomPiPo>); // PiPoCollection::addToCollection("myCustomPiPo", new PiPoCreator<myCustomPiPo>);
...@@ -50,10 +72,10 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -50,10 +72,10 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
// #include "PiPoMaximChroma.h" // #include "PiPoMaximChroma.h"
// this one is not part of the default collection : // this one is not part of the default collection :
// PiPoCollection::addToCollection("chroma", new PiPoCreator<PiPoMaximChroma>); // PiPoCollection::addToCollection("chroma", new PiPoCreator<PiPoMaximChroma>);
//* //*
host.setGraph("slice:fft:sum:scale:onseg"); host.setGraph("slice:fft:sum:scale:onseg");
host.setAttr("slice.size", 1024); host.setAttr("slice.size", 1024);
host.setAttr("slice.hop", 256); host.setAttr("slice.hop", 256);
host.setAttr("slice.norm", "power"); host.setAttr("slice.norm", "power");
...@@ -73,7 +95,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -73,7 +95,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
host.setAttr("onseg.startisonset", 1.); host.setAttr("onseg.startisonset", 1.);
host.setAttr("onseg.threshold", 9.); host.setAttr("onseg.threshold", 9.);
host.setAttr("onseg.offthresh", -120.); host.setAttr("onseg.offthresh", -120.);
std::cout << "onseg threshold : "; std::cout << "onseg threshold : ";
std::cout << host.getDoubleAttr("onseg.threshold") << std::endl; std::cout << host.getDoubleAttr("onseg.threshold") << std::endl;
std::cout << "fft mode : "; std::cout << "fft mode : ";
...@@ -81,7 +103,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -81,7 +103,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
std::cout << "param names : " << std::endl; std::cout << "param names : " << std::endl;
std::vector<std::string> attrs = host.getAttrNames(); std::vector<std::string> attrs = host.getAttrNames();
for (int i = 0; i < attrs.size(); ++i) for (int i = 0; i < attrs.size(); ++i)
{ {
std::cout << "- " << attrs[i] << std::endl; std::cout << "- " << attrs[i] << std::endl;
...@@ -94,7 +116,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -94,7 +116,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
//std::string filePath = ${PROJECT_DIR}; //std::string filePath = ${PROJECT_DIR};
std::string filePath = "./data/pipo.json"; std::string filePath = "./data/pipo.json";
std::cout << filePath << std::endl; std::cout << filePath << std::endl;
//host.writeJSON(filePath); //host.writeJSON(filePath);
host.readJSON(filePath); host.readJSON(filePath);
//host.putJSON(jj); //host.putJSON(jj);
...@@ -104,7 +126,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -104,7 +126,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
// set another chain : // set another chain :
// pipoHost.setChain("chroma"); // pipoHost.setChain("chroma");
WHEN("file is processed") WHEN("file is processed")
{ {
rapidmix::signalAttributes sa; rapidmix::signalAttributes sa;
...@@ -117,9 +139,9 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]") ...@@ -117,9 +139,9 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
sa.hasVarSize = false; sa.hasVarSize = false;
sa.domain = 0; sa.domain = 0;
sa.maxFrames = 1; sa.maxFrames = 1;
host.setInputStreamAttributes(sa); host.setInputSignalAttributes(sa);
float value; float value;
for (unsigned int i = 0; i < buffer.length; ++i) { for (unsigned int i = 0; i < buffer.length; ++i) {
value = buffer.play(); value = buffer.play();
......
//
// test_rapidXmmTools.cpp
// Unit tests for rapidXmmTools
//
#ifndef CATCH_CONFIG_MAIN #ifndef CATCH_CONFIG_MAIN
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#endif #endif
...@@ -18,37 +13,37 @@ SCENARIO("Test GMM", "[machineLearning]") ...@@ -18,37 +13,37 @@ SCENARIO("Test GMM", "[machineLearning]")
{ {
rapidmix::xmmConfig xcfg; rapidmix::xmmConfig xcfg;
xcfg.relativeRegularization = 0.1; xcfg.relativeRegularization = 0.1;
rapidmix::trainingData myXmmData; rapidmix::trainingData myXmmData;
std::vector<double> myXmmInput; std::vector<double> myXmmInput;
std::vector<double> myXmmOutput; std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1"); myXmmData.startRecording("lab1");
myXmmInput = { 0.2, 0.7 }; myXmmInput = { 0.2, 0.7 };
myXmmData.addElement(myXmmInput, myXmmOutput); myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording(); myXmmData.stopRecording();
myXmmData.startRecording("lab2"); myXmmData.startRecording("lab2");
myXmmInput = { 0.8, 0.1 }; myXmmInput = { 0.8, 0.1 };
myXmmData.addElement(myXmmInput, myXmmOutput); myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording(); myXmmData.stopRecording();
myXmmData.writeJSON("/var/tmp/testTrainingData.json"); myXmmData.writeJSON("/var/tmp/testTrainingData.json");
rapidmix::xmmStaticClassification myGmm(xcfg); rapidmix::xmmStaticClassification myGmm(xcfg);
myGmm.train(myXmmData); myGmm.train(myXmmData);
std::string filepath = "/var/tmp/modelSetDescription"; std::string filepath = "/var/tmp/modelSetDescription";
myGmm.writeJSON(filepath); myGmm.writeJSON(filepath);
myXmmInput = { 0.2, 0.7 }; myXmmInput = { 0.2, 0.7 };
WHEN("GMM model is deserialized from file") WHEN("GMM model is deserialized from file")
{ {
rapidmix::xmmStaticClassification myGmmFromFile; rapidmix::xmmStaticClassification myGmmFromFile;
myGmmFromFile.readJSON(filepath); myGmmFromFile.readJSON(filepath);
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
{ {
REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromFile.run(myXmmInput)[0]); REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromFile.run(myXmmInput)[0]);
...@@ -59,7 +54,7 @@ SCENARIO("Test GMM", "[machineLearning]") ...@@ -59,7 +54,7 @@ SCENARIO("Test GMM", "[machineLearning]")
{ {
rapidmix::xmmStaticClassification myGmmFromString; rapidmix::xmmStaticClassification myGmmFromString;
myGmmFromString.putJSON(myGmm.getJSON()); myGmmFromString.putJSON(myGmm.getJSON());
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
{ {
REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromString.run(myXmmInput)[0]); REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromString.run(myXmmInput)[0]);
...@@ -78,39 +73,39 @@ SCENARIO("Test GMR", "[machineLearning]") ...@@ -78,39 +73,39 @@ SCENARIO("Test GMR", "[machineLearning]")
{ {
rapidmix::xmmConfig xcfg; rapidmix::xmmConfig xcfg;
xcfg.relativeRegularization = 0.1; xcfg.relativeRegularization = 0.1;
rapidmix::trainingData myXmmData; rapidmix::trainingData myXmmData;
std::vector<double> myXmmInput; std::vector<double> myXmmInput;
std::vector<double> myXmmOutput; std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1"); myXmmData.startRecording("lab1");
myXmmInput = { 0.2, 0.7 }; myXmmInput = { 0.2, 0.7 };
myXmmOutput = { 1.0 }; myXmmOutput = { 1.0 };
myXmmData.addElement(myXmmInput, myXmmOutput); myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording(); myXmmData.stopRecording();
myXmmData.startRecording("lab2"); myXmmData.startRecording("lab2");
myXmmInput = { 0.8, 0.1 }; myXmmInput = { 0.8, 0.1 };
myXmmOutput = { 2.0 }; myXmmOutput = { 2.0 };
myXmmData.addElement(myXmmInput, myXmmOutput); myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording(); myXmmData.stopRecording();
myXmmData.writeJSON("/var/tmp/testTrainingData.json"); myXmmData.writeJSON("/var/tmp/testTrainingData.json");
rapidmix::xmmStaticRegression myGmr(xcfg); rapidmix::xmmStaticRegression myGmr(xcfg);
myGmr.train(myXmmData); myGmr.train(myXmmData);
std::string filepath = "/var/tmp/modelSetDescription"; std::string filepath = "/var/tmp/modelSetDescription";
myGmr.writeJSON(filepath); myGmr.writeJSON(filepath);
myXmmInput = { 0.2, 0.7 }; myXmmInput = { 0.2, 0.7 };
WHEN("GMM model is deserialized from file") WHEN("GMM model is deserialized from file")
{ {
rapidmix::xmmStaticClassification myGmrFromFile; rapidmix::xmmStaticClassification myGmrFromFile;
myGmrFromFile.readJSON(filepath); myGmrFromFile.readJSON(filepath);
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
{ {
double epsilon = 0.001; double epsilon = 0.001;
...@@ -119,12 +114,12 @@ SCENARIO("Test GMR", "[machineLearning]") ...@@ -119,12 +114,12 @@ SCENARIO("Test GMR", "[machineLearning]")
REQUIRE(std::abs(origOut - fileOut) < epsilon); REQUIRE(std::abs(origOut - fileOut) < epsilon);
} }
} }
WHEN("GMM model is deserialized from JSON stream") WHEN("GMM model is deserialized from JSON stream")
{ {
rapidmix::xmmStaticClassification myGmrFromString; rapidmix::xmmStaticClassification myGmrFromString;
myGmrFromString.putJSON(myGmr.getJSON()); myGmrFromString.putJSON(myGmr.getJSON());
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
{ {
double epsilon = 0.001; double epsilon = 0.001;
...@@ -148,10 +143,10 @@ SCENARIO("Test HMM", "[machineLearning]") ...@@ -148,10 +143,10 @@ SCENARIO("Test HMM", "[machineLearning]")
xcfg.relativeRegularization = 0.1; xcfg.relativeRegularization = 0.1;
xcfg.states = 6; xcfg.states = 6;
xcfg.likelihoodWindow = 10; xcfg.likelihoodWindow = 10;
rapidmix::trainingData myXmmData; rapidmix::trainingData myXmmData;
std::vector<double> myXmmOutput; std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1"); myXmmData.startRecording("lab1");
std::vector<std::vector<double>> myXmmPhrase = { std::vector<std::vector<double>> myXmmPhrase = {
{ 0.0, 0.0 }, { 0.0, 0.0 },
...@@ -179,16 +174,16 @@ SCENARIO("Test HMM", "[machineLearning]") ...@@ -179,16 +174,16 @@ SCENARIO("Test HMM", "[machineLearning]")
myXmmData.addElement(myXmmPhrase[i], myXmmOutput); myXmmData.addElement(myXmmPhrase[i], myXmmOutput);
} }
myXmmData.stopRecording(); myXmmData.stopRecording();
rapidmix::xmmTemporalClassification myHmm(xcfg); rapidmix::xmmTemporalClassification myHmm(xcfg);
myHmm.train(myXmmData); myHmm.train(myXmmData);
myXmmData.writeJSON("/var/tmp/testTrainingData.json"); myXmmData.writeJSON("/var/tmp/testTrainingData.json");
std::string filepath = "/var/tmp/modelSetDescription"; std::string filepath = "/var/tmp/modelSetDescription";
myHmm.writeJSON(filepath); myHmm.writeJSON(filepath);
WHEN("HMM model processes the phrase it was trained with") WHEN("HMM model processes the phrase it was trained with")
{ {
THEN("check its time progression output is constantly increasing") THEN("check its time progression output is constantly increasing")
...@@ -201,16 +196,16 @@ SCENARIO("Test HMM", "[machineLearning]") ...@@ -201,16 +196,16 @@ SCENARIO("Test HMM", "[machineLearning]")
} }
std::vector<double> sortedProgress = progress; std::vector<double> sortedProgress = progress;
std::sort(sortedProgress.begin(), sortedProgress.end()); std::sort(sortedProgress.begin(), sortedProgress.end());
REQUIRE(std::equal(progress.begin(), progress.end(), sortedProgress.begin())); REQUIRE(std::equal(progress.begin(), progress.end(), sortedProgress.begin()));
} }
} }
WHEN("HMM model is deserialized from file") WHEN("HMM model is deserialized from file")
{ {
rapidmix::xmmTemporalClassification myHmmFromFile; rapidmix::xmmTemporalClassification myHmmFromFile;
myHmmFromFile.readJSON(filepath); myHmmFromFile.readJSON(filepath);
for (int i = 0; i < myXmmPhrase.size(); ++i) { for (int i = 0; i < myXmmPhrase.size(); ++i) {
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
...@@ -219,14 +214,14 @@ SCENARIO("Test HMM", "[machineLearning]") ...@@ -219,14 +214,14 @@ SCENARIO("Test HMM", "[machineLearning]")
} }
} }
} }
WHEN("HMM model is deserialized from JSON stream") WHEN("HMM model is deserialized from JSON stream")
{ {
rapidmix::xmmTemporalClassification myHmmFromString; rapidmix::xmmTemporalClassification myHmmFromString;
myHmmFromString.putJSON(myHmm.getJSON()); myHmmFromString.putJSON(myHmm.getJSON());
for (int i = 0; i < myXmmPhrase.size(); ++i) { for (int i = 0; i < myXmmPhrase.size(); ++i) {
THEN("compare results of original and deserialized models") THEN("compare results of original and deserialized models")
{ {
REQUIRE(myHmm.run(myXmmPhrase[i]) == myHmmFromString.run(myXmmPhrase[i])); REQUIRE(myHmm.run(myXmmPhrase[i]) == myHmmFromString.run(myXmmPhrase[i]));
...@@ -250,9 +245,9 @@ SCENARIO("Test HMR", "[machineLearning]") ...@@ -250,9 +245,9 @@ SCENARIO("Test HMR", "[machineLearning]")
xcfg.absoluteRegularization = 0.001; xcfg.absoluteRegularization = 0.001;
xcfg.states = 6; xcfg.states = 6;
xcfg.likelihoodWindow = 10; xcfg.likelihoodWindow = 10;
rapidmix::trainingData myXmmData; rapidmix::trainingData myXmmData;
myXmmData.startRecording("lab1"); myXmmData.startRecording("lab1");
std::vector <std::pair <std::vector<double>, std::vector<double>>> myXmmPhrase = { std::vector <std::pair <std::vector<double>, std::vector<double>>> myXmmPhrase = {
{ { 0.0, 0.0 }, { 1.0 } }, { { 0.0, 0.0 }, { 1.0 } },
...@@ -276,54 +271,59 @@ SCENARIO("Test HMR", "[machineLearning]") ...@@ -276,54 +271,59 @@ SCENARIO("Test HMR", "[machineLearning]")
{ { 1.5, 2.5 }, { 19.0 } }, { { 1.5, 2.5 }, { 19.0 } },
{ { 1.6, 2.6 }, { 20.0 } } { { 1.6, 2.6 }, { 20.0 } }
}; };
for (int i = 0; i < myXmmPhrase.size(); ++i) { for (int i = 0; i < myXmmPhrase.size(); ++i) {
myXmmData.addElement(myXmmPhrase[i].first, myXmmPhrase[i].second); myXmmData.addElement(myXmmPhrase[i].first, myXmmPhrase[i].second);
} }
myXmmData.stopRecording(); myXmmData.stopRecording();
rapidmix::xmmTemporalRegression myHmr(xcfg); rapidmix::xmmTemporalRegression myHmr(xcfg);
myHmr.train(myXmmData); myHmr.train(myXmmData);
myXmmData.writeJSON("/var/tmp/testTrainingData.json"); myXmmData.writeJSON("/var/tmp/testTrainingData.json");
std::string filepath = "/var/tmp/modelSetDescription"; std::string filepath = "/var/tmp/modelSetDescription";
myHmr.writeJSON(filepath); myHmr.writeJSON(filepath);
myHmr.reset();
WHEN("HMR model processes the phrase it was trained with") WHEN("HMR model processes the phrase it was trained with")
{ {
THEN("check its regression output is the same as the output example") THEN("check its regression output is the same as the output example")
{ {
int cnt = 0; int cnt = 0;
double sum = 0; double sum = 0;
for (int i = 0; i < myXmmPhrase.size(); ++i) { for (int i = 0; i < myXmmPhrase.size(); ++i) {
std::vector<double> regression; std::vector<double> regression;
regression = myHmr.run(myXmmPhrase[i].first); regression = myHmr.run(myXmmPhrase[i].first);
for (int j = 0; j < regression.size(); ++j) { for (int j = 0; j < regression.size(); ++j) {
double delta = regression[j] - myXmmPhrase[i].second[j]; double delta = regression[j] - myXmmPhrase[i].second[j];
sum += delta * delta; sum += delta * delta;
cnt++; cnt++;
} }
} }
sum = std::sqrt(sum / cnt); sum = std::sqrt(sum / cnt);
// totally arbitrary epsilon value : // totally arbitrary epsilon value :
double epsilon = 1.0; double epsilon = 1.0;
REQUIRE(sum <= epsilon); REQUIRE(sum <= epsilon);
} }