Created
September 23, 2011 00:32
-
-
Save satoruhiga/1236458 to your computer and use it in GitHub Desktop.
ofxRecordableOscReceiver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "ofMain.h" | |
#include "ofxOsc.h" | |
#define OFX_RECOSC_SAVE_XML | |
#ifdef OFX_RECOSC_SAVE_XML | |
#include "ofxXmlSettings.h" | |
#endif | |
/* | |
#include "testApp.h" | |
#include "ofxRecordableOscReceiver.h" | |
ofxRecordableOscReceiver receiver; | |
float rotX = 0; | |
float rotY = 0; | |
void testApp::setup() | |
{ | |
ofSetFrameRate(60); | |
ofSetVerticalSync(true); | |
receiver.setup(9001); | |
} | |
void testApp::update() | |
{ | |
// same interface with ofxOscReceiver | |
while (receiver.hasWaitingMessages()) { | |
ofxOscMessage m; | |
receiver.getNextMessage(&m); | |
if (m.getAddress() == "/rot") | |
{ | |
rotX = m.getArgAsFloat(0); | |
rotY = m.getArgAsFloat(1); | |
} | |
} | |
} | |
void testApp::draw() | |
{ | |
glTranslatef(ofGetWidth()/2, ofGetHeight()/2, 0); | |
glRotatef(rotY, 1, 0, 0); | |
glRotatef(rotX, 0, 1, 0); | |
ofNoFill(); | |
ofBox(0, 0, 0, 200); | |
} | |
void testApp::keyPressed(int key) | |
{ | |
if (key == 's') | |
{ | |
receiver.save(); | |
} | |
else if (key == 'l') | |
{ | |
receiver.load(); | |
} | |
} | |
*/ | |
/* | |
maxpat | |
----------begin_max5_patcher---------- | |
942.3oc0YtsaaBCFG+5jmBKTuZJqEehC6t8bLUMQ.2TVIXD3nltp9tOiMjl1 | |
lTLAGuzarEFpye98cx70mmOyaIeKqwC7Cvu.yl877YyTK0tvrtqm4sNYaZQR | |
i5w7R4qWyJEdKz2Sv1JTqWyR40Yfa.UEIOsLI8g9m3NdonI+ur1mBht1ua4x | |
MqyKKXB0tB6VrJQjded4peK2MgVUPHU92.Hj1QH0ucBIGA295Fw2H52o9sOO | |
SoJ9x+78.39RoLYsRJd+rNOovq8FuLed6vBCIPI6Q419A.TvSxVyZZ.694zx | |
R7TES+p34sSzSDJHjhFjn1oPz.LA9QlPicBSZXE.Hv+n.YYR4JuEuNaM.AgZ | |
BgUSjfAHD9.DJxtDRvWspfcTRjKCo1Wbi4sT6.Pw8iivMH7TdUZ8xSVw9f09 | |
JHf56e5d+U0rFYpkDQNubu2x.+tXekUzua3vvBcbXQvwpsIPsMjP0EQihVD2 | |
jHIujIeCONGWLcVFFNLKwCyxnPiBuPGfkT6xxykOoodW3H3D8tHgec7tL0Oo | |
mJmteBg5Dpv1VUCtJGJO+BDEdM3a.bf8yjQ6vQLZ3nO3vQeDcMNXz3q+SHeE | |
wpo.p2sC4e5.BaW.UkmJZJxyX0e5Q.V7YmDvjzOpQe+cSiHRCYQCeUxCfap4 | |
Bo+8mlrwxIZPX0GKnqtMNCNNxMEjtIsfkTa8TKD8oiPD7jNjD1GqyPo+nK+w | |
WFCG5HN1H3UVGiXcpUDMZRXD4qCDiUS3S3z.3.6hw6J3xeyixK4sSD69RrSs | |
7FR6CBisQ4MDTERO3W7efTYXxEL7FYQrofAriBEqYOlWlY+bZA5B2jo8geHc | |
aR5BFIwiOXD8erW.GgMHbm2AYRwZcMRJjz6cM1xln.q5IUv4UfqfV2UpKmDh | |
BmlqjFWwQu1vkQ5I4ppiscg09UGiCsQ.ILfre0wfS.iTmkYqsq1m+1Gz2uRM | |
f6RXMNj3ltbuIqR5YjAJ3oIE2yaDfXeenk50OR2cJjlBPb33a1ugTPsgpdg7 | |
t+4GJU0t9aQSCeScZuUuuA5fW0UFqQjWphW16gjIG2+gtOOKiUtuvWmmUwko | |
66DA31CZnLVSxxT.3PZh5dMMHmftUSgFno2I7ytlnFno1y05PMQHlvI2pIpQ | |
Zxs93DircX2pIrAZhD5VMYRbGww1NjA4LID2qoA4ja8mvl3OgeaAnytlHlpI | |
j6zjI06ba4Nb3kmjBt3jD5xyvgt7LbHSLbH2VVAQu7vD7LKI4EuL+evWkJJF | |
-----------end_max5_patcher----------- | |
*/ | |
class ofxRecordableOscReceiver | |
{ | |
typedef ofPtr<ofxOscMessage> ofxOscMessageRef; | |
typedef deque<ofxOscMessageRef> MessageList; | |
MessageList messageQueue; | |
ofxOscReceiver receiver; | |
bool recording, playback, looping; | |
unsigned int currentPlaybackFrame; | |
vector<MessageList> recordedMessages; | |
public: | |
ofxRecordableOscReceiver() | |
{ | |
currentPlaybackFrame = 0; | |
recording = playback = looping = false; | |
} | |
// ofxOscReceiver interface | |
void setup(int listen_port) | |
{ | |
receiver.setup(listen_port); | |
ofAddListener(ofEvents.update, this, &ofxRecordableOscReceiver::onUpdate); | |
} | |
bool hasWaitingMessages() | |
{ | |
return !messageQueue.empty(); | |
} | |
bool getNextMessage(ofxOscMessage* m) | |
{ | |
if (messageQueue.empty()) return false; | |
*m = *messageQueue.front(); | |
messageQueue.pop_front(); | |
return true; | |
} | |
// record & playback interface | |
void play() | |
{ | |
stop(); | |
playback = true; | |
rewind(); | |
} | |
void record() | |
{ | |
stop(); | |
recording = true; | |
clear(); | |
rewind(); | |
} | |
void stop() | |
{ | |
recording = false; | |
playback = false; | |
} | |
void rewind() | |
{ | |
currentPlaybackFrame = 0; | |
} | |
void clear() | |
{ | |
recordedMessages.clear(); | |
} | |
void loop(bool yn) | |
{ | |
looping = yn; | |
} | |
void seek(unsigned int head) | |
{ | |
currentPlaybackFrame = ofClamp(head, 0, recordedMessages.size()-1); | |
} | |
bool isRecording() const { return recording; } | |
bool isPlayback() const { return playback; } | |
void onUpdate(ofEventArgs&) | |
{ | |
messageQueue.clear(); | |
MessageList frameMessage; | |
while (receiver.hasWaitingMessages()) { | |
ofxOscMessage m; | |
receiver.getNextMessage(&m); | |
string addr = m.getAddress(); | |
if (addr == "/record") | |
{ | |
record(); | |
} | |
else if (addr == "/play") | |
{ | |
play(); | |
} | |
else if (addr == "/stop") | |
{ | |
stop(); | |
} | |
else if (addr == "/rewind") | |
{ | |
rewind(); | |
} | |
else if (addr == "/seek") | |
{ | |
seek(m.getArgAsInt32(0)); | |
} | |
else if (addr == "/clear") | |
{ | |
clear(); | |
} | |
else if (addr == "/loop") | |
{ | |
loop(m.getArgAsInt32(0)); | |
} | |
ofxOscMessage *mm = new ofxOscMessage(m); | |
frameMessage.push_back(ofxOscMessageRef(mm)); | |
} | |
if (playback) | |
{ | |
if (!recordedMessages.empty()) | |
{ | |
messageQueue = recordedMessages[currentPlaybackFrame]; | |
currentPlaybackFrame++; | |
if (looping) | |
{ | |
currentPlaybackFrame = currentPlaybackFrame % recordedMessages.size(); | |
} | |
else | |
{ | |
currentPlaybackFrame = ofClamp(currentPlaybackFrame, 0, recordedMessages.size()-1); | |
} | |
} | |
} | |
else | |
{ | |
messageQueue = frameMessage; | |
if (recording) | |
{ | |
recordedMessages.push_back(frameMessage); | |
} | |
} | |
} | |
#ifdef OFX_RECOSC_SAVE_XML | |
void save(string path = "") | |
{ | |
if (path == "") | |
{ | |
ofFileDialogResult res = ofSystemSaveDialog("recording.xml", ""); | |
path = res.getPath(); | |
} | |
ofFile f(path); | |
if (f.exists()) | |
{ | |
f.remove(false); | |
} | |
ofxXmlSettings xml(path); | |
xml.addTag("data"); | |
xml.pushTag("data"); | |
for (int i = 0; i < recordedMessages.size(); i++) | |
{ | |
MessageList &l = recordedMessages[i]; | |
if (!l.empty()) | |
{ | |
for (int k = 0; k < l.size(); k++) | |
{ | |
ofxOscMessage &m = *l[k]; | |
string path = m.getAddress(); | |
int tagid = xml.addTag("message"); | |
xml.setAttribute("message", "frame", i, tagid); | |
xml.setAttribute("message", "path", path, tagid); | |
xml.pushTag("message", tagid); | |
for (int j = 0; j < m.getNumArgs(); j++) | |
{ | |
switch (m.getArgType(j)) | |
{ | |
case OFXOSC_TYPE_INT32: | |
{ | |
int vid = xml.addValue("v", m.getArgAsInt32(j)); | |
xml.setAttribute("v", "t", "i", vid); | |
break; | |
} | |
case OFXOSC_TYPE_FLOAT: | |
{ | |
int vid = xml.addValue("v", m.getArgAsFloat(j)); | |
xml.setAttribute("v", "t", "f", vid); | |
break; | |
} | |
case OFXOSC_TYPE_STRING: | |
{ | |
int vid = xml.addValue("v", m.getArgAsString(j)); | |
xml.setAttribute("v", "t", "s", vid); | |
break; | |
} | |
} | |
} | |
xml.popTag(); | |
} | |
} | |
} | |
xml.popTag(); | |
xml.saveFile(); | |
} | |
void load(string path = "") | |
{ | |
if (path == "") | |
{ | |
ofFileDialogResult res = ofSystemLoadDialog(); | |
path = res.getPath(); | |
} | |
ofxXmlSettings xml(path); | |
xml.pushTag("data"); | |
int num_tags = xml.getNumTags("message"); | |
if (num_tags == 0) return; | |
int num_frames = xml.getAttribute("message", "frame", 0, num_tags-1); | |
recordedMessages.clear(); | |
recordedMessages.resize(num_frames + 30); // post roll | |
for (int i = 0; i < num_tags; i++) | |
{ | |
int frame = xml.getAttribute("message", "frame", 0, i); | |
string path = xml.getAttribute("message", "path", "", i); | |
ofxOscMessage *m = new ofxOscMessage(); | |
m->setAddress(path); | |
xml.pushTag("message", i); | |
int num_value = xml.getNumTags("v"); | |
for (int k = 0; k < num_value; k++) | |
{ | |
string t = xml.getAttribute("v", "t", "", k); | |
if (t == "i") | |
{ | |
m->addIntArg(xml.getValue("v", 0, k)); | |
} | |
else if (t == "f") | |
{ | |
m->addFloatArg(xml.getValue("v", 0.0, k)); | |
} | |
else if (t == "s") | |
{ | |
m->addStringArg(xml.getValue("v", "", k)); | |
} | |
} | |
xml.popTag(); | |
recordedMessages[frame].push_back(ofPtr<ofxOscMessage>(m)); | |
} | |
xml.popTag(); | |
} | |
#endif | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment