Adding OSC control interface

21 views
Skip to first unread message

Olaf

unread,
Jul 5, 2012, 10:49:32 AM7/5/12
to gst123
Hello Stefan,

I was needing a media player which is control-able by some OSC
messages and decided to add this functionality to gst123.

I.e. sending OSC messages of the form "/gst123 OSC_PAUSE" now toggle
the pause of gst123.
This extraction of my header file should declare the functionalities :

/* List of supported commands over osc interface.
* Command format: /gst123 [OSC_COMMAND] [Matching parameter… See
following list]
* The ()-values are the default values of optional arguments.
* The signature between the {}-brackets codes the parameter type.
* i - Integer value, f - float value, s - string value, b - boolean
value.
* */
enum OscCommand {
OSC_SET_VOLUME = 1, /* [volume] {f}, Range:[0,10]*/
OSC_INCREASE_VOLUME = 2, /* [dvol (0.1)] {f} */
OSC_DECREASE_VOLUME = 3, /* [dvol (0.1)] {f} */
OSC_MUTE = 4, /*[mute (toggle)] {b}. Mute or unmute. */
OSC_PAUSE = 10, /*[pause (toggle)] {b}. Pause or play. */
OSC_PLAY = 11, /* [track number (0)] {i}. Play entry of playlist */
OSC_FULLSCREEN = 20, /*[fullscreen (toggle)] {b}. */
OSC_RELATVE_SEEK = 30, /*[seconds(10.0)] {f}. */
OSC_SEEK = 31, /*[position in seconds] {f}. */
OSC_PLAY_NEXT = 32, /* No parameter. */
OSC_PLAY_PREVIOUS = 33, /* No parameter. */
OSC_ADD_TRACK = 40, /* [filename] [start play (false)] [position
(end)] {sbi} */
OSC_REMOVE_TRACK = 41, /* [go to next file (false)] [position
(current)] {bi} */
OSC_QUIT = 99, /* No parameter. */
};


Are you interested to get this back in your repository? (Maybe it is
not your intention to depart from mgp23.)
Or should I fork your project?


Regards Olaf

Olaf

unread,
Jul 8, 2012, 1:10:09 PM7/8/12
to gst123
For the sake of completeness here is my patch again the current master
branch (commit 3e46d2e501da68d929bb5f26900a292a5fc04a1f)

Regards Olaf

===================


diff --git a/configure.ac b/configure.ac
index 34ce41a..363c660 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,6 +106,19 @@ Debian users: aptitude install libncurses-dev
])

dnl
+dnl Define osc interface
+dnl
+AC_DEFUN([AC_OSCPACK_REQUIREMENTS],
+[
+ dnl We need oscpack
+ dnl PKG_CHECK_MODULES(OSCPACK, oscpack)
+ OSCPACK_CFLAGS="-I/usr/include/oscpack"
+ OSCPACK_LIBS="-loscpack"
+ AC_SUBST(OSCPACK_CFLAGS)
+ AC_SUBST(OSCPACK_LIBS)
+])
+
+dnl
dnl Manpage from wiki (required for --enable-maintainer-mode)
dnl
AC_DEFUN([AC_MAN_REQUIREMENTS],
@@ -139,6 +152,7 @@ AC_GSTREAMER_GTK_REQUIREMENTS
AC_X11_REQUIREMENTS
AC_NCURSES_REQUIREMENTS
AC_MAN_REQUIREMENTS
+AC_OSCPACK_REQUIREMENTS

MC_PROG_CC_SUPPORTS_OPTION([-Wall], [
CFLAGS="$CFLAGS -Wall"
diff --git a/src/Makefile.am b/src/Makefile.am
index c35da4b..22d00db 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,8 +4,13 @@ AM_CFLAGS = $(GSTREAMER_CFLAGS) $
(GSTREAMER_GTK_CFLAGS) $(NCURSES_CFLAGS)
bin_PROGRAMS = gst123

gst123_SOURCES = gst123.cc glib-extra.c glib-extra.h terminal.cc
terminal.h gtkinterface.h gtkinterface.cc keyhandler.h \
- options.cc options.h microconf.cc microconf.h
configfile.cc configfile.h \
+ options.cc options.h microconf.cc microconf.h configfile.cc
configfile.h \
uri.cc playlist.cc m3uparser.cc plsparser.cc uri.h playlist.h
m3uparser.h plsparser.h \
iostream.cc iostream.h networkstream.cc filestream.cc
consolestream.cc \
- httpstream.cc visualization.h visualization.cc msg.h msg.cc
typefinder.h typefinder.cc
-gst123_LDADD = $(GSTREAMER_LIBS) $(GSTREAMER_GTK_LIBS) $
(NCURSES_LIBS)
+ httpstream.cc visualization.h visualization.cc msg.h msg.cc
typefinder.h typefinder.cc \
+ osc.h oschandler.h osceventsource.h osceventsource.cc
+gst123_LDADD = $(GSTREAMER_LIBS) $(GSTREAMER_GTK_LIBS) $
(NCURSES_LIBS) $(OSCPACK_LIBS)
+
+INCLUDES = @OSCPACK_CFLAGS@
+oscpack_LDADD = @OSCPACK_LIBS@
+
diff --git a/src/gst123.cc b/src/gst123.cc
index ce5876d..7b4bfac 100644
--- a/src/gst123.cc
+++ b/src/gst123.cc
@@ -41,6 +41,12 @@
#include <list>
#include <iostream>

+#include <cstring>
+#include "osc.h"
+#include "oschandler.h"
+#include "osceventsource.h"
+
+
using std::string;
using std::vector;
using std::list;
@@ -106,7 +112,7 @@ force_aspect_ratio (gpointer element, gpointer
userdata)

struct Options options;

-struct Player : public KeyHandler
+struct Player : public KeyHandler, public OscHandler
{
vector<string> uris;

@@ -121,6 +127,8 @@ struct Player : public KeyHandler
gint video_size_width;
gint video_size_height;

+ GAsyncQueue *osc_queue;
+
enum
{
KEEP_CODEC_TAGS,
@@ -141,15 +149,18 @@ struct Player : public KeyHandler
}

void
- add_uri (string uri)
+ add_uri (string uri, int pos)
{
+ pos = (pos<0)?uris.size():(pos<(int)uris.size())?pos:uris.size();
+
if (uri.find (":/") == uri.npos)
- {
- if (!g_path_is_absolute (uri.c_str()))
- uri = g_get_current_dir() + string (G_DIR_SEPARATOR + uri);
- uri = "file://" + uri;
- }
- uris.push_back (uri);
+ {
+ if (!g_path_is_absolute (uri.c_str()))
+ uri = g_get_current_dir() + string (G_DIR_SEPARATOR + uri);
+ uri = "file://" + uri;
+ }
+
+ uris.insert(uris.begin()+pos,uri);
}

string
@@ -205,12 +216,25 @@ struct Player : public KeyHandler
void
remove_current_uri()
{
- assert (play_position > 0);
+ if( play_position <= 0 ){
+ printf("There is no file to remove.\n");
+ return;
+ }
+ //assert (play_position > 0);

play_position--;
uris.erase (uris.begin() + play_position);
}

+ void
+ remove_uri(guint position)
+ {
+ if( position < 0 || position >= uris.size() ) return;
+ if( play_position > position ) play_position--;
+ uris.erase (uris.begin() + position);
+
+ }
+
bool
is_image_file (const string& uri)
{
@@ -228,7 +252,21 @@ struct Player : public KeyHandler
return false;
}

-
+ /* Play file of playlist on position pos
+ * Disable shuffle option to avoid
+ * reshuffling for pos=0.
+ * */
+ void
+ play_track_on_position(int pos){
+ if( pos >= (int)uris.size() ) pos=uris.size()-1;
+ if( pos < 0 ) pos =uris.size()-1 ;
+ play_position = pos;
+
+ bool s = options.shuffle;
+ options.shuffle = false;
+ play_next();
+ options.shuffle = s;
+ }
void
play_next()
{
@@ -243,14 +281,18 @@ struct Player : public KeyHandler

for (;;)
{
- if (play_position == uris.size() && options.repeat)
+ if (play_position >= uris.size())
{
if (uris.empty())
{
Msg::print ("No files remaining in playlist.\n");
- quit();
+ if( !options.daemon )
+ quit();
+ else
+ return;
}
- play_position = 0;
+ if( options.repeat)
+ play_position = 0;
}
if (options.shuffle && play_position == 0)
{
@@ -264,7 +306,6 @@ struct Player : public KeyHandler
if (play_position < uris.size())
{
string uri = uris[play_position++];
-
overwrite_time_display();

if (is_image_file (uri))
@@ -277,7 +318,7 @@ struct Player : public KeyHandler
{
Msg::print ("\nPlaying %s\n", uri.c_str());

- gtk_interface.set_title (g_basename (uri.c_str()));
+ gtk_interface.set_title (g_path_get_basename
(uri.c_str()));

video_size_width = 0;
video_size_height = 0;
@@ -291,7 +332,8 @@ struct Player : public KeyHandler
}
else
{
- quit();
+ if( !options.daemon )
+ quit();
return; // -> done
}
}
@@ -345,8 +387,21 @@ struct Player : public KeyHandler
}
}

+ /* Set absolute volume. */
void
- set_volume (gdouble volume_change)
+ set_volume (gdouble volume)
+ {
+ //check boundaries
+ volume = 0>volume?0:(volume<10?volume:10);
+
+ overwrite_time_display();
+ Msg::print ("Volume: %4.1f%% \n", volume*100);
+ g_object_set (G_OBJECT (playbin), "volume", volume, NULL);
+ }
+
+ /* Old set_volume. RENAMED!! */
+ void
+ relative_set_volume (gdouble volume_change)
{
gdouble cur_volume;
g_object_get (G_OBJECT (playbin), "volume", &cur_volume, NULL);
@@ -392,15 +447,98 @@ struct Player : public KeyHandler
}

void process_input (int key);
+ void process_osc ();
void print_keyboard_help();
- void add_uri_or_directory (const string& name);
+ void add_uri_or_directory (const string& name, int pos);

Player() : playbin (0), loop(0), play_position (0)
{
cols = get_columns();
+ osc_queue = g_async_queue_new();
}
+ ~Player(){
+ // delete pending osc messages and clear reference
+ OscMessage *om;
+ while( (om=(OscMessage*)g_async_queue_try_pop(osc_queue)) != NULL )
{
+ delete om;
+ }
+ g_async_queue_unref(osc_queue);
+ }
+};
+
+class GstOscPacketListener : public osc::OscPacketListener {
+ protected:
+
+ virtual void ProcessMessage( const osc::ReceivedMessage& m,
+ const IpEndpointName& remoteEndpoint )
+ {
+ //put data into queue if address pattern match
+ if( std::strcmp( m.AddressPattern(), "/gst123" ) == 0 ){
+ OscMessage *om = new OscMessage(&m);
+ g_async_queue_push(player->osc_queue, om );
+ //player->process_osc();//this will called in main loop
+ }
+ }
+ Player *player;
+ public:
+ GstOscPacketListener( Player *_player ){
+ player = _player;
+ }
+};
+
+static gpointer
+osc_thread_func (gpointer _data)
+{
+ UdpListeningReceiveSocket *s = (UdpListeningReceiveSocket*) _data;
+ s->Run();
+ return NULL;
+}
+
+struct Osc{
+ OscEventSource *osc_event;
+ GstOscPacketListener *listener;
+ UdpListeningReceiveSocket *s;
+ GThread *osc_thread;
+
+ Osc():osc_event(NULL), listener(NULL), s(NULL), osc_thread(NULL){
+ }
+
+ void init(Player *_player, gint port=7000){
+ listener = new GstOscPacketListener(_player);
+ s = new UdpListeningReceiveSocket(
+ IpEndpointName( IpEndpointName::ANY_ADDRESS, port ),
+ listener);
+ osc_event = new OscEventSource();
+ osc_event->init (_player->loop, _player);
+
+ //start thread;
+ osc_thread = g_thread_new("osc", osc_thread_func, (gpointer*)s);
+ }
+
+ void end(){
+ if( osc_event != NULL ){
+ osc_event->end();
+ // end and join thread
+ s->AsynchronousBreak();
+ g_thread_join(osc_thread);
+
+ delete osc_event;
+ osc_event = NULL;
+ }
+
+ delete s;
+ s = NULL;
+ delete listener;
+ listener = NULL;
+ }
+
+ ~Osc(){
+ end();
+ }
+
};

+
static void
collect_tags (const GstTagList *tag_list,
const gchar *tag,
@@ -717,10 +855,10 @@ Player::process_input (int key)
toggle_pause();
break;
case '+':
- set_volume (0.1);
+ relative_set_volume (0.1);
break;
case '-':
- set_volume (-0.1);
+ relative_set_volume (-0.1);
break;
case 'M':
case 'm':
@@ -743,6 +881,130 @@ Player::process_input (int key)
}
}

+/*
+ * Handle osc messages.
+ * */
+void
+Player::process_osc(){
+ //get pending osc messages
+ OscMessage *om;
+ while( (om=(OscMessage*)g_async_queue_try_pop(osc_queue)) != NULL ){
+ if( options.verbose ) om->print();
+ //check if first argument is int value and switch command
+ OscArg *cmd = *om->args;
+ OscArg *arg1=NULL, *arg2=NULL, *arg3=NULL;
+ if( om->length>1) arg1 = *(om->args+1);
+ if( om->length>2) arg2 = *(om->args+2);
+ if( om->length>3) arg3 = *(om->args+3);
+
+ if (om->length < 1 || cmd->type != OSC_INT){
+ delete om;
+ continue;
+ }
+ switch( cmd->intval ){
+ case OSC_SET_VOLUME:
+ set_volume( arg1->floatval );
+ break;
+ case OSC_INCREASE_VOLUME:
+ if( om->length>1 && arg1->type == OSC_FLOAT )
+ relative_set_volume(arg1->floatval);
+ else
+ relative_set_volume(0.1);
+ break;
+ case OSC_DECREASE_VOLUME:
+ if( om->length>1 && arg1->type == OSC_FLOAT )
+ relative_set_volume(-arg1->floatval);
+ else
+ relative_set_volume(-0.1);
+ break;
+ case OSC_MUTE:
+ gboolean mute;
+ g_object_get (G_OBJECT (playbin), "mute", &mute, NULL);
+
+ gboolean mute2;
+ if(om->length>1)
+ mute2 = arg1->intval?true:false;
+ else
+ mute2 = !mute;
+ g_object_set (G_OBJECT (playbin), "mute", mute^mute2, NULL);
+ break;
+ case OSC_PAUSE:
+ if( om->length<2 )
+ toggle_pause();
+ else if( arg1->intval )
+ gst_element_set_state (playbin, GST_STATE_PAUSED);
+ else
+ gst_element_set_state (playbin, GST_STATE_PLAYING);
+ break;
+ case OSC_QUIT:
+ quit();
+ break;
+ case OSC_FULLSCREEN:
+ if( om->length<2 )
+ toggle_fullscreen();
+ else{
+ normal_size();
+ if( arg1->intval ) toggle_fullscreen();
+ }
+ break;
+ case OSC_RELATVE_SEEK:
+ printf("Length: %i\n", om->length);
+ if( om->length<2 )
+ relative_seek (10.0);
+ else if( arg1->type == OSC_FLOAT )
+ relative_seek ( arg1->floatval );
+ else if( arg1->type == OSC_INT )
+ relative_seek ( arg1->intval );
+ else
+ relative_seek (10.0);
+ break;
+ case OSC_SEEK:
+ if( om->length>1 && arg1->type == OSC_FLOAT )
+ seek( (gint64) (arg1->floatval * GST_SECOND) );
+ else if( om->length>1 && arg1->type == OSC_INT )
+ seek( (gint64) (arg1->intval * GST_SECOND) );
+ break;
+ case OSC_PLAY:
+ if( om->length>1 && arg1->type == OSC_INT )
+ play_track_on_position( arg1->intval );
+ else
+ play_track_on_position( 0 );
+ break;
+ case OSC_PLAY_NEXT:
+ play_next();
+ break;
+ case OSC_PLAY_PREVIOUS:
+ play_track_on_position(play_position-2);
+ break;
+ case OSC_ADD_TRACK:
+ if( om->length>1 && arg1->type == OSC_STRING ){
+ string s( arg1->charval );
+ int pos;
+ if( om->length>3 ) pos = arg3->intval;
+ else pos = -1;
+ add_uri_or_directory( s, pos );
+ //start playing of added file if second argument true.
+ if( om->length>2 && arg2->intval>0 )
+ play_track_on_position( pos );
+ }
+ break;
+ case OSC_REMOVE_TRACK:
+ if( om->length>2 ){
+ if ( arg1->intval && (int)play_position == arg2->intval+1 )
+ play_next();
+ remove_uri(arg2->intval);
+ }else{
+ remove_current_uri();
+ if ( om->length>1 && arg1->intval )
+ play_track_on_position(play_position);
+ }
+ break;
+
+ }
+ delete om;
+ }
+}
+
void
Player::print_keyboard_help()
{
@@ -766,20 +1028,22 @@ Player::print_keyboard_help()
}

void
-Player::add_uri_or_directory (const string& name)
+Player::add_uri_or_directory (const string& name, int pos=-1)
{
+ if(pos<0) pos = (int) uris.size();
if (is_directory (name)) // => play all files in this dir
{
vector<string> uris = crawl (name);
for (vector<string>::const_iterator ui = uris.begin(); ui !=
uris.end(); ui++)
- add_uri (*ui);
+ add_uri (*ui, pos++);
}
else
{
- add_uri (name);
+ add_uri (name, pos);
}
}

+
gint
main (gint argc,
gchar *argv[])
@@ -792,6 +1056,9 @@ main (gint argc,

options.parse (argc, argv);

+ /* Osc object require init call. */
+ Osc osc;
+
/* init GStreamer */
gst_init (&argc, &argv);
gtk_interface.init (&argc, &argv, &player);
@@ -885,6 +1152,12 @@ main (gint argc,
g_object_set (G_OBJECT (player.playbin), "audio-sink",
audio_sink, NULL);
}
}
+ if (options.oscport)
+ {
+ if( options.verbose )
+ Msg::print("Listen for OSC messages on port %i.\n",
options.oscport);
+ osc.init(&player, options.oscport);
+ }
gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE
(player.playbin)), my_bus_callback, &player);
g_timeout_add (130, (GSourceFunc) cb_print_position, &player);
signal (SIGINT, sigint_handler);
@@ -898,6 +1171,10 @@ main (gint argc,
gtk_interface.end();

/* also clean up */
+ if (options.oscport)
+ {
+ osc.end();
+ }
gst_element_set_state (player.playbin, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (player.playbin));

diff --git a/src/options.cc b/src/options.cc
index 4888f06..9b49f93 100644
--- a/src/options.cc
+++ b/src/options.cc
@@ -43,10 +43,12 @@ Options::Options ()
verbose = FALSE;
novideo = FALSE;
quiet = FALSE;
+ daemon = FALSE;
uris = NULL;
audio_output = NULL;
print_visualization_list = FALSE;
visualization = NULL;
+ oscport = 0;

string default_audio_output = ConfigFile::the().audio_output();
if (default_audio_output != "")
@@ -88,6 +90,10 @@ Options::parse (int argc, char **argv)
"show available visualization plugins", NULL },
{"quiet", 'q', 0, G_OPTION_ARG_NONE, &instance->quiet,
"don't display any messages", NULL},
+ {"osc", 'p', 0, G_OPTION_ARG_INT, &instance->oscport,
+ "Listen to osc control commands on port <port>.", "<port>"},
+ {"daemon", 'd', 0, G_OPTION_ARG_NONE, &instance->daemon,
+ "Do not quit program after playing and wait. Useful in
combination with osc or http interface.", NULL},
{G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY,
&instance->uris, "Movies to play", NULL},
{NULL} /* end the list */
};
diff --git a/src/options.h b/src/options.h
index 2b87221..402f447 100644
--- a/src/options.h
+++ b/src/options.h
@@ -42,10 +42,12 @@ public:
gboolean novideo;
gboolean print_visualization_list;
gboolean quiet;
+ gboolean daemon; /* No automatic quit() calls. */
char **uris;
std::list<std::string> playlists;
char *audio_output;
char *visualization;
+ gint oscport;

Options ();
void parse (int argc, char **argv);
diff --git a/src/osc.h b/src/osc.h
new file mode 100644
index 0000000..921864a
--- /dev/null
+++ b/src/osc.h
@@ -0,0 +1,151 @@
+/* GST123 - GStreamer based command line media player
+ * Copyright (C) 2012 Olaf Schulz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GST123_OSC_H
+#define GST123_OSC_H
+/*
+ * Struct for OSC messages.
+ *
+ * */
+
+#include <glib.h>
+#include <glib/gprintf.h>
+
+//osc stuff
+#include "ip/UdpSocket.h"
+#include "osc/OscReceivedElements.h"
+#include "osc/OscPacketListener.h"
+
+//using namespace Gst123;
+
+/* List of supported commands over osc interface.
+ * Command format: /gst123 [OSC_COMMAND] [Matching parameter… See
following list]
+ * The ()-values are the default values of optional arguments.
+ * The signature between the {}-brackets codes the parameter type.
+ * i - Integer value, f - float value, s - string value, b - boolean
value.
+ * */
+enum OscCommand {
+ OSC_SET_VOLUME = 1, /* [volume] {f}, Range:[0,10]*/
+ OSC_INCREASE_VOLUME = 2, /* [dvol (0.1)] {f} */
+ OSC_DECREASE_VOLUME = 3, /* [dvol (0.1)] {f} */
+ OSC_MUTE = 4, /*[mute (toggle)] {b}. Mute or unmute. */
+ OSC_PAUSE = 10, /*[pause (toggle)] {b}. Pause or play. */
+ OSC_PLAY = 11, /* [track number (0)] {i}. Play entry of playlist */
+ OSC_FULLSCREEN = 20, /*[fullscreen (toggle)] {b}. */
+ OSC_RELATVE_SEEK = 30, /*[seconds(10.0)] {f}. */
+ OSC_SEEK = 31, /*[position in seconds] {f}. */
+ OSC_PLAY_NEXT = 32, /* No parameter. */
+ OSC_PLAY_PREVIOUS = 33, /* No parameter. */
+ OSC_ADD_TRACK = 40, /* [filename] [start play (false)] [position
(end)] {sbi} */
+ OSC_REMOVE_TRACK = 41, /* [go to next file (false)] [position
(current)] {bi} */
+ OSC_QUIT = 99, /* No parameter. */
+};
+
+enum OscType { OSC_INT, OSC_FLOAT, OSC_STRING, OSC_NOT_SUPPORTED };
+
+/* Argument. If type=OSC_STRING. intval store length of char array */
+struct OscArg{
+ OscType type;
+ int intval;
+ float floatval;
+ gchar *charval;
+ //int &length=intval;
+ int length; // Length of charval.
+ //OscArg(): charval(NULL) {
+ OscArg(){
+ type = OSC_NOT_SUPPORTED;
+ intval = 0;
+ floatval = 0;
+ charval = NULL;
+ length = 0;
+ }
+ OscArg(int i){
+ OscArg();
+ type = OSC_INT;
+ intval = i;
+ }
+ OscArg(float f){
+ OscArg();
+ type = OSC_FLOAT;
+ floatval = f;
+ }
+ OscArg(const gchar* str){
+ OscArg();
+ type = OSC_STRING;
+ length = strlen(str);
+ charval = g_strndup(str, length);
+ }
+ ~OscArg(){
+ if(charval != NULL ){
+ if( type != OSC_STRING )
+ printf("Error, charpointer is not null!!\n");
+ else
+ g_free(charval);
+ }
+ }
+ void print(){
+ switch( type ){
+ case OSC_INT: printf("%i (i)",intval); break;
+ case OSC_FLOAT: printf("%f (f)",floatval); break;
+ case OSC_STRING: printf("%s (s, %i chars)",charval, length);
break;
+ default: printf("? (type?)");
+ }
+ }
+};
+
+/* Message. Contains array of Arguments and Address. */
+struct OscMessage{
+ gchar *address;
+ OscArg **args;
+ int length; // Length of args array.
+
+ OscMessage(const osc::ReceivedMessage *m){
+ address = g_strdup( m->AddressPattern() );
+ length = m->ArgumentCount();
+ args = (OscArg**) g_malloc( sizeof(OscArg*) * length );
+ osc::ReceivedMessage::const_iterator arg = m->ArgumentsBegin();
+ OscArg **arg2 = args;
+ for(int i=0;i<length;i++ ){
+ if( arg->IsInt32() ){ *arg2 = new OscArg((int) (arg++)-
>AsInt32() ); arg2++; }
+ else if( arg->IsBool() ){ *arg2 = new OscArg((int) (arg++)-
>AsBool()?1:0 ); arg2++; }
+ else if( arg->IsFloat() ){ *arg2 = new OscArg( (arg++)-
>AsFloat() ); arg2++; }
+ else if( arg->IsString() ){ *arg2 = new OscArg((char*) (arg++)-
>AsString() ); arg2++; }
+ else { *arg2 = new OscArg(); arg++; arg2++; };
+ }
+ }
+ ~OscMessage(){
+ for(int i=0;i<length;i++){
+ delete *(args+i);
+ *(args+i) = NULL;
+ }
+ //g_free(args);//SIGABRT?!
+ //args = NULL;
+ g_free(address);
+ }
+ void print(){
+ printf("OSC message: %s ",address);
+ for(int i=0;i<length;i++){
+ printf(", ");
+ (*(args+i))->print();
+ }
+ printf("\n");
+ }
+};
+
+#endif
diff --git a/src/osceventsource.cc b/src/osceventsource.cc
new file mode 100644
index 0000000..fcfaf12
--- /dev/null
+++ b/src/osceventsource.cc
@@ -0,0 +1,88 @@
+/* GST123 - GStreamer based command line media player
+ * Copyright (C) 2012 Olaf Schulz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <ncurses.h>
+#include <term.h>
+#include <unistd.h>
+#include <string.h>
+//#include <signal.h>
+
+#include <vector>
+#include <map>
+
+#include "osceventsource.h"
+
+using std::vector;
+using std::string;
+using std::map;
+
+static GPollFD stdin_poll_fd = { 0, G_IO_IN, 0 };
+static OscEventSource *osc_instance;
+
+static gboolean
+stdin_prepare (GSource *source,
+ gint *timeout)
+{
+ *timeout = -1;
+ return FALSE;
+}
+
+static gboolean
+stdin_check (GSource *source)
+{
+ return TRUE;
+ //return g_async_queue_length(osc_instance->osc_queue)>0;//mutex
error?!
+}
+
+gboolean
+OscEventSource::stdin_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ osc_instance->osc_handler->process_osc();
+
+ return TRUE;
+}
+
+void
+OscEventSource::signal_sig_cont (int s)
+{
+}
+
+void
+OscEventSource::init (GMainLoop *loop, OscHandler *osc_handler)
+{
+ osc_instance = this;
+ this->osc_handler = osc_handler;
+
+ // add mainloop source for osc messages
+ static GSourceFuncs source_funcs = { stdin_prepare, stdin_check,
stdin_dispatch, };
+ GSource *source = g_source_new (&source_funcs, sizeof (GSource));
+ g_source_attach (source, g_main_loop_get_context (loop));
+ g_main_context_add_poll (g_main_loop_get_context (loop),
&stdin_poll_fd, G_PRIORITY_DEFAULT);
+
+ //signal (SIGCONT, signal_sig_cont);
+}
+
+void
+OscEventSource::end()
+{
+}
+
diff --git a/src/osceventsource.h b/src/osceventsource.h
new file mode 100644
index 0000000..8310869
--- /dev/null
+++ b/src/osceventsource.h
@@ -0,0 +1,42 @@
+/* GST123 - GStreamer based command line media player
+ * Copyright (C) 2012 Olaf Schulz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef GST123_OSC_EVENT_SOURCE_H
+#define GST123_OSC_EVENT_SOURCE_H
+
+#include <glib.h>
+#include <vector>
+#include <string>
+#include <map>
+
+#include "oschandler.h"
+
+class OscEventSource
+{
+ OscHandler *osc_handler;
+
+ static gboolean stdin_dispatch (GSource *source, GSourceFunc
callback, gpointer user_data);
+ static void signal_sig_cont (int);
+
+public:
+ GAsyncQueue *osc_queue;
+ void init (GMainLoop *loop, OscHandler *osc_handler);
+ void end();
+};
+
+#endif
diff --git a/src/oschandler.h b/src/oschandler.h
new file mode 100644
index 0000000..577dcc5
--- /dev/null
+++ b/src/oschandler.h
@@ -0,0 +1,30 @@
+/* GST123 - GStreamer based command line media player
+ * Copyright (C) 2012 Olaf Schulz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef GST123_OSC_HANDLER_H
+#define GST123_OSC_HANDLER_H
+
+#include "osc.h"
+
+class OscHandler
+{
+public:
+ virtual void process_osc () = 0;
+};
+
+#endif
Reply all
Reply to author
Forward
0 new messages