Skip to content

Commit

Permalink
Merge pull request openframeworks#3011 from openframeworks/osc-blob-s…
Browse files Browse the repository at this point in the history
…upport

blob support for ofxOsc.
  • Loading branch information
ofTheo committed Jun 6, 2014
2 parents 88c34cb + 3f60774 commit 2bfcd0e
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 14 deletions.
2 changes: 1 addition & 1 deletion addons/ofxOsc/libs/oscpack/src/ip/UdpSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class UdpSocket{
void Bind( const IpEndpointName& localEndpoint );
bool IsBound() const;

int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size );
};


Expand Down
18 changes: 16 additions & 2 deletions addons/ofxOsc/libs/oscpack/src/ip/posix/UdpSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
typedef ssize_t socklen_t;
#endif

static int MAX_BUFFER_SIZE = 292000;

static void SockaddrFromIpEndpointName( struct sockaddr_in& sockAddr, const IpEndpointName& endpoint )
{
Expand Down Expand Up @@ -121,7 +122,21 @@ class UdpSocket::Implementation{
int reusePort = 1; // int on posix
setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &reusePort, sizeof(reusePort));
#endif


// lets increase the size of the buffer if possible.
int maxBufferSize = 0;
socklen_t optlen = sizeof(maxBufferSize);
int res = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, &maxBufferSize, &optlen);

if( maxBufferSize < MAX_BUFFER_SIZE ){
maxBufferSize = MAX_BUFFER_SIZE;
setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, &maxBufferSize, sizeof(maxBufferSize));
setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, &maxBufferSize, sizeof(maxBufferSize));
}else{
//if we are natively supporting a larger buffer size then increase our value;
MAX_BUFFER_SIZE = maxBufferSize;
}

memset( &sendToAddr_, 0, sizeof(sendToAddr_) );
sendToAddr_.sin_family = AF_INET;
}
Expand Down Expand Up @@ -415,7 +430,6 @@ class SocketReceiveMultiplexer::Implementation{
timerQueue_.push_back( std::make_pair( currentTimeMs + i->initialDelayMs, *i ) );
std::sort( timerQueue_.begin(), timerQueue_.end(), CompareScheduledTimerCalls );

const int MAX_BUFFER_SIZE = 4098;
char *data = new char[ MAX_BUFFER_SIZE ];
IpEndpointName remoteEndpoint;

Expand Down
23 changes: 22 additions & 1 deletion addons/ofxOsc/src/ofxOscArg.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@

#pragma once

#include "ofConstants.h"
#include <string>
#include "ofMain.h"

typedef enum _ofxOscArgType
{
Expand Down Expand Up @@ -145,3 +145,24 @@ class ofxOscArgString : public ofxOscArg
private:
std::string value;
};

class ofxOscArgBlob : public ofxOscArg
{
public:
ofxOscArgBlob( ofBuffer _value ){
value = _value;
}
~ofxOscArgBlob(){};

/// return the type of this argument
ofxOscArgType getType() { return OFXOSC_TYPE_BLOB; }
string getTypeName() { return "blob"; }

/// return value
ofBuffer get() const { return value; }
/// set value
void set( const char * _value, unsigned int length ) { value.set(_value, length); }

private:
ofBuffer value;
};
17 changes: 17 additions & 0 deletions addons/ofxOsc/src/ofxOscMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,17 @@ string ofxOscMessage::getArgAsString( int index ) const
return ((ofxOscArgString*)args[index])->get();
}

ofBuffer ofxOscMessage::getArgAsBlob( int index ) const
{
if ( getArgType(index) != OFXOSC_TYPE_BLOB )
{
ofLogError("ofxOscMessage") << "getArgAsBlob(): argument " << index << " is not a blob";
return ofBuffer();
}
else
return ((ofxOscArgBlob*)args[index])->get();
}



/*
Expand Down Expand Up @@ -202,6 +213,10 @@ void ofxOscMessage::addStringArg( string argument )
args.push_back( new ofxOscArgString( argument ) );
}

void ofxOscMessage::addBlobArg( ofBuffer argument )
{
args.push_back( new ofxOscArgBlob( argument ) );
}

/*
Expand Down Expand Up @@ -230,6 +245,8 @@ ofxOscMessage& ofxOscMessage::copy( const ofxOscMessage& other )
args.push_back( new ofxOscArgFloat( other.getArgAsFloat( i ) ) );
else if ( argType == OFXOSC_TYPE_STRING )
args.push_back( new ofxOscArgString( other.getArgAsString( i ) ) );
else if ( argType == OFXOSC_TYPE_BLOB )
args.push_back( new ofxOscArgBlob( other.getArgAsBlob( i ) ) );
else
{
assert( false && "bad argument type" );
Expand Down
3 changes: 2 additions & 1 deletion addons/ofxOsc/src/ofxOscMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class ofxOscMessage
uint64_t getArgAsInt64( int index ) const;
float getArgAsFloat( int index ) const;
string getArgAsString( int index ) const;
ofBuffer getArgAsBlob( int index ) const;

/// message construction
void setAddress( string _address ) { address = _address; };
Expand All @@ -80,7 +81,7 @@ class ofxOscMessage
void addInt64Arg( uint64_t argument );
void addFloatArg( float argument );
void addStringArg( string argument );

void addBlobArg( ofBuffer argument );

private:

Expand Down
12 changes: 10 additions & 2 deletions addons/ofxOsc/src/ofxOscReceiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ ofxOscReceiver::startThread( void* receiverInstance )

void ofxOscReceiver::ProcessMessage( const osc::ReceivedMessage &m, const IpEndpointName& remoteEndpoint )
{

// convert the message to an ofxOscMessage
ofxOscMessage* ofMessage = new ofxOscMessage();

// set the address
ofMessage->setAddress( m.AddressPattern() );

// set the sender ip/host
char endpoint_host[ IpEndpointName::ADDRESS_STRING_LENGTH ];
remoteEndpoint.AddressAsString( endpoint_host );
Expand All @@ -156,7 +157,13 @@ void ofxOscReceiver::ProcessMessage( const osc::ReceivedMessage &m, const IpEndp
ofMessage->addFloatArg( arg->AsFloatUnchecked() );
else if ( arg->IsString() )
ofMessage->addStringArg( arg->AsStringUnchecked() );
else
else if ( arg->IsBlob() ){
const char * dataPtr;
unsigned long len = 0;
arg->AsBlobUnchecked((const void*&)dataPtr, len);
ofBuffer buffer(dataPtr, len);
ofMessage->addBlobArg( buffer );
}else
{
ofLogError("ofxOscReceiver") << "ProcessMessage: argument in message " << m.AddressPattern() << " is not an int, float, or string";
}
Expand Down Expand Up @@ -224,6 +231,7 @@ bool ofxOscReceiver::getNextMessage( ofxOscMessage* message )
return true;
}


bool ofxOscReceiver::getParameter(ofAbstractParameter & parameter){
ofxOscMessage msg;
if ( messages.size() == 0 ) return false;
Expand Down
16 changes: 12 additions & 4 deletions addons/ofxOsc/src/ofxOscSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ void ofxOscSender::shutdown()

void ofxOscSender::sendBundle( ofxOscBundle& bundle )
{
static const int OUTPUT_BUFFER_SIZE = 32768;
//setting this much larger as it gets trimmed down to the size its using before being sent.
//TODO: much better if we could make this dynamic? Maybe have ofxOscBundle return its size?
static const int OUTPUT_BUFFER_SIZE = 327680;
char buffer[OUTPUT_BUFFER_SIZE];
osc::OutboundPacketStream p(buffer, OUTPUT_BUFFER_SIZE );

Expand All @@ -76,15 +78,17 @@ void ofxOscSender::sendBundle( ofxOscBundle& bundle )

void ofxOscSender::sendMessage( ofxOscMessage& message )
{
static const int OUTPUT_BUFFER_SIZE = 16384;
//setting this much larger as it gets trimmed down to the size its using before being sent.
//TODO: much better if we could make this dynamic? Maybe have ofxOscMessage return its size?
static const int OUTPUT_BUFFER_SIZE = 327680;
char buffer[OUTPUT_BUFFER_SIZE];
osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );

// serialise the message
p << osc::BeginBundleImmediate;
appendMessage( message, p );
p << osc::EndBundle;

socket->Send( p.Data(), p.Size() );
}

Expand Down Expand Up @@ -174,7 +178,11 @@ void ofxOscSender::appendMessage( ofxOscMessage& message, osc::OutboundPacketStr
p << message.getArgAsFloat( i );
else if ( message.getArgType( i ) == OFXOSC_TYPE_STRING )
p << message.getArgAsString( i ).c_str();
else
else if ( message.getArgType( i ) == OFXOSC_TYPE_BLOB ){
ofBuffer buff = message.getArgAsBlob(i);
osc::Blob b(buff.getBinaryBuffer(), (unsigned long)buff.size());
p << b;
}else
{
ofLogError("ofxOscSender") << "appendMessage(): bad argument type " << message.getArgType( i );
assert( false );
Expand Down
12 changes: 11 additions & 1 deletion examples/addons/oscReceiveExample/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void ofApp::update(){
// get the next message
ofxOscMessage m;
receiver.getNextMessage(&m);

// check for mouse moved message
if(m.getAddress() == "/mouse/position"){
// both the arguments are int32's
Expand All @@ -42,6 +42,11 @@ void ofApp::update(){
// the single argument is a string
mouseButtonState = m.getArgAsString(0);
}
// check for an image being sent (note: the size of the image depends greatly on your network buffer sizes - if an image is too big the message won't come through )
else if(m.getAddress() == "/image" ){
ofBuffer buffer = m.getArgAsBlob(0);
receivedImage.loadImage(buffer);
}
else{
// unrecognized message: display on the bottom of the screen
string msg_string;
Expand Down Expand Up @@ -83,6 +88,11 @@ void ofApp::draw(){
string buf;
buf = "listening for osc messages on port" + ofToString(PORT);
ofDrawBitmapString(buf, 10, 20);

if(receivedImage.getWidth() > 0){
ofDrawBitmapString("Image:", 10, 160);
receivedImage.draw(10, 180);
}

// draw mouse state
buf = "mouse: " + ofToString(mouseX, 4) + " " + ofToString(mouseY, 4);
Expand Down
2 changes: 2 additions & 0 deletions examples/addons/oscReceiveExample/src/ofApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ class ofApp : public ofBaseApp {

int mouseX, mouseY;
string mouseButtonState;

ofImage receivedImage;
};
25 changes: 24 additions & 1 deletion examples/addons/oscSenderExample/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ void ofApp::setup(){

// open an outgoing connection to HOST:PORT
sender.setup(HOST, PORT);

imgAsBuffer = ofBufferFromFile("sendImageTest.jpg", true);

}

//--------------------------------------------------------------
Expand All @@ -16,13 +19,21 @@ void ofApp::update(){

//--------------------------------------------------------------
void ofApp::draw(){

if(img.getWidth() > 0){
ofDrawBitmapString("Image:", 10, 160);
img.draw(10, 180);
}

// display instructions
string buf;
buf = "sending osc messages to" + string(HOST) + ofToString(PORT);
ofDrawBitmapString(buf, 10, 20);
ofDrawBitmapString("move the mouse to send osc message [/mouse/position <x> <y>]", 10, 50);
ofDrawBitmapString("click to send osc message [/mouse/button <button> <\"up\"|\"down\">]", 10, 65);
ofDrawBitmapString("press A to send osc message [/test 1 3.5 hello <time>]", 10, 80);
ofDrawBitmapString("press I to send a (small) image as a osc blob to [/image]", 10, 95);

}

//--------------------------------------------------------------
Expand All @@ -36,6 +47,18 @@ void ofApp::keyPressed(int key){
m.addFloatArg(ofGetElapsedTimef());
sender.sendMessage(m);
}

//send an image. (Note: the size of the image depends greatly on your network buffer sizes - if an image is too big the message won't come through )

if( key == 'i' || key == 'I'){
img.loadImage(imgAsBuffer);

ofxOscMessage m;
m.setAddress("/image");
m.addBlobArg(imgAsBuffer);
sender.sendMessage(m);
cout << "ofApp:: sending image with size: " << imgAsBuffer.size() << endl;
}
}

//--------------------------------------------------------------
Expand Down Expand Up @@ -86,6 +109,6 @@ void ofApp::gotMessage(ofMessage msg){

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}

3 changes: 2 additions & 1 deletion examples/addons/oscSenderExample/src/ofApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class ofApp : public ofBaseApp {

ofTrueTypeFont font;
ofxOscSender sender;

ofBuffer imgAsBuffer;
ofImage img;
};

0 comments on commit 2bfcd0e

Please sign in to comment.