diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/.gitkeep b/examples/ofx/prob_drums+ml+myo/bin/data/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-thung.wav b/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-thung.wav new file mode 100644 index 0000000000000000000000000000000000000000..882ee40589b51830a12c3fe0b7ac471088480921 Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-thung.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-tong.wav b/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-tong.wav new file mode 100644 index 0000000000000000000000000000000000000000..a8cdd0495c0632abfedc71519322b39d8e27beff Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/drums-ciblon-medium-tong.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl1.wav b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl1.wav new file mode 100644 index 0000000000000000000000000000000000000000..97de1a9afd85b3a3a5524d4158578ef909c5cc9d Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl1.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl2.wav b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl2.wav new file mode 100644 index 0000000000000000000000000000000000000000..31ebc6ee8d77babf3f04a277fb648bf4dd3811c5 Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl2.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl3.wav b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl3.wav new file mode 100644 index 0000000000000000000000000000000000000000..24c556d305fabc7fc3cad7c37e33b1ca03f8331b Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl3.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl4.wav b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl4.wav new file mode 100644 index 0000000000000000000000000000000000000000..4f9655cd5b4c82f481b2621b98f0a084fc0ca996 Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl4.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl5.wav b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl5.wav new file mode 100644 index 0000000000000000000000000000000000000000..6914f80731e21c07e834c98fe48aaca5882fc685 Binary files /dev/null and b/examples/ofx/prob_drums+ml+myo/bin/data/saron-sbpl5.wav differ diff --git a/examples/ofx/prob_drums+ml+myo/bin/data/thung b/examples/ofx/prob_drums+ml+myo/bin/data/thung new file mode 100644 index 0000000000000000000000000000000000000000..342b42304cf2fba3263c28ef068b81014050f570 --- /dev/null +++ b/examples/ofx/prob_drums+ml+myo/bin/data/thung @@ -0,0 +1,14 @@ +<group> + <0>100</0> + <1>0</1> + <2>44</2> + <3>0</3> + <4>100</4> + <5>0</5> + <6>45</6> + <7>0</7> + <8>100</8> + <9>0</9> + <10>45</10> + <11>0</11> +</group> diff --git a/examples/ofx/prob_drums+ml+myo/src/main.cpp b/examples/ofx/prob_drums+ml+myo/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e57370b26ee652c85ce0b32f19eace3b681585a4 --- /dev/null +++ b/examples/ofx/prob_drums+ml+myo/src/main.cpp @@ -0,0 +1,13 @@ +#include "ofMain.h" +#include "ofApp.h" + +//======================================================================== +int main( ){ + ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context + + // this kicks off the running of my app + // can be OF_WINDOW or OF_FULLSCREEN + // pass in width and height too: + ofRunApp(new ofApp()); + +} diff --git a/examples/ofx/prob_drums+ml+myo/src/ofApp.cpp b/examples/ofx/prob_drums+ml+myo/src/ofApp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..339beb4d4b68fa0b0f549db632463a475f932c81 --- /dev/null +++ b/examples/ofx/prob_drums+ml+myo/src/ofApp.cpp @@ -0,0 +1,338 @@ +#include <array> + +#include "ofApp.h" + +//-------------------------------------------------------------- +void ofApp::setup(){ + + myo.setup(); + + //gui + probsClear.addListener(this, &ofApp::probsClearPressed); + resetModel.addListener(this, &ofApp::resetModelPressed); + + guiTong.setup("tong"); + guiTong.add(tong0.setup("1", 50, 0, 100)); + guiTong.add(tong1.setup("2", 0, 0, 100)); + guiTong.add(tong2.setup("3", 90, 0, 100)); + guiTong.add(tong3.setup("4", 0, 0, 100)); + guiTong.add(tong4.setup("5", 90, 0, 100)); + guiTong.add(tong5.setup("6", 0, 0, 100)); + guiTong.add(tong6.setup("7", 0, 0, 100)); + guiTong.add(tong7.setup("8", 60, 0, 100)); + guiTong.add(tong8.setup("9", 0, 0, 100)); + guiTong.add(tong9.setup("10", 90, 0, 100)); + guiTong.add(tong10.setup("11", 0, 0, 100)); + guiTong.add(tong11.setup("12", 0, 0, 100)); + ofColor green(0, 255, 0); + guiTong.setHeaderBackgroundColor(green); + + guiThung.setup("thung", "thung", 250, 10); + guiThung.add(thung0.setup("1", 100, 0, 100)); + guiThung.add(thung1.setup("2", 0, 0, 100)); + guiThung.add(thung2.setup("3", 10, 0, 100)); + guiThung.add(thung3.setup("4", 0, 0, 100)); + guiThung.add(thung4.setup("5", 60, 0, 100)); + guiThung.add(thung5.setup("6", 0, 0, 100)); + guiThung.add(thung6.setup("7", 10, 0, 100)); + guiThung.add(thung7.setup("8", 0, 0, 100)); + guiThung.add(thung8.setup("9", 60, 0, 100)); + guiThung.add(thung9.setup("10", 0, 0, 100)); + guiThung.add(thung10.setup("11", 30, 0, 100)); + guiThung.add(thung11.setup("12", 0, 0, 100)); + ofColor yellow(255, 255, 0); + guiThung.setHeaderBackgroundColor(yellow); + + guiGeneral.setup("general", "general", 500, 10); + guiGeneral.add(gain.setup("gain", 1., 0., 1.)); + guiGeneral.add(modelControl.setup("run model", false)); + guiGeneral.add(resetModel.setup("reset model")); + guiGeneral.add(inputDevice.setup("myo", false)); + guiGeneral.add(probsClear.setup("clear")); + + //This will make life easier later + allSliders.push_back(tong0); + allSliders.push_back(tong1); + allSliders.push_back(tong2); + allSliders.push_back(tong3); + allSliders.push_back(tong4); + allSliders.push_back(tong5); + allSliders.push_back(tong6); + allSliders.push_back(tong7); + allSliders.push_back(tong8); + allSliders.push_back(tong9); + allSliders.push_back(tong10); + allSliders.push_back(tong11); + allSliders.push_back(thung0); + allSliders.push_back(thung1); + allSliders.push_back(thung2); + allSliders.push_back(thung3); + allSliders.push_back(thung4); + allSliders.push_back(thung5); + allSliders.push_back(thung6); + allSliders.push_back(thung7); + allSliders.push_back(thung8); + allSliders.push_back(thung9); + allSliders.push_back(thung10); + allSliders.push_back(thung11); + + //RapidLib + trained = false; + + //loading samples + saron_sbpl1.load(ofToDataPath("saron-sbpl1.wav")); + saron_sbpl2.load(ofToDataPath("saron-sbpl2.wav")); + saron_sbpl3.load(ofToDataPath("saron-sbpl3.wav")); + saron_sbpl4.load(ofToDataPath("saron-sbpl4.wav")); + saron_sbpl5.load(ofToDataPath("saron-sbpl5.wav")); + + ciblon_tong.load(ofToDataPath("drums-ciblon-medium-tong.wav")); + ciblon_thung.load(ofToDataPath("drums-ciblon-medium-thung.wav")); + + //maxi Clock + myClock.setTicksPerBeat(4);//This sets the number of ticks per beat + myClock.setTempo(120);// This sets the tempo in Beats Per Minute + + //audio setup + sampleRate = 44100; + bufferSize = 512; + + ofxMaxiSettings::setup(sampleRate, 2, initialBufferSize); + ofSoundStreamSetup(2,2,this, sampleRate, bufferSize, 4); +} + +//-------------------------------------------------------------- +void ofApp::update(){ + + if (inputDevice) { //Only when Myo is toggled on + + //Simple gain control + float emg = myo.getDevices()[0]->getEmgSamples()[4]; + streamBuf.pushToWindow(double(emg)); + gain = streamBuf.rms() * 0.01; + + //Machine learning with quarternions + double myoX = myo.getDevices()[0]->getQuaternion().x(); + double myoY = myo.getDevices()[0]->getQuaternion().y(); + double myoZ = myo.getDevices()[0]->getQuaternion().z(); + double myoW = myo.getDevices()[0]->getQuaternion().w(); + + if (inputDevice) { + if (recordingState > 0) { + trainingExample tempExample; + tempExample.input = { myoX, myoY, myoZ, myoW }; + for (int i = 0; i < allSliders.size() ; ++i) { + tempExample.output.push_back(double(allSliders[i])); + } + trainingSet.push_back(tempExample); + } else if (trained && modelControl == 1) { + std::vector<double> inputVec; + inputVec.push_back(myoX); + inputVec.push_back(myoY); + inputVec.push_back(myoZ); + inputVec.push_back(myoW); + std::vector<double> output = myNN.run(inputVec); + + for (int i = 0; i < output.size(); ++i) { + allSliders[i] = int(output[i]); + } + } + } + } +} + +//-------------------------------------------------------------- +void ofApp::exit(){ + myo.stop(); +} + + +//-------------------------------------------------------------- +void ofApp::draw(){ + //ofClear(0); + ofDrawBitmapString(currentBeat, 100, 300); + ofDrawBitmapString("Hold space to record", 200, 300); + + guiTong.draw(); + guiThung.draw(); + guiGeneral.draw(); + + if (inputDevice) { + ofSetColor(255); + for ( int i=0; i<myo.getDevices().size(); i++ ) { + stringstream s; + s << "id: " << myo.getDevices()[i]->getId() << endl; + s << "which: " << myo.getDevices()[i]->getWhichArm() << endl; + s << "pose: " << myo.getDevices()[i]->getPose() << endl; + s << "accel: "; + s << myo.getDevices()[i]->getAccel().x << ","; + s << myo.getDevices()[i]->getAccel().y << ","; + s << myo.getDevices()[i]->getAccel().z << endl; + s << "gyro: "; + s << myo.getDevices()[i]->getGyro().x << ","; + s << myo.getDevices()[i]->getGyro().y << ","; + s << myo.getDevices()[i]->getGyro().z << endl; + s << "quaternion: "; + s << myo.getDevices()[i]->getQuaternion().x() << ","; + s << myo.getDevices()[i]->getQuaternion().y() << ","; + s << myo.getDevices()[i]->getQuaternion().z() << ","; + s << myo.getDevices()[i]->getQuaternion().w() << endl; + s << "roll/pitch/yaw: "; + s << myo.getDevices()[i]->getRoll() << ","; + s << myo.getDevices()[i]->getPitch() << ","; + s << myo.getDevices()[i]->getYaw() << endl; + s << "raw data: "; + for ( int j=0; j<8; j++ ) { + s << myo.getDevices()[i]->getEmgSamples()[j]; + s << ","; + } + s << endl; + ofSetColor(0); + ofDrawBitmapString(s.str(), 10, 400 + i*100); + } + } + +} + +//-------------------------------------------------------------- +void ofApp::probsClearPressed() { + std::cout << "clearing probs" << std::endl; + for (int i = 0; i < allSliders.size(); ++i) { + allSliders[i] = 0; + } +} + +//-------------------------------------------------------------- +void ofApp::resetModelPressed() { + std::cout << "resetting models" << std::endl; + myNN.reset(); + trainingSet.clear(); + modelControl = false; +} + +//-------------------------------------------------------------- +bool eventTest(int prob) { + int testRand = rand() % 100; + if (testRand < prob) { + return true; + } + return false; +} + +//-------------------------------------------------------------- +void ofApp::audioOut(float * output, int bufferSize, int nChannels) { + //probs = { tong0, tong1, tong2, tong3, tong4, tong5, tong6, tong7, tong8, tong9, tong10, tong11 }; + //probs2 = { thung0, thung1, thung2, thung3, thung4, thung5, thung6, thung7, thung8, thung9, thung10, thung11 }; + bool beatsTong[12]; + bool beats2[12]; + for (int i = 0; i < 12; ++i) { + beatsTong[i] = eventTest(allSliders[i]); + beats2[i] = eventTest(allSliders[i + 12]); + } + int lastCount = 0; + int testMe = 0; + for (int i = 0; i < bufferSize; i++){ + + myClock.ticker(); + if (myClock.tick) { + if (beatsTong[currentBeat]) { + ciblon_tong.trigger(); + } + if (beats2[currentBeat]) { + ciblon_thung.trigger(); + } + currentBeat = (currentBeat + 1) % 12; + } + + outputs[0] = ciblon_tong.playOnce() * gain; + outputs[1] = ciblon_thung.playOnce() * gain; + output[i*nChannels ] = outputs[0]; + output[i*nChannels + 1] = outputs[1]; + } + +} + +//-------------------------------------------------------------- +void ofApp::keyPressed(int key){ + //std::cout << "key: " << key << std::endl; + switch(key) { + case 32: + recordingState = 1; + break; + case 13: + modelControl = (modelControl) ? false : true; + break; + } +} + +//-------------------------------------------------------------- +void ofApp::keyReleased(int key){ + recordingState = 0; + if (trainingSet.size() > 0) { + trained = myNN.train(trainingSet); + std::cout << "trained: " << trained << std::endl; + } +} + +//-------------------------------------------------------------- +void ofApp::mouseMoved(int x, int y ){ + if (inputDevice == false) { //don't do this with Myo is on + if (recordingState > 0) { + trainingExample tempExample; + tempExample.input = { double(x), double(y) }; + for (int i = 0; i < allSliders.size() ; ++i) { + tempExample.output.push_back(double(allSliders[i])); + } + trainingSet.push_back(tempExample); + } else if (trained && modelControl == 1) { + std::vector<double> inputVec; + inputVec.push_back(double(x)); + inputVec.push_back(double(y)); + std::vector<double> output = myNN.run(inputVec); + + for (int i = 0; i < output.size(); ++i) { + allSliders[i] = int(output[i]); + } + } + } +} + +//-------------------------------------------------------------- +void ofApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mousePressed(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseEntered(int x, int y){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseExited(int x, int y){ + +} + +//-------------------------------------------------------------- +void ofApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void ofApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void ofApp::dragEvent(ofDragInfo dragInfo){ + +} diff --git a/examples/ofx/prob_drums+ml+myo/src/ofApp.h b/examples/ofx/prob_drums+ml+myo/src/ofApp.h new file mode 100644 index 0000000000000000000000000000000000000000..ffcad8f1a95a1decb66956ea6fda03a6d1cf437b --- /dev/null +++ b/examples/ofx/prob_drums+ml+myo/src/ofApp.h @@ -0,0 +1,91 @@ +#pragma once + +#include <vector> + +#include "ofMain.h" +#include "ofxGui.h" +#include "ofxMyo.h" +#include "ofxMaxim.h" +#include "regression.h" +#include "rapidStream.h" + +class ofApp : public ofBaseApp{ + +public: + void setup(); + void update(); + void draw(); + void exit(); + + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y ); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void mouseEntered(int x, int y); + void mouseExited(int x, int y); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + + void probsClearPressed(); + void resetModelPressed(); + + ofxIntSlider thung0, thung1, thung2, thung3; + ofxIntSlider thung4, thung5, thung6, thung7; + ofxIntSlider thung8, thung9, thung10, thung11; + std::vector<ofxIntSlider> thungs; + ofxPanel guiThung; + + ofxIntSlider tong0, tong1, tong2, tong3; + ofxIntSlider tong4, tong5, tong6, tong7; + ofxIntSlider tong8, tong9, tong10, tong11; + ofxPanel guiTong; + + ofxFloatSlider gain; + ofxToggle inputDevice; + ofxToggle modelControl; + ofxButton resetModel; + ofxButton probsClear; + ofxPanel guiGeneral; + + std::vector<ofxIntSlider> allSliders; + + //Maxi + void audioOut(float * output, int bufferSize, int nChannels); + //void audioIn(float * input, int bufferSize, int nChannels); + + int bufferSize; + int initialBufferSize; + int sampleRate; + +private: + + ofxMyo::Myo myo; + + //---------Maxi---------------// + double outputs[2]; + + maxiSample saron_sbpl1; + maxiSample saron_sbpl2; + maxiSample saron_sbpl3; + maxiSample saron_sbpl4; + maxiSample saron_sbpl5; + + maxiSample ciblon_tong; + maxiSample ciblon_thung; + + maxiClock myClock; + + int currentBeat; + + //---------RapidLib---------------// + regression myNN; + std::vector<trainingExample> trainingSet; + int recordingState; + bool trained; + + rapidStream streamBuf = rapidStream(25); + +};