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
template <class SingleClassModel, class Model>
Json::Value xmmTool<SingleClassModel, Model>::toJSON(/*std::string modelType*/) {
Json::Value root;
Json::Value metadata;
Json::Value modelSet;
metadata["creator"] = "Rapid API C++";
metadata["version"] = "v0.1.1"; //TODO: This should be a macro someplace
metadata["family"] = "xmm";
root["metadata"] = metadata;
root["docType"] = "rapid-mix:ml-model";
root["docVersion"] = RAPIDMIX_JSON_DOC_VERSION;
modelSet.append(model.toJson());
root["modelSet"] = modelSet;
Json::Value target;
target["name"] = "xmm";
target["version"] = "v1.0.0";
root["target"] = target;
root["payload"] = model.toJson();
return root;
}
template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::fromJSON(Json::Value &jm) {
if (jm["metadata"]["family"].asString().compare("xmm") == 0 &&
jm["modelSet"].size() > 0) {
model.fromJson(jm["modelSet"][0]);
if (jm["docType"].asString().compare("rapid-mix:ml-model") == 0 &&
jm["target"]["name"].asString().compare("xmm") == 0 &&
jm["payload"].size() > 0) {
model.fromJson(jm["payload"]);
model.reset();
return true;
}
......
......@@ -107,7 +107,7 @@ int main() {
std::vector<float> f({ 1, 2, 3 });
spHost.frames(0, 1, &f[0], 1, 1);
}
std::cout << "pipo passed" << std::endl;
std::cout << "pipo passed." << std::endl;
/////////////////////////////////////Test rapidStream signal processing
......
......@@ -17,6 +17,22 @@
#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 =================================//
SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
......@@ -24,23 +40,29 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
GIVEN("A rapidPiPoHost class with a rapidPiPo chain and an audio file")
{
maxiSample buffer;
Stuff stuff;
// in XCode this gives the path to DerivedData folder
// char pathStrBuf[MAX_PATH_SIZE];
// char *cwd = getcwd(pathStrBuf, sizeof(pathStrBuf));
// std::cout << std::string(cwd) << std::endl;
// but here we just add the file to the Copy File(s) Build Phase
buffer.load("./data/DnB-loop-175BPM.wav", 0);
// ( source : http://freesound.org/people/yewbic/sounds/40107/ )
buffer.reset(); // (no real need to do this 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 :
// #include "myCustomPiPo.h"
// PiPoCollection::addToCollection("myCustomPiPo", new PiPoCreator<myCustomPiPo>);
......@@ -50,10 +72,10 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
// #include "PiPoMaximChroma.h"
// this one is not part of the default collection :
// PiPoCollection::addToCollection("chroma", new PiPoCreator<PiPoMaximChroma>);
//*
host.setGraph("slice:fft:sum:scale:onseg");
host.setAttr("slice.size", 1024);
host.setAttr("slice.hop", 256);
host.setAttr("slice.norm", "power");
......@@ -73,7 +95,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
host.setAttr("onseg.startisonset", 1.);
host.setAttr("onseg.threshold", 9.);
host.setAttr("onseg.offthresh", -120.);
std::cout << "onseg threshold : ";
std::cout << host.getDoubleAttr("onseg.threshold") << std::endl;
std::cout << "fft mode : ";
......@@ -81,7 +103,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
std::cout << "param names : " << std::endl;
std::vector<std::string> attrs = host.getAttrNames();
for (int i = 0; i < attrs.size(); ++i)
{
std::cout << "- " << attrs[i] << std::endl;
......@@ -94,7 +116,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
//std::string filePath = ${PROJECT_DIR};
std::string filePath = "./data/pipo.json";
std::cout << filePath << std::endl;
//host.writeJSON(filePath);
host.readJSON(filePath);
//host.putJSON(jj);
......@@ -104,7 +126,7 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
// set another chain :
// pipoHost.setChain("chroma");
WHEN("file is processed")
{
rapidmix::signalAttributes sa;
......@@ -117,9 +139,9 @@ SCENARIO("Test rapidPiPoHost", "[signalProcessing]")
sa.hasVarSize = false;
sa.domain = 0;
sa.maxFrames = 1;
host.setInputStreamAttributes(sa);
host.setInputSignalAttributes(sa);
float value;
for (unsigned int i = 0; i < buffer.length; ++i) {
value = buffer.play();
......
//
// test_rapidXmmTools.cpp
// Unit tests for rapidXmmTools
//
#ifndef CATCH_CONFIG_MAIN
#define CATCH_CONFIG_MAIN
#endif
......@@ -18,37 +13,37 @@ SCENARIO("Test GMM", "[machineLearning]")
{
rapidmix::xmmConfig xcfg;
xcfg.relativeRegularization = 0.1;
rapidmix::trainingData myXmmData;
std::vector<double> myXmmInput;
std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1");
myXmmInput = { 0.2, 0.7 };
myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording();
myXmmData.startRecording("lab2");
myXmmInput = { 0.8, 0.1 };
myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording();
myXmmData.writeJSON("/var/tmp/testTrainingData.json");
rapidmix::xmmStaticClassification myGmm(xcfg);
myGmm.train(myXmmData);
std::string filepath = "/var/tmp/modelSetDescription";
myGmm.writeJSON(filepath);
myXmmInput = { 0.2, 0.7 };
WHEN("GMM model is deserialized from file")
{
rapidmix::xmmStaticClassification myGmmFromFile;
myGmmFromFile.readJSON(filepath);
THEN("compare results of original and deserialized models")
{
REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromFile.run(myXmmInput)[0]);
......@@ -59,7 +54,7 @@ SCENARIO("Test GMM", "[machineLearning]")
{
rapidmix::xmmStaticClassification myGmmFromString;
myGmmFromString.putJSON(myGmm.getJSON());
THEN("compare results of original and deserialized models")
{
REQUIRE(myGmm.run(myXmmInput)[0] == myGmmFromString.run(myXmmInput)[0]);
......@@ -78,39 +73,39 @@ SCENARIO("Test GMR", "[machineLearning]")
{
rapidmix::xmmConfig xcfg;
xcfg.relativeRegularization = 0.1;
rapidmix::trainingData myXmmData;
std::vector<double> myXmmInput;
std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1");
myXmmInput = { 0.2, 0.7 };
myXmmOutput = { 1.0 };
myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording();
myXmmData.startRecording("lab2");
myXmmInput = { 0.8, 0.1 };
myXmmOutput = { 2.0 };
myXmmData.addElement(myXmmInput, myXmmOutput);
myXmmData.stopRecording();
myXmmData.writeJSON("/var/tmp/testTrainingData.json");
rapidmix::xmmStaticRegression myGmr(xcfg);
myGmr.train(myXmmData);
std::string filepath = "/var/tmp/modelSetDescription";
myGmr.writeJSON(filepath);
myXmmInput = { 0.2, 0.7 };
WHEN("GMM model is deserialized from file")
{
rapidmix::xmmStaticClassification myGmrFromFile;
myGmrFromFile.readJSON(filepath);
THEN("compare results of original and deserialized models")
{
double epsilon = 0.001;
......@@ -119,12 +114,12 @@ SCENARIO("Test GMR", "[machineLearning]")
REQUIRE(std::abs(origOut - fileOut) < epsilon);
}
}
WHEN("GMM model is deserialized from JSON stream")
{
rapidmix::xmmStaticClassification myGmrFromString;
myGmrFromString.putJSON(myGmr.getJSON());
THEN("compare results of original and deserialized models")
{
double epsilon = 0.001;
......@@ -148,10 +143,10 @@ SCENARIO("Test HMM", "[machineLearning]")
xcfg.relativeRegularization = 0.1;
xcfg.states = 6;
xcfg.likelihoodWindow = 10;
rapidmix::trainingData myXmmData;
std::vector<double> myXmmOutput;
myXmmData.startRecording("lab1");
std::vector<std::vector<double>> myXmmPhrase = {
{ 0.0, 0.0 },
......@@ -179,16 +174,16 @@ SCENARIO("Test HMM", "[machineLearning]")
myXmmData.addElement(myXmmPhrase[i], myXmmOutput);
}
myXmmData.stopRecording();
rapidmix::xmmTemporalClassification myHmm(xcfg);
myHmm.train(myXmmData);
myXmmData.writeJSON("/var/tmp/testTrainingData.json");
std::string filepath = "/var/tmp/modelSetDescription";
myHmm.writeJSON(filepath);
WHEN("HMM model processes the phrase it was trained with")
{
THEN("check its time progression output is constantly increasing")
......@@ -201,16 +196,16 @@ SCENARIO("Test HMM", "[machineLearning]")
}
std::vector<double> sortedProgress = progress;
std::sort(sortedProgress.begin(), sortedProgress.end());
REQUIRE(std::equal(progress.begin(), progress.end(), sortedProgress.begin()));
}
}
WHEN("HMM model is deserialized from file")
{
rapidmix::xmmTemporalClassification myHmmFromFile;
myHmmFromFile.readJSON(filepath);
for (int i = 0; i < myXmmPhrase.size(); ++i) {
THEN("compare results of original and deserialized models")
......@@ -219,14 +214,14 @@ SCENARIO("Test HMM", "[machineLearning]")
}
}
}
WHEN("HMM model is deserialized from JSON stream")
{
rapidmix::xmmTemporalClassification myHmmFromString;
myHmmFromString.putJSON(myHmm.getJSON());
for (int i = 0; i < myXmmPhrase.size(); ++i) {
THEN("compare results of original and deserialized models")
{
REQUIRE(myHmm.run(myXmmPhrase[i]) == myHmmFromString.run(myXmmPhrase[i]));
......@@ -250,9 +245,9 @@ SCENARIO("Test HMR", "[machineLearning]")
xcfg.absoluteRegularization = 0.001;
xcfg.states = 6;
xcfg.likelihoodWindow = 10;
rapidmix::trainingData myXmmData;
myXmmData.startRecording("lab1");
std::vector <std::pair <std::vector<double>, std::vector<double>>> myXmmPhrase = {
{ { 0.0, 0.0 }, { 1.0 } },
......@@ -276,54 +271,59 @@ SCENARIO("Test HMR", "[machineLearning]")
{ { 1.5, 2.5 }, { 19.0 } },
{ { 1.6, 2.6 }, { 20.0 } }
};
for (int i = 0; i < myXmmPhrase.size(); ++i) {
myXmmData.addElement(myXmmPhrase[i].first, myXmmPhrase[i].second);
}
myXmmData.stopRecording();
rapidmix::xmmTemporalRegression myHmr(xcfg);
myHmr.train(myXmmData);
myXmmData.writeJSON("/var/tmp/testTrainingData.json");
std::string filepath = "/var/tmp/modelSetDescription";
myHmr.writeJSON(filepath);
myHmr.reset();
WHEN("HMR model processes the phrase it was trained with")
{
THEN("check its regression output is the same as the output example")
{
int cnt = 0;
double sum = 0;
for (int i = 0; i < myXmmPhrase.size(); ++i) {
std::vector<double> regression;
regression = myHmr.run(myXmmPhrase[i].first);
for (int j = 0; j < regression.size(); ++j) {
double delta = regression[j] - myXmmPhrase[i].second[j];
sum += delta * delta;
cnt++;
}
}
sum = std::sqrt(sum / cnt);
// totally arbitrary epsilon value :
double epsilon = 1.0;
REQUIRE(sum <= epsilon);
}
}
WHEN("HMR model is deserialized from file")
{
rapidmix::xmmTemporalRegression myHmrFromFile;
myHmrFromFile.readJSON(filepath);
for (int i = 0; i < myXmmPhrase.size(); ++i) {
myHmr.reset();
myHmrFromFile.reset();
THEN("compare results of original and deserialized models")
{
int cnt = 0;
......@@ -333,14 +333,14 @@ SCENARIO("Test HMR", "[machineLearning]")
std::vector<double> r1, r2;
r1 = myHmr.run(myXmmPhrase[i].first);
r2 = myHmrFromFile.run(myXmmPhrase[i].first);
for (int j = 0; j < r1.size(); ++j) {
double delta = r1[j] - r2[j];
sum += delta * delta;
cnt++;
}
}
sum = std::sqrt(sum / cnt);
// totally arbitrary epsilon value :
......@@ -349,33 +349,36 @@ SCENARIO("Test HMR", "[machineLearning]")
}
}
}
WHEN("HMR model is deserialized from JSON stream")
{
rapidmix::xmmTemporalRegression myHmrFromString;
myHmrFromString.putJSON(myHmr.getJSON());
for (int i = 0; i < myXmmPhrase.size(); ++i) {
myHmr.reset();
myHmrFromString.reset();
THEN("compare results of original and deserialized models")
{
int cnt = 0;
double sum = 0;
for (int i = 0; i < myXmmPhrase.size(); ++i) {
std::vector<double> r1, r2;
r1 = myHmr.run(myXmmPhrase[i].first);
r2 = myHmrFromString.run(myXmmPhrase[i].first);
for (int j = 0; j < r1.size(); ++j) {
double delta = r1[j] - r2[j];
sum += delta * delta;
cnt++;
}
}
sum = std::sqrt(sum / cnt);
// totally arbitrary epsilon value :
double epsilon = 0.1;
REQUIRE(sum <= epsilon);
......
#ifndef CATCH_CONFIG_MAIN
#define CATCH_CONFIG_MAIN
#endif
#include "catch.hpp"
#include "machineLearning.h"
//============================= TRAINING DATA ================================//
SCENARIO("Test training sets managements", "[machineLearning]")
{
GIVEN("A training set we fill in a variety of ways")
{
rapidmix::trainingData set;
set.createNewPhrase("test_label_01");
std::vector <std::pair <std::vector<double>, std::vector<double>>> phrase = {
{ { 0.0, 0.0 }, { 9.0 } },
{ { 1.0, 0.0 }, { 8.0 } },
{ { 2.0, 0.0 }, { 7.0 } },
{ { 3.0, 0.0 }, { 6.0 } },
{ { 4.0, 0.0 }, { 5.0 } },
{ { 5.0, 0.0 }, { 4.0 } },
{ { 6.0, 0.0 }, { 3.0 } },
{ { 7.0, 0.0 }, { 2.0 } },
{ { 8.0, 0.0 }, { 1.0 } },
{ { 9.0, 0.0 }, { 0.0 } }
};
for (int i = 0; i < phrase.size(); ++i) {
set.addElement(phrase[i].first, phrase[i].second);
}
WHEN("We serialize / deserialize a training set")
{
std::string js = set.getJSON();
std::cout << js << std::endl;
THEN("It should stay the same")
{
}
}
}
}
......@@ -38,6 +38,9 @@
311BA31E1EDC7ADE00244DAC /* maximilian.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE2C5A1F1ED8450C00E9FAFA /* maximilian.cpp */; };
311BA3211EDC7B2400244DAC /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 311BA3201EDC7B2400244DAC /* Accelerate.framework */; };
311BA3251EDCE80B00244DAC /* jsoncpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE2C5E081ED8450E00E9FAFA /* jsoncpp.cpp */; };
312C61BD1FE95A680085E283 /* trainingData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE2C5EC01ED8459300E9FAFA /* trainingData.cpp */; };
312C61CD1FE95A680085E283 /* jsoncpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE2C5E081ED8450E00E9FAFA /* jsoncpp.cpp */; };
312C61D41FE95A8F0085E283 /* test_trainingData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 312C61B71FE958CB0085E283 /* test_trainingData.cpp */; };
319C94A11FC5BFA80055BE40 /* PiPoHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 319C93FD1FC49BAA0055BE40 /* PiPoHost.cpp */; };
319C94A21FC5C0C10055BE40 /* PiPoCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 319C947C1FC49D490055BE40 /* PiPoCollection.cpp */; };
319C94A31FC5C0DE0055BE40 /* BayesianFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 319C93ED1FC49B5C0055BE40 /* BayesianFilter.cpp */; };
......@@ -148,6 +151,15 @@
);
runOnlyForDeploymentPostprocessing = 1;
};
312C61CF1FE95A680085E283 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
31D7B7281E6B048100917757 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 12;
......@@ -216,6 +228,8 @@
311BA2FC1EDC6F1900244DAC /* xmm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xmm.h; path = xmm/src/xmm.h; sourceTree = "<group>"; };
311BA3201EDC7B2400244DAC /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
311BA3231EDC7BA400244DAC /* DnB-loop-175BPM.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = "DnB-loop-175BPM.wav"; path = "data/DnB-loop-175BPM.wav"; sourceTree = "<group>"; };
312C61B71FE958CB0085E283 /* test_trainingData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_trainingData.cpp; sourceTree = "<group>"; };
312C61D31FE95A680085E283 /* test_trainingData */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = test_trainingData; sourceTree = BUILT_PRODUCTS_DIR; };
318E7A361FD748D900FEEB7E /* pipo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = pipo.json; path = data/pipo.json; sourceTree = "<group>"; };
319C93ED1FC49B5C0055BE40 /* BayesianFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BayesianFilter.cpp; path = pipo/modules/bayesfilter/src/BayesianFilter.cpp; sourceTree = "<group>"; };
319C93EE1FC49B5C0055BE40 /* BayesianFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BayesianFilter.h; path = pipo/modules/bayesfilter/src/BayesianFilter.h; sourceTree = "<group>"; };
......@@ -448,6 +462,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
312C61CE1FE95A680085E283 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
31D7B7271E6B048100917757 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
......@@ -1046,6 +1067,7 @@
BE2C5EE11ED8480D00E9FAFA /* test_rapidPiPo.cpp */,
BE2C5EE21ED8480D00E9FAFA /* test_rapidXMM.cpp */,
BE2C5EE31ED8480D00E9FAFA /* test_signalProcessing.cpp */,
312C61B71FE958CB0085E283 /* test_trainingData.cpp */,
);
path = src;
sourceTree = "<group>";
......@@ -1079,6 +1101,7 @@
0BFFEF311E56085C00EF19A5 /* test_rapidXMM */,
0BFFEF3F1E5608C000EF19A5 /* test_signalProcessing */,
31D7B72C1E6B048100917757 /* test_rapidPiPo */,
312C61D31FE95A680085E283 /* test_trainingData */,