void chladniReceiver::onAlsNoteEvent( alsNoteEventArgs &args ){ ofxOscMessage m; m.setAddress("/km/chladni/noteEvent"); m.addStringArg(args.clipName); m.addIntArg(args.note.key); sendOscMessage(m); }
// ALS Parser void chladniReceiver::onAlsTrackEvent( alsTrackEventArgs &args ){ //sendOscMessage("/km/chladni/trackChange", args.trackName ); ofxOscMessage m; m.setAddress("/km/chladni/trackChange"); m.addStringArg(args.trackName); m.addFloatArg(args.audioClip.duration); //cout << args.audioClip.time << " - " << args.trackName << endl; sendOscMessage(m); }
bool chladniReceiver::sendOscMessage(const string& _addr, const float& _value){ if( bSenderIsConnected && !_addr.empty() ){ ofxOscMessage m; m.setAddress(_addr); m.addFloatArg(_value); return sendOscMessage(m); } return false; }
// (addr starts with a slash) bool durationReceiver::sendOscMessage(const string& _addr, const string& _value){ if( bSenderIsConnected && !_addr.empty() ){ ofxOscMessage m; m.setAddress(_addr); if(_value.empty()){ m.addTriggerArg(); } else { m.addSymbolArg(_addr); } return sendOscMessage(m); } return false; }
void chladniReceiver::showGuiWindow(){ if(!bShowGuiWindow) return; ImGui::SetNextWindowSize(ImVec2(400,ofGetHeight()*0.8), ImGuiSetCond_Once); ImGui::Begin( ((string)"Module: ").append(karmaModule::getName()).append("###module-").append( ofToString(this) ).c_str() , &bShowGuiWindow ); ImGui::TextWrapped("This module receives OSC messages trough the OSCRouter module and forwards them to effects and other components."); ImGui::TextWrapped("Works together with a chladni plate / cymatics wave generator in PureData."); ImGui::Separator(); OSCRouter::ImGuiShowOSCRouterConnectionTester(); ImGui::Separator(); if( ImGui::CollapsingHeader( "OSC Setup / Config (Pd)", "chladniReceiverOSC", true, true ) ){ ImGui::TextWrapped("Pd OSC connection"); ImGui::Indent(); ImGui::TextWrapped("Configure how you connect to PureData patch /utilities/chladni-plate-generator.pd"); if(ImGui::InputInt("chladni sending port", &oscSendParams.port)){ connectOSCSender(); } static char addrBuffer[64]; for(int i=0; i<64; ++i){ if(i < oscSendParams.host.size()){ addrBuffer[i]=oscSendParams.host[i]; } else { addrBuffer[i]=0; } } if(ImGui::InputText("chladni remote host", &addrBuffer[0], 64, ImGuiInputTextFlags_EnterReturnsTrue)){ oscSendParams.host = ofToString(addrBuffer); connectOSCSender(); } if( chladniRC::getInstance().pureDataIsConnected()){ ImGui::TextWrapped("Status: Connected"); } else { ImGui::TextWrapped("Status: Not Connected"); } if(ImGui::Button("Reconnect")){ connectOSCSender(); } // todo: launch pd from OF ? // see: https://forum.openframeworks.cc/t/using-shell-script-to-launch-external-apps-from-of/3853 // see: http://stackoverflow.com/questions/646217/how-to-run-a-bash-script-from-c-program ImGui::Unindent(); ImGui::Separator(); if( chladniRC::getInstance().pureDataIsConnected() && ImGui::CollapsingHeader( "Chladni-plate Pd Controls", "chladniReceiverPdCommands", true, true ) ){ ImGui::TextWrapped("Pd OSC Controls"); ImGui::Indent(); ImGui::TextWrapped("Control the chladni Pd-patch !"); if(ImGui::Button("Trigger change")){ sendOscMessage("/km/chladni/randomChange", "1"); } static float frequency = 64.05f; if( ImGui::SliderFloat("Frequency", &frequency, 30.f, 140.f) ){ sendOscMessage( "/km/chladni/setFreq", frequency ); } static int delay = 600; if( ImGui::SliderInt("Delay (ms)", &delay, 0, 1000) ){ sendOscMessage( "/km/chladni/setDelay", delay ); } // static broadcast // if(ImGui::Checkbox("react to notes")){ // // } ImGui::Unindent(); } } ImGui::Separator(); static bool wasOpen = false; if( ImGui::CollapsingHeader( "Arduino Setup (water control)", "chladniReceiverArduino", true, true ) ){ static std::vector<ofx::IO::SerialDeviceInfo> devicesInfo = ofx::IO::SerialDeviceUtils::listDevices(); // refresh list ? if(!wasOpen){ devicesInfo = ofx::IO::SerialDeviceUtils::listDevices(); wasOpen = true; } ImGui::Indent(); ImGui::TextWrapped("Communicates with a USB Arduino device. Needs patch: /src/modules/serialController_v1/karmaMapperSerial_v1/karmaMapperSerial_v1.ino"); if(ImGui::Button("Connect to first Arduino device")){ chladniRC::getInstance().setupArduinoSerial(); } if(ImGui::ListBoxHeader("Connect to device...")){ if (!devicesInfo.empty()){ for (std::size_t i = 0; i < devicesInfo.size(); ++i) { if(ImGui::Selectable( ( devicesInfo[i].getDescription() + " (" + devicesInfo[i].getPort() + ")" +"###"+devicesInfo[i].getDescription()).c_str(), devicesInfo[i].getPort().compare( chladniRC::getInstance().getArduinoDevicePort() )==0 )){ if( chladniRC::getInstance().connectToArduino(devicesInfo[i]) ){ // todo: remember device ? } else { // todo: notify failure } } } } else { ImGui::TextWrapped("[None Available]"); } ImGui::ListBoxFooter(); } if( chladniRC::getInstance().arduinoIsConnected()){ ImGui::TextWrapped("Status: Connected to: %s", chladniRC::getInstance().getArduinoDevicePort().c_str() ); } else { ImGui::TextWrapped("Status: Not Connected"); } ImGui::Separator(); // ping if(chladniRC::getInstance().arduinoIsConnected()){ if(ImGui::Button("Ping Device")){ chladniRC::getInstance().pingArduino(); } ImGui::TextWrapped("Last ping return: %s", chladniRC::getInstance().getLastArduinoPingMessage().c_str() ); ImGui::Separator(); // Water flow ImGui::TextWrapped("Water Flow Control:"); ImGui::Indent(); for(int ev=0; ev<KM_CHLADNI_NUM_ELECTROVALVES; ++ev){ float flow = chladniRC::getInstance().getSolenoidFlow(ev); if( ImGui::SliderFloat((ofToString("EV")+ofToString(ev)).c_str(), &flow, 0.f, 1.f) ){ chladniRC::getInstance().setSolenoidFlow(ev, flow); } } ImGui::Unindent(); ImGui::Separator(); // Led strips ImGui::TextWrapped("LED strips:"); ImGui::Indent(); for(int ls=0; ls<KM_CHLADNI_NUM_LED_STRIPS; ++ls){ ImGui::TextWrapped("LED strip #%d", ls); ImGui::Indent(); float intensityManu = chladniRC::getInstance().getLEDStripIntensityManu(ls); ImGui::SliderFloat((ofToString("LED strip ")+ofToString(ls)+" manu value").c_str(), &intensityManu, 0.f, 1.f); float intensityAuto = chladniRC::getInstance().getLEDStripIntensityAuto(ls); if(ImGui::SliderFloat((ofToString("LED strip ")+ofToString(ls)+" auto value").c_str(), &intensityAuto, 0.f, 1.f)){ chladniRC::getInstance().setLEDStripIntensityAuto(ls, intensityAuto); } ImGui::Unindent(); } ImGui::Unindent(); // Flowmeters ImGui::TextWrapped("Flow meters:"); ImGui::Indent(); for(int fm=0; fm<KM_CHLADNI_NUM_LED_STRIPS; ++fm){ ImGui::TextWrapped("Flow Meter %d", fm); float value = chladniRC::getInstance().getFlowMeterRate(fm); ImGui::SliderFloat("Flow rate", &value, 0.f, 1.f); } } ImGui::Unindent(); } ImGui::End(); }
//-------------------------------------------------------------- void ofApp::update(){ activePoses.clear(); bodies.clear(); kinect.update(); unsigned short * depthPixels = this->kinect.getDepthSource()->getPixels(); HRESULT hr = m_pCoordinateMapper->MapColorFrameToDepthSpace( 512 * 424, (const UINT16*)depthPixels, 1920 * 1080, m_pDepthCoordinates); // 1. create tracked bodies/joints array // THERE IS A MAXIMUM OF 6 BODIES TRACKED BY KINECT for (int i = 0; i<6; i++){ // IF THE BODY IS BEING TRACKED... if (this->kinect.getBodySource()->getBodies()[i].tracked){ auto b = this->kinect.getBodySource()->getBodies()[i]; map<JointType, ofxKFW2::Data::Joint>::iterator it; map<int, ofxKFW2::Data::Joint> jointsData; if (b.joints.find(JointType_SpineBase) != b.joints.end()) { if (b.joints.find(JointType_SpineBase)->second.getPosition().z <= maxDistance) { // ITERATE THROUGH ALL JOINTS IN THE TRACKED BODY... for (it = b.joints.begin(); it != b.joints.end(); ++it) { jointsData.insert( pair<int, ofxKFW2::Data::Joint>(it->first, it->second)); } bodies.push_back(jointsData); } } } } // 2. calculate angles for (vector< map<int, ofxKFW2::Data::Joint> >::iterator i = bodies.begin(); i != bodies.end(); i++) { int index = i - bodies.begin(); map<string, float> jointAngles; for (map<string, CalcParams>::iterator paramsIterator = jointCalcParams.begin(); paramsIterator != jointCalcParams.end(); paramsIterator++) { map<int, ofxKFW2::Data::Joint> b = *i; auto j1 = b.find(paramsIterator->second.j[0]); auto j2 = b.find(paramsIterator->second.j[1]); auto j3 = b.find(paramsIterator->second.j[2]); if ( checkTracking(j1, j2, j3, b) ) { float angle = calcAngle( j1, j2, j3 ); jointAngles.insert( pair<string, float>(paramsIterator->first, angle) ); } } jointAngleArray.push_back(jointAngles); // 3. check for poses // check for angles matching poses int activePose = -1; for (map<int, Pose>::iterator j = poses.begin(); j != poses.end(); j++) { Pose pose = j->second; float elTar = pose.ElbowLeft; float erTar = pose.ElbowRight; float zslTar = pose.zShoulderLeft; float zsrTar = pose.zShoulderRight; // get angles or if not found to -1 float elA = (jointAngles.find("elbowLeft") != jointAngles.end()) ? jointAngles.find("elbowLeft")->second : -1.0; float erA = (jointAngles.find("elbowRight") != jointAngles.end()) ? jointAngles.find("elbowRight")->second : -1.0; float zslA = (jointAngles.find("zShoulderLeft") != jointAngles.end()) ? jointAngles.find("zShoulderLeft")->second : -1.0; float zsrA = (jointAngles.find("zShoulderRight") != jointAngles.end()) ? jointAngles.find("zShoulderRight")->second : -1.0; float elDif = abs( elTar - elA ); float erDif = abs( erTar - erA ); float zslDif = abs( zslTar - zslA ); float zsrDif = abs( zsrTar - zsrA ); // tolerance value if ( elDif < tol && elA != -1.0 && erDif < tol && erA != -1.0 && zslDif < tol && zslA != -1.0 && zsrDif < 10.0 && zsrA != -1.0 ) { // sendOscMessage(97 + i->first); // cout << "pose " << j->first << endl; activePose = j->first; } else { // activePoses.push_back(-1.0); // cout << "pose -1" << endl; } } activePoses.push_back(activePose); } scanLineX = ofGetFrameNum() % ofGetWidth(); for (int i = 0; i < bodies.size(); i++) { if (bodies[i].find(JointType_SpineBase) != bodies[i].end() ) { ofVec2f pos = bodies[i].find(JointType_SpineBase)->second.getProjected(m_pCoordinateMapper); if (pos.x > scanLineX && pos.x < scanLineX + 1 ) { cout << "hitting body " << pos.x << endl; // cout << "active pose " << activePoses[i] << endl; if ( activePoses[i] > -1 ) { cout << "triggering: " << 97 + activePoses[i] << endl; sendOscMessage(97 + activePoses[i]); } else { // play 'fallback sound' } } } } // mesh = kinect.getDepthSource()->getMesh( // false, // ofxKinectForWindows2::Source::Depth::PointCloudOptions::TextureCoordinates::ColorCamera); }
//-------------------------------------------------------------- void ofApp::keyPressed(int key){ if (key = 'h') { showGUI = !showGUI; } sendOscMessage(key); }