aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranz Zotter <fzotter@users.sourceforge.net>2006-02-22 12:48:15 +0000
committerFranz Zotter <fzotter@users.sourceforge.net>2006-02-22 12:48:15 +0000
commit97d9a1382b32a7055f407265d24f8dc900e04741 (patch)
treeb2804dbff72d634e2e0a38507e7c8c6c8768033a
These is the beginning of a try to connect the pd to octave. Especially when using the iemmatrix features in pd, this feature becomes sensible. On the whole it shall enable the user to use the command line parser of octave.svn2git-root
The take-over strategy is bad at this starting point. No threading, no practical data transmission. Perhaps the common work on it can help. (Franz) svn path=/trunk/externals/iem/pdoctave/; revision=4611
-rw-r--r--pdoctave.c130
-rw-r--r--pdoctave.h6
-rw-r--r--pdoctave.pd20
-rw-r--r--pdoctave_command.c114
-rw-r--r--pdoctave_command.h5
-rw-r--r--pdoctave_dataframe.c249
-rw-r--r--pdoctave_dataframe.h66
-rw-r--r--pdoctave_datatypes.h7
-rw-r--r--pdoctave_get.c183
-rw-r--r--pdoctave_get.h5
-rw-r--r--pdoctave_send.c150
-rw-r--r--pdoctave_send.h5
-rw-r--r--read_shared_mem.cc99
-rw-r--r--test.cc10
-rw-r--r--test_pdoctave.pd80
-rw-r--r--write_shared_mem.cc105
16 files changed, 1234 insertions, 0 deletions
diff --git a/pdoctave.c b/pdoctave.c
new file mode 100644
index 0000000..31cd69b
--- /dev/null
+++ b/pdoctave.c
@@ -0,0 +1,130 @@
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#ifndef __pdoctave_c__
+#include "m_pd.h"
+#include "pdoctave_send.h"
+#include "pdoctave_get.h"
+#include "pdoctave_command.h"
+//#include "math.h"
+//#include "d_mayer_fft.c"
+//#include "/home/fzotter/downloads/pd-0.38-4/src/d_mayer_fft.c"
+//#include "/home/pd/src/pd-0.37-1-alsamm/src/d_mayer_fft.c"
+
+static t_class *pdoctave_class;
+static int obj_instances = 0;
+static int octave_pid;
+static int fd[2];
+
+
+/* PDOCTAVE is an object that starts an octave process and holds a pipe to its stdin.
+ * other sub-routines can use the 'writeToOctaveStdIN' routine to write commands
+ * to octave.
+*/
+
+
+typedef struct _PDOctave_ PDOctave;
+struct _PDOctave_
+{
+ t_object x_obj;
+};
+
+int getPDOctaveInstances ()
+{
+ return obj_instances;
+}
+
+// writing commands to the octave-process
+int writeToOctaveStdIN (const char *cmd)
+{
+ int bytes_written;
+ if (obj_instances > 0) {
+ bytes_written = write(fd[1], (void*)cmd, strlen(cmd));
+ if (bytes_written == -1) {
+ post("error writing to pipe");
+ return -1;
+ }
+// post("wrote %d bytes", bytes_written);
+ return 0;
+ }
+ else
+ return -1;
+}
+
+static void deletePDOctave (PDOctave *pdoctave_obj)
+{
+ if (obj_instances-- == 1) {
+ int err = 0;
+ close(fd[1]);
+
+ if ((waitpid(octave_pid, NULL, 0) == -1) && (errno != ECHILD)) {
+ err = 1;
+ }
+ if (err) {
+ post("error closing octave");
+ }
+ }
+}
+
+
+static void *newPDOctave (t_symbol *s, int argc, t_atom *argv)
+{
+ PDOctave * pdoctave_obj;
+ pdoctave_obj = (PDOctave *) pd_new (pdoctave_class);
+
+ // creating only one pipe!
+ if (!obj_instances++) {
+
+ if (pipe(fd) == -1) {
+ post("Error creating pipe.");
+ }
+
+ if ((octave_pid = fork()) == 0) { /* child process */
+ // execution of octave and pipe to octave stdin
+ close(fd[1]);
+
+ if (dup2(fd[0], STDIN_FILENO) == -1) {
+ post("error duplicating filedescriptor to STDIN");
+ exit(1);
+ return;
+ }
+
+ close(fd[0]);
+ execlp("octave", "octave", "-i", NULL);
+ // this is only reached, when the octave process is
+ // dying before the pdoctave object
+ post("shell command ``octave'' could not be executed");
+ } else if (octave_pid == -1) {
+ // Error handling
+ } else { /* parent process */
+ close(fd[0]);
+ // waiting for the child process having the octave pipe
+ // and process properly set up
+ sleep(1);
+ }
+ }
+ return ((void *) pdoctave_obj);
+}
+
+void pdoctave_setup (void)
+{
+ pdoctave_class = class_new
+ (gensym("pdoctave"),
+ (t_newmethod) newPDOctave,
+ (t_method) deletePDOctave,
+ sizeof (PDOctave),
+ CLASS_NOINLET, 0);
+ post("pdoctave successfully loaded!");
+ pdoctave_send_setup ();
+ pdoctave_command_setup ();
+ pdoctave_get_setup ();
+}
+
+#define __pdoctave_c_
+#endif
diff --git a/pdoctave.h b/pdoctave.h
new file mode 100644
index 0000000..9678863
--- /dev/null
+++ b/pdoctave.h
@@ -0,0 +1,6 @@
+// pdoctave functions
+
+// functions return -1 when they fail (= octave object is not instanciated in pd)
+
+int getPDOctaveInstances ();
+int writeToOctaveStdIN (const char *cmd);
diff --git a/pdoctave.pd b/pdoctave.pd
new file mode 100644
index 0000000..0cd232f
--- /dev/null
+++ b/pdoctave.pd
@@ -0,0 +1,20 @@
+#N canvas 576 230 660 659 10;
+#X obj 103 514 shell;
+#X obj 376 509 table octave 100;
+#X obj 326 429 textfile;
+#X msg 366 305 clear;
+#X msg 333 272 write octave_matrix.m;
+#X obj 177 522 print;
+#X msg 340 345 add clearplot() \, add load octave_matrix.mtx \, add
+plot(octave_matrix) \, add grid on \, add pause(2);
+#X msg 100 453 konsole -e octave /home/fzotter/Documents/Arbeit/ConferenceSystem/octave_matrix.m
+;
+#X msg 92 387 konsole -e octave;
+#X msg 146 572 \; octave write /home/fzotter/Documents/Arbeit/ConferenceSystem/octave_matrix.mtx
+;
+#X connect 3 0 2 0;
+#X connect 4 0 2 0;
+#X connect 6 0 2 0;
+#X connect 7 0 0 0;
+#X connect 7 0 5 0;
+#X connect 8 0 0 0;
diff --git a/pdoctave_command.c b/pdoctave_command.c
new file mode 100644
index 0000000..b1f1d6b
--- /dev/null
+++ b/pdoctave_command.c
@@ -0,0 +1,114 @@
+#include <string.h>
+#ifndef __pdoctave_command_c_
+#define __pdoctave_command_c_
+#include "pdoctave.h" /* writing a command to octave */
+#include "pdoctave_dataframe.h"
+#include "m_pd.h"
+
+static t_class *pdoctave_command_class;
+
+typedef struct _PDOctaveCommand_ PDOctaveCommand;
+struct _PDOctaveCommand_
+{
+ t_object x_obj;
+ char oct_command[1024];
+ int pos;
+};
+
+static void clearStringCommand (PDOctaveCommand *pdoctcmd_obj)
+{
+ pdoctcmd_obj->pos=0;
+ pdoctcmd_obj->oct_command[0] = '\0';
+}
+
+static void addStringToCommand (PDOctaveCommand *pdoctcmd_obj, char *str)
+{
+ int n = strlen (str);
+ strcpy(pdoctcmd_obj->oct_command+pdoctcmd_obj->pos, str);
+ pdoctcmd_obj->pos += n;
+}
+
+static void addAtomToCommand (PDOctaveCommand *pdoctcmd_obj, t_atom *a)
+{
+ const unsigned int bufsize = 50;
+ char str[bufsize];
+
+ atom_string (a, str, bufsize);
+
+ if (strcmp(str,"\\\\,") == 0) {
+ strcpy(str,",\0");
+ }
+ else if (strcmp(str,"\\\\;") == 0) {
+ strcpy(str,";\0");
+ }
+
+ addStringToCommand (pdoctcmd_obj, str);
+}
+
+static void removeEscapeSlashes (char *c)
+{
+ int pos = strlen(c);
+ c = c+pos-1;
+
+ while (--pos) {
+ if (*--c == '\\') {
+ strcpy(c,c+1);
+ }
+ }
+}
+static void pDOctaveCommandBang (PDOctaveCommand *pdoctcmd_obj)
+{
+ post("command: %s sent", pdoctcmd_obj->oct_command);
+ writeToOctaveStdIN (pdoctcmd_obj->oct_command);
+}
+
+
+static void pDOctaveCommandAny (PDOctaveCommand *pdoctcmd_obj, t_symbol *s, int argc, t_atom *argv)
+{
+ clearStringCommand (pdoctcmd_obj);
+ if (argc>0)
+ while (argc--) {
+ addAtomToCommand (pdoctcmd_obj, argv++);
+ addStringToCommand (pdoctcmd_obj, " \0");
+ }
+
+ addStringToCommand (pdoctcmd_obj, "\n");
+ removeEscapeSlashes (pdoctcmd_obj->oct_command);
+ pDOctaveCommandBang (pdoctcmd_obj);
+}
+
+static void *newPDOctaveCommand (t_symbol *s, int argc, t_atom *argv)
+{
+ PDOctaveCommand *pdoctcmd_obj = (PDOctaveCommand *)
+ pd_new (pdoctave_command_class);
+
+ post("getpdoctaveinstances returned %d", getPDOctaveInstances());
+ if (getPDOctaveInstances()<1) {
+ post("Octave not running, insert a 'pdoctave' object!!");
+ }
+ pdoctcmd_obj->pos = 0;
+ if (argc>0)
+ while (argc--) {
+ addAtomToCommand (pdoctcmd_obj, argv++);
+ addStringToCommand (pdoctcmd_obj, " \0");
+ }
+
+ addStringToCommand (pdoctcmd_obj, "\n");
+ removeEscapeSlashes(pdoctcmd_obj->oct_command);
+
+ return ((void *) pdoctcmd_obj);
+}
+void pdoctave_command_setup (void)
+{
+ pdoctave_command_class = class_new
+ (gensym("pdoctave_command"),
+ (t_newmethod) newPDOctaveCommand,
+ 0,
+ sizeof (PDOctaveCommand),
+ CLASS_DEFAULT, A_GIMME, 0);
+ class_addbang (pdoctave_command_class, (t_method) pDOctaveCommandBang);
+ class_addanything (pdoctave_command_class, (t_method) pDOctaveCommandAny);
+ post("pdoctave_command successfully loaded");
+}
+#endif
+
diff --git a/pdoctave_command.h b/pdoctave_command.h
new file mode 100644
index 0000000..7250c89
--- /dev/null
+++ b/pdoctave_command.h
@@ -0,0 +1,5 @@
+#ifndef __pdoctave_command_h_
+#define __pdoctave_command_h_
+void pdoctave_command_setup (void);
+#endif
+
diff --git a/pdoctave_dataframe.c b/pdoctave_dataframe.c
new file mode 100644
index 0000000..7193c62
--- /dev/null
+++ b/pdoctave_dataframe.c
@@ -0,0 +1,249 @@
+#include "pdoctave_dataframe.h"
+
+SharedDataFrame *newSharedDataFrame ()
+{
+ int id;
+ SharedDataFrame *sdf;
+
+ id = shmget (IPC_PRIVATE, sizeof(SharedDataFrame),
+ SHM_R | SHM_W);
+
+ if (id == -1) return 0;
+
+ sdf = shmat (id, 0, 0);
+
+ if (sdf == (SharedDataFrame *) -1) {
+ shmctl (id, IPC_RMID, 0);
+ return 0;
+ }
+
+ sdf->frame_attached = 1;
+ sdf->data_attached = 0;
+ sdf->data_frame_id = id;
+ sdf->data_vec_id = -1;
+ sdf->block_for_write = 0;
+ sdf->block_for_read = 0;
+
+ return sdf;
+}
+
+
+SharedDataFrame *getSharedDataFrame (int id)
+{
+ SharedDataFrame *sdf;
+
+ sdf = shmat (id, 0, 0);
+
+ if (sdf == (SharedDataFrame *) -1)
+ return 0;
+
+ sdf->frame_attached++;
+
+ return sdf;
+}
+
+
+
+
+void freeSharedDataFrame (SharedDataFrame **sdf)
+{
+ SharedDataFrame *sdfp = *sdf;
+ if (sdfp) {
+ if (sdfp->frame_attached > 0)
+ sdfp->frame_attached--;
+ shmdt(sdfp);
+ *sdf = 0;
+ }
+}
+
+
+void removeSharedDataFrame (SharedDataFrame **sdf)
+{
+ int id;
+ SharedDataFrame *sdfp = *sdf;
+ if (sdfp) {
+ id = sdfp->data_frame_id;
+ if (sdfp->frame_attached > 0)
+ shmdt (sdfp);
+ if (id != -1)
+ shmctl(id, IPC_RMID, 0);
+ *sdf = 0;
+ }
+}
+
+
+int getSharedDataFrameId (SharedDataFrame *sdf)
+{
+ if (sdf)
+ return sdf->data_frame_id;
+ else
+ return -1;
+}
+
+
+
+DatTyp getSharedDataType (SharedDataFrame *sdf)
+{
+ if (sdf)
+ return sdf->data_typ;
+ else
+ return UNKNOWN;
+}
+
+
+int getSharedDataVecLength (SharedDataFrame *sdf)
+{
+ if (sdf)
+ return sdf->data_vec_len;
+ else
+ return 0;
+}
+
+
+void *newSharedData (SharedDataFrame *sdf, int n, int size_bytes, DatTyp dtyp)
+{
+ void *data;
+ int id;
+
+ if (sdf) {
+
+ id = sdf->data_vec_id;
+ if (id == -1)
+ id = shmget(IPC_PRIVATE, n*size_bytes, SHM_R | SHM_W);
+
+ if (id == -1) return 0;
+
+ data = shmat(id,0,0);
+
+ if (data == (void *) -1) {
+ shmctl (id, IPC_RMID, 0);
+ return 0;
+ }
+
+ sdf->data_attached = 1;
+ sdf->data_size_bytes = size_bytes;
+ sdf->data_vec_len = n;
+ sdf->data_vec_id = id;
+ sdf->data_typ = dtyp;
+
+ return data;
+ }
+ else return 0;
+}
+
+
+void *getSharedData (SharedDataFrame *sdf)
+{
+ void *data;
+
+ if ((sdf)&&(sdf->data_vec_id != -1)) {
+
+ data = shmat(sdf->data_vec_id,0,0);
+
+ if (data == (void *) -1) {
+ return 0;
+ }
+
+ sdf->data_attached++;
+
+ return data;
+ }
+ else
+ return 0;
+}
+
+
+void freeSharedData (SharedDataFrame *sdf, void **data)
+{
+ void *datap = *data;
+ if (datap) {
+ shmdt(datap);
+ *data = 0;
+ if ((sdf)&&(sdf->data_attached > 0))
+ sdf->data_attached--;
+ }
+}
+
+
+void removeSharedData (SharedDataFrame *sdf, void **data)
+{
+ int id;
+ void *datap = *data;
+ if (datap) {
+ shmdt (datap);
+ *data = 0;
+ if (sdf) {
+ if (sdf->data_attached > 0)
+ sdf->data_attached--;
+ if (sdf->data_vec_id != -1) {
+ shmctl (sdf->data_vec_id, IPC_RMID, 0);
+ sdf->data_vec_id = -1;
+ }
+ }
+ }
+}
+
+void unBlockForReading (SharedDataFrame *sdf)
+{
+ if (sdf)
+ sdf->block_for_read = 0;
+}
+void unBlockForWriting (SharedDataFrame *sdf)
+{
+ if (sdf)
+ sdf->block_for_write = 0;
+}
+void blockForReading (SharedDataFrame *sdf)
+{
+ if (sdf)
+ sdf->block_for_read = 1;
+}
+void blockForWriting (SharedDataFrame *sdf)
+{
+ if (sdf)
+ sdf->block_for_write = 1;
+}
+void sleepUntilReadUnBlocked (SharedDataFrame *sdf, int usleep_time)
+{
+ int timer = 0;
+ if (sdf) {
+ while ((sdf->block_for_read!=0)&&(timer < MAX_SLEEP_TIME)) {
+ timer += usleep_time;
+ usleep (usleep_time);
+ }
+ }
+}
+void sleepUntilReadBlocked (SharedDataFrame *sdf, int usleep_time)
+{
+ int timer = 0;
+ if (sdf) {
+ while ((sdf->block_for_read==0)&&(timer < MAX_SLEEP_TIME)) {
+ timer +=usleep_time;
+ usleep (usleep_time);
+ }
+
+ }
+}
+void sleepUntilWriteUnBlocked (SharedDataFrame *sdf, int usleep_time)
+{
+ int timer = 0;
+ if (sdf) {
+ while ((sdf->block_for_write!=0)&&(timer < MAX_SLEEP_TIME)) {
+ timer +=usleep_time;
+ usleep (usleep_time);
+ }
+
+ }
+}
+void sleepUntilWriteBlocked (SharedDataFrame *sdf, int usleep_time)
+{
+ int timer = 0;
+ if (sdf) {
+ while ((sdf->block_for_write==0)&&(timer < MAX_SLEEP_TIME)) {
+ timer +=usleep_time;
+ usleep (usleep_time);
+ }
+
+ }
+}
+
diff --git a/pdoctave_dataframe.h b/pdoctave_dataframe.h
new file mode 100644
index 0000000..53a21cc
--- /dev/null
+++ b/pdoctave_dataframe.h
@@ -0,0 +1,66 @@
+#ifndef __pdoctave_data_frame_h__
+#define __pdoctave_data_frame_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <unistd.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/wait.h>
+#include <stdio.h>
+
+#include "pdoctave_datatypes.h"
+
+#define STD_USLEEP_TIME 100
+#define MAX_SLEEP_TIME 200000
+
+typedef struct _SharedDataFrame_ SharedDataFrame;
+
+struct _SharedDataFrame_ {
+ int data_frame_id;
+
+ int data_vec_id;
+ int data_vec_len;
+ int data_size_bytes;
+ DatTyp data_typ;
+
+ // internal states
+ int frame_attached;
+ int data_attached;
+
+ int block_for_read;
+ int block_for_write;
+};
+
+SharedDataFrame *newSharedDataFrame ();
+SharedDataFrame *getSharedDataFrame (int id);
+void freeSharedDataFrame (SharedDataFrame **sdf);
+void removeSharedDataFrame (SharedDataFrame **sdf);
+int getSharedDataFrameId (SharedDataFrame *sdf);
+
+DatTyp getSharedDataType (SharedDataFrame *sdf);
+int getSharedDataVecLength (SharedDataFrame *sdf);
+
+void *newSharedData (SharedDataFrame *sdf, int n, int size_bytes, DatTyp dtyp);
+void *getSharedData (SharedDataFrame *sdf);
+void freeSharedData (SharedDataFrame *sdf, void **data);
+void removeSharedData (SharedDataFrame *sdf, void **data);
+
+void unBlockForReading (SharedDataFrame *sdf);
+void unBlockForWriting (SharedDataFrame *sdf);
+void blockForReading (SharedDataFrame *sdf);
+void blockForWriting (SharedDataFrame *sdf);
+void sleepUntilReadUnBlocked (SharedDataFrame *sdf, int usleep_time);
+void sleepUntilReadBlocked (SharedDataFrame *sdf, int usleep_time);
+void sleepUntilWriteUnBlocked (SharedDataFrame *sdf, int usleep_time);
+void sleepUntilWriteBlocked (SharedDataFrame *sdf, int usleep_time);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/pdoctave_datatypes.h b/pdoctave_datatypes.h
new file mode 100644
index 0000000..603e055
--- /dev/null
+++ b/pdoctave_datatypes.h
@@ -0,0 +1,7 @@
+typedef enum {
+ MATRIX,
+ FLOAT,
+ LIST,
+ SYMBOL,
+ UNKNOWN
+} DatTyp;
diff --git a/pdoctave_get.c b/pdoctave_get.c
new file mode 100644
index 0000000..1c7df7b
--- /dev/null
+++ b/pdoctave_get.c
@@ -0,0 +1,183 @@
+#include <string.h>
+#ifndef __pdoctave_get_c_
+#define __pdoctave_get_c_
+#include "pdoctave.h" /* writing a command to octave */
+#include "pdoctave_dataframe.h"
+#include "m_pd.h"
+
+static t_class *pdoctave_get_class;
+
+typedef struct _PDOctaveGet_ PDOctaveGet;
+struct _PDOctaveGet_
+{
+ t_object x_obj;
+ t_outlet *outlet;
+ SharedDataFrame *sdf;
+ char oct_command[150];
+ char *oct_name;
+ void *data;
+ int list_length;
+ t_atom *list;
+};
+
+static void *newPDOctaveGet (t_symbol *s, int argc, t_atom *argv)
+{
+ PDOctaveGet *pdoctget_obj = (PDOctaveGet *)
+ pd_new (pdoctave_get_class);
+ t_symbol *name;
+
+ post("getpdoctaveinstances returned %d", getPDOctaveInstances());
+ if (getPDOctaveInstances()<1) {
+ post("Octave not running, insert a 'pdoctave' object!!");
+ }
+ if (argc>0)
+ name = atom_getsymbol(argv);
+ else
+ name = gensym ("pdm1");
+
+ pdoctget_obj->sdf = newSharedDataFrame ();
+ pdoctget_obj->data = 0;
+ pdoctget_obj->oct_name = name->s_name;
+ pdoctget_obj->outlet = outlet_new (&pdoctget_obj->x_obj, 0);
+
+ return ((void *) pdoctget_obj);
+}
+
+static void pDOctaveGetCommand (PDOctaveGet *pdoctget_obj)
+{
+ char *cmd;
+ cmd = pdoctget_obj->oct_command;
+ strcpy(cmd, "write_shared_mem(");
+ cmd += 17;
+ strcpy(cmd, pdoctget_obj->oct_name);
+ cmd += strlen (cmd);
+ *cmd++ = ',';
+ sprintf(cmd, "%d", getSharedDataFrameId(pdoctget_obj->sdf));
+ cmd += strlen(cmd);
+ strcpy (cmd, ")\n");
+
+ writeToOctaveStdIN (pdoctget_obj->oct_command);
+}
+
+static void copyFloats (float *f, t_atom *a, int n)
+{
+ for (;n--;a++,f++)
+ SETFLOAT (a, *f);
+}
+
+static void outletListAllocation (PDOctaveGet *pdoctget_obj, int newsize)
+{
+ if (newsize != pdoctget_obj->list_length) {
+ if (newsize > 0) {
+ if (pdoctget_obj->list_length > 0) {
+ pdoctget_obj->list = (t_atom *)
+ resizebytes (pdoctget_obj->list,
+ sizeof(t_atom) * pdoctget_obj->list_length,
+ sizeof(t_atom) * newsize);
+ pdoctget_obj->list_length = newsize;
+ }
+ else {
+ pdoctget_obj->list = (t_atom *) getbytes (sizeof(t_atom) * newsize);
+ pdoctget_obj->list_length = newsize;
+ }
+ }
+ else if (newsize == 0) {
+ freebytes (pdoctget_obj->list, sizeof(t_atom) * pdoctget_obj->list_length);
+ pdoctget_obj->list = 0;
+ pdoctget_obj->list_length = 0;
+ }
+ }
+}
+
+static void pdoctaveConvertData (PDOctaveGet *pdoctget_obj)
+{
+ int size = getSharedDataVecLength(pdoctget_obj->sdf);
+ t_symbol *s;
+ switch (getSharedDataType (pdoctget_obj->sdf)) {
+ case FLOAT:
+ case MATRIX:
+ case LIST:
+ outletListAllocation (pdoctget_obj, size);
+ copyFloats ((float *) pdoctget_obj->data, pdoctget_obj->list, size);
+ break;
+ case SYMBOL:
+ size = 1;
+ outletListAllocation (pdoctget_obj, 1);
+ s = gensym((char*)pdoctget_obj->data);
+ SETSYMBOL (pdoctget_obj->list, s);
+ break;
+ case UNKNOWN:
+ post("pdoctave_get: unknown return value");
+ }
+ removeSharedData (pdoctget_obj->sdf, &(pdoctget_obj->data));
+}
+
+static void pdoctaveOutletList (PDOctaveGet *pdoctget_obj)
+{
+ t_symbol *s;
+ switch (getSharedDataType (pdoctget_obj->sdf)) {
+ case FLOAT:
+ s = gensym("float");
+ break;
+ case LIST:
+ s = gensym("list");
+ break;
+ case MATRIX:
+ s = gensym("matrix");
+ break;
+ case SYMBOL:
+ s = gensym("symbol");
+ break;
+ case UNKNOWN:
+ post("pdoctave_get: unknown return value");
+ return;
+ }
+ outlet_anything (pdoctget_obj->outlet,
+ s, pdoctget_obj->list_length, pdoctget_obj->list);
+}
+
+static void pDOctaveGetBang (PDOctaveGet *pdoctget_obj)
+{
+ SharedDataFrame *sdf;
+
+ sdf = pdoctget_obj->sdf;
+
+ sleepUntilReadUnBlocked (sdf,STD_USLEEP_TIME);
+ blockForReading (sdf);
+
+ // sending read command
+ blockForWriting (sdf);
+ pDOctaveGetCommand (pdoctget_obj);
+ sleepUntilWriteUnBlocked (sdf,STD_USLEEP_TIME);
+
+ // waiting for results
+ pdoctget_obj->data = getSharedData (sdf);
+
+ // converting incoming data
+ pdoctaveConvertData (pdoctget_obj);
+ unBlockForReading (sdf);
+
+ // outletting data
+ pdoctaveOutletList (pdoctget_obj);
+}
+
+
+static void deletePDOctaveGet (PDOctaveGet *pdoctget_obj)
+{
+ removeSharedData (pdoctget_obj->sdf, &(pdoctget_obj->data));
+ removeSharedDataFrame (&(pdoctget_obj->sdf));
+}
+
+void pdoctave_get_setup (void)
+{
+ pdoctave_get_class = class_new
+ (gensym("pdoctave_get"),
+ (t_newmethod) newPDOctaveGet,
+ (t_method) deletePDOctaveGet,
+ sizeof (PDOctaveGet),
+ CLASS_DEFAULT, A_GIMME, 0);
+ class_addbang (pdoctave_get_class, (t_method) pDOctaveGetBang);
+ post("pdoctave_get successfully loaded");
+}
+#endif
+
diff --git a/pdoctave_get.h b/pdoctave_get.h
new file mode 100644
index 0000000..f408b1b
--- /dev/null
+++ b/pdoctave_get.h
@@ -0,0 +1,5 @@
+#ifndef __pdoctave_send_h_
+#define __pdoctave_send_h_
+void pdoctave_send_setup (void);
+#endif
+
diff --git a/pdoctave_send.c b/pdoctave_send.c
new file mode 100644
index 0000000..b6a38d4
--- /dev/null
+++ b/pdoctave_send.c
@@ -0,0 +1,150 @@
+#include <string.h>
+#ifndef __pdoctave_send_c_
+#define __pdoctave_send_c_
+#include "pdoctave.h" /* writing a command to octave */
+#include "pdoctave_dataframe.h"
+#include "m_pd.h"
+
+static t_class *pdoctave_send_class;
+
+typedef struct _PDOctaveSend_ PDOctaveSend;
+struct _PDOctaveSend_
+{
+ t_object x_obj;
+ SharedDataFrame *sdf;
+ char oct_command[150];
+ char *oct_name;
+ void *data;
+};
+
+static void *newPDOctaveSend (t_symbol *s, int argc, t_atom *argv)
+{
+ PDOctaveSend *pdoctsnd_obj = (PDOctaveSend *)
+ pd_new (pdoctave_send_class);
+ t_symbol *name;
+
+ if (getPDOctaveInstances()<1) {
+ post("Octave not running, insert a 'pdoctave' object!!");
+ }
+ if (argc>0)
+ name = atom_getsymbol(argv);
+ else
+ name = gensym ("pdm1");
+
+ pdoctsnd_obj->sdf = newSharedDataFrame ();
+ pdoctsnd_obj->data = 0;
+ pdoctsnd_obj->oct_name = name->s_name;
+
+ return ((void *) pdoctsnd_obj);
+}
+
+static void pDOctaveSendBang (PDOctaveSend *pdoctsnd_obj)
+{
+ char *cmd;
+ strcpy(pdoctsnd_obj->oct_command, pdoctsnd_obj->oct_name);
+ cmd = pdoctsnd_obj->oct_command + strlen(pdoctsnd_obj->oct_name);
+ strcpy(cmd, "=read_shared_mem(");
+ cmd += 17;
+ sprintf(cmd, "%d", getSharedDataFrameId(pdoctsnd_obj->sdf));
+ cmd = cmd+strlen(cmd);
+ strcpy (cmd, ");\n");
+
+ writeToOctaveStdIN (pdoctsnd_obj->oct_command);
+ freeSharedData (pdoctsnd_obj->sdf, &(pdoctsnd_obj->data));
+ //removeSharedData (pdoctsnd_obj->sdf, &(pdoctsnd_obj->data));
+}
+
+static void copyFloats (float *f, t_atom *a, int n)
+{
+ for (;n--;a++,f++)
+ *f = atom_getfloat(a);
+}
+
+static DatTyp pdSelectorClassify (char *selector)
+{
+ DatTyp pdtyp;
+ if (!strcmp (selector, "matrix"))
+ pdtyp = MATRIX;
+ else if (!strcmp (selector, "float"))
+ pdtyp = FLOAT;
+ else if (!strcmp (selector, "list"))
+ pdtyp = LIST;
+ else if (!strcmp (selector, "symbol"))
+ pdtyp = SYMBOL;
+ else
+ pdtyp = UNKNOWN;
+ return pdtyp;
+}
+
+static void pDOctaveSend (PDOctaveSend *pdoctsnd_obj,
+ t_symbol *s, int argc, t_atom *argv)
+{
+ DatTyp pdtyp;
+ SharedDataFrame *sdf;
+
+ char *selector = s->s_name;
+ t_symbol *symptr;
+ float *f;
+ char *c;
+ int count = argc;
+
+ pdtyp = pdSelectorClassify (selector);
+
+ sdf = pdoctsnd_obj->sdf;
+
+ sleepUntilWriteUnBlocked (sdf, STD_USLEEP_TIME);
+ blockForWriting (sdf);
+
+ if (pdoctsnd_obj->data)
+ removeSharedData (sdf, &(pdoctsnd_obj->data));
+
+ if (pdtyp != SYMBOL) {
+ if (pdoctsnd_obj->data = newSharedData (sdf, argc, sizeof(float), pdtyp)) {
+ f = (float *) pdoctsnd_obj->data;
+ copyFloats (f, argv, argc);
+ }
+ else {
+ post("pdoctave_send: allocation of shared memory size %d bytes failed!",
+ sizeof(float) * argc);
+ return;
+ }
+ }
+ else {
+ symptr = atom_getsymbol (argv);
+ if (pdoctsnd_obj->data = newSharedData (sdf, strlen(symptr->s_name)+1, sizeof(char), pdtyp)) {
+ c = (char *) pdoctsnd_obj->data;
+ strcpy (c, symptr->s_name);
+ }
+ else {
+ post("pdoctave_send: allocation of shared memory size %d bytes failed!",
+ sizeof(char) * (strlen(symptr->s_name)+1));
+ return;
+ }
+ }
+ blockForReading (sdf);
+ freeSharedData (sdf, &(pdoctsnd_obj->data));
+ pDOctaveSendBang (pdoctsnd_obj);
+ sleepUntilReadUnBlocked (sdf,STD_USLEEP_TIME);
+ unBlockForWriting (sdf);
+}
+
+static void deletePDOctaveSend (PDOctaveSend *pdoctsnd_obj)
+{
+ removeSharedData (pdoctsnd_obj->sdf, &(pdoctsnd_obj->data));
+ removeSharedDataFrame (&(pdoctsnd_obj->sdf));
+}
+
+void pdoctave_send_setup (void)
+{
+ pdoctave_send_class = class_new
+ (gensym("pdoctave_send"),
+ (t_newmethod) newPDOctaveSend,
+ (t_method) deletePDOctaveSend,
+ sizeof (PDOctaveSend),
+ CLASS_DEFAULT, A_GIMME, 0);
+ class_addbang (pdoctave_send_class, (t_method) pDOctaveSendBang);
+ class_addanything (pdoctave_send_class, (t_method) pDOctaveSend);
+ post("pdoctave_send successfully loaded");
+}
+#endif
+
diff --git a/pdoctave_send.h b/pdoctave_send.h
new file mode 100644
index 0000000..ad914f2
--- /dev/null
+++ b/pdoctave_send.h
@@ -0,0 +1,5 @@
+#ifndef __pdoctave_get_h_
+#define __pdoctave_get_h_
+void pdoctave_get_setup (void);
+#endif
+
diff --git a/read_shared_mem.cc b/read_shared_mem.cc
new file mode 100644
index 0000000..446ee0f
--- /dev/null
+++ b/read_shared_mem.cc
@@ -0,0 +1,99 @@
+#include <octave/oct.h>
+
+#include <unistd.h>
+#include <string.h>
+#include "pdoctave_dataframe.h"
+
+Matrix writeFloatIntoOctMatrix (int n, int m, float *f)
+{
+ int i;
+ int j;
+ Matrix mtx = Matrix(n,m);
+ for (j = 0; j < n; j++)
+ for (i=0; i < m; i++)
+ mtx(j,i) = (double)*f++;
+ return mtx;
+}
+
+double writeFloatIntoDouble (float f)
+{
+ return (double) f;
+}
+
+RowVector writeFloatIntoRowVector (int n, float *f)
+{
+ RowVector rv = RowVector(n);
+ int i;
+ for (i = 0; i<n; i++)
+ rv(i) = (double) *f++;
+ return rv;
+}
+
+ColumnVector writeFloatIntoColumnVector (int n, float *f)
+{
+ ColumnVector cv = ColumnVector(n);
+ int i;
+ for (i = 0; i<n; i++)
+ cv(i) = (double) *f++;
+ return cv;
+}
+
+DEFUN_DLD (read_shared_mem, args, , "reading and returning a pd-value in octave")
+{
+ SharedDataFrame *sdf;
+ void *data;
+ octave_value convert_result;
+ int shmem_id = args(0).int_value();
+ float *f;
+ std::string str;
+ std::string quote_sign = "\"";
+
+ if (shmem_id == -1) {
+ error("failed to get valid id\n");
+ return octave_value();
+ }
+ sdf = getSharedDataFrame (shmem_id);
+
+ if (!sdf) {
+ error("failed to attach memory!\n");
+ return octave_value();
+ }
+ sleepUntilWriteBlocked (sdf,STD_USLEEP_TIME);
+ sleepUntilReadBlocked (sdf, STD_USLEEP_TIME);
+
+ data = getSharedData (sdf);
+ if (!data) {
+ error("failed to attach data!\n");
+ freeSharedDataFrame (&sdf);
+ unBlockForReading (sdf);
+ return octave_value();
+ }
+
+ f = (float*) data;
+
+ switch (getSharedDataType (sdf)) {
+ case FLOAT:
+ convert_result = octave_value(writeFloatIntoDouble (*f));
+ break;
+ case LIST:
+ convert_result = octave_value(
+ writeFloatIntoRowVector (getSharedDataVecLength(sdf), f));
+ break;
+ case SYMBOL:
+ str = (std::string) (char *) data;
+ convert_result = octave_value(quote_sign+str+quote_sign);
+ break;
+ case MATRIX:
+ convert_result = octave_value(writeFloatIntoOctMatrix ((int)f[0],(int)f[1],f+2));
+ break;
+ case UNKNOWN:
+ error("unknown pdoctave type");
+ convert_result = octave_value ();
+ }
+ unBlockForReading (sdf);
+ removeSharedData (sdf, &data);
+ freeSharedDataFrame (&sdf);
+ return (convert_result);
+}
+
+
diff --git a/test.cc b/test.cc
new file mode 100644
index 0000000..815d8e7
--- /dev/null
+++ b/test.cc
@@ -0,0 +1,10 @@
+#include <octave/oct.h>
+
+#include <string.h>
+DEFUN_DLD (test, args, , "reading and returning a pd-value in octave")
+{
+ puts("eval(a+b)\n");
+ return octave_value ();
+}
+
+
diff --git a/test_pdoctave.pd b/test_pdoctave.pd
new file mode 100644
index 0000000..48c6c26
--- /dev/null
+++ b/test_pdoctave.pd
@@ -0,0 +1,80 @@
+#N canvas 0 0 1027 680 10;
+#X obj 199 138 print;
+#X msg 219 112 hallo;
+#X msg 192 254 list 1 2 3 4 5;
+#X msg 265 212 matrix 2 2 1 2 3 4;
+#X msg 179 213 2;
+#X msg 338 264 symbol halo;
+#X floatatom 139 255 5 0 0 0 - - -;
+#X msg 244 176 float 2;
+#X symbolatom 341 297 10 0 0 0 - - -;
+#X obj 354 121 mtx_ones 4 7;
+#X obj 389 77 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 138 50 pdoctave;
+#X obj 185 291 pdoctave_send a;
+#X obj 137 346 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 246 481 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 251 500 pdoctave_command b=[1:5 \; 1 \, 2 \, 3 \, 4 \, 0];
+#X obj 144 575 pdoctave_get a;
+#X obj 134 552 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 146 606 print;
+#X obj 449 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 383 152 mtx_egg 30 15;
+#X obj 354 434 mtx_ones;
+#X msg 371 410 12;
+#X floatatom 436 398 5 0 0 0 - - -;
+#X obj 429 416 pp set;
+#X obj 114 404 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 123 430 pdoctave_command mesh(a);
+#X obj 602 292 mtx_ones 1;
+#X floatatom 610 241 5 0 0 0 - - -;
+#X obj 615 266 pack f 1;
+#X obj 529 194 mtx_rand;
+#X floatatom 596 122 5 0 0 0 - - -;
+#X obj 192 378 pdoctave_command b=repmat(a \, 1 \, 2);
+#X obj 593 546 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 475 316 bang;
+#X msg 516 304 clear;
+#X obj 522 561 pp set;
+#X msg 516 592 ab;
+#X obj 749 601 print;
+#X obj 515 331 entry 500 200 grey90 black;
+#X obj 621 542 pdoctave_command b = [1 \, 2 \, 3 \; 3 4 5];
+#X connect 1 0 0 0;
+#X connect 2 0 12 0;
+#X connect 3 0 12 0;
+#X connect 4 0 12 0;
+#X connect 5 0 12 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 12 0;
+#X connect 9 0 12 0;
+#X connect 10 0 9 0;
+#X connect 13 0 32 0;
+#X connect 14 0 15 0;
+#X connect 16 0 18 0;
+#X connect 17 0 16 0;
+#X connect 19 0 20 0;
+#X connect 20 0 12 0;
+#X connect 21 0 12 0;
+#X connect 22 0 21 0;
+#X connect 23 0 24 0;
+#X connect 24 0 22 0;
+#X connect 25 0 26 0;
+#X connect 27 0 12 0;
+#X connect 28 0 29 0;
+#X connect 29 0 27 0;
+#X connect 30 0 12 0;
+#X connect 31 0 30 0;
+#X connect 33 0 40 0;
+#X connect 34 0 39 0;
+#X connect 35 0 39 0;
+#X connect 36 0 37 0;
+#X connect 39 0 40 0;
diff --git a/write_shared_mem.cc b/write_shared_mem.cc
new file mode 100644
index 0000000..2149e91
--- /dev/null
+++ b/write_shared_mem.cc
@@ -0,0 +1,105 @@
+#include <octave/oct.h>
+
+#include <unistd.h>
+#include <string.h>
+#include "pdoctave_dataframe.h"
+
+DatTyp classifyOctPDType (octave_value res)
+{
+ DatTyp pdtyp;
+ if (res.is_real_scalar())
+ pdtyp = FLOAT;
+ else if (res.is_real_matrix())
+ pdtyp = MATRIX;
+ else if (res.is_string())
+ pdtyp = SYMBOL;
+ else
+ pdtyp = UNKNOWN;
+}
+
+void writeOctMatrixIntoFloat (Matrix mtx, float *f)
+{
+ int n = mtx.rows();
+ int m = mtx.columns();
+ int i;
+ int j;
+
+ *f++ = n;
+ *f++ = m;
+
+ for (j = 0; j < m; j++)
+ for (i=0; i < n; i++)
+ *f++ = (float) mtx(i,j);
+}
+
+void writeOctScalarIntoFloat (double d, float *f)
+{
+ *f = (float) d;
+}
+void writeOctStringIntoString (char *s, char *c)
+{
+ strcpy (s,c);
+}
+
+
+DEFUN_DLD (write_shared_mem, args, , "returning an octave value to pd-value")
+{
+ SharedDataFrame *sdf;
+ int size;
+ void *data;
+ DatTyp pdtype;
+ int shmem_id = args(1).int_value();
+
+ if (shmem_id == -1) {
+ error("failed to get valid id\n");
+ return octave_value();
+ }
+ sdf = getSharedDataFrame (shmem_id);
+
+ if (!sdf) {
+ error("failed to attach memory!\n");
+ return octave_value();
+ }
+
+ sleepUntilWriteBlocked (sdf,STD_USLEEP_TIME);
+
+ if (args(0).is_string()) {
+ pdtype = SYMBOL;
+ }
+ else if (args(0).is_real_matrix()) {
+ pdtype = MATRIX;
+ size = args(0).columns() * args(0).rows()+2;
+ if (data = newSharedData (sdf, size, sizeof(float),pdtype)) {
+ writeOctMatrixIntoFloat (args(0).matrix_value(), (float *) data);
+ }
+ else {
+ error("failed to get new data memory!");
+ unBlockForWriting (sdf);
+ freeSharedDataFrame (&sdf);
+ return octave_value();
+ }
+ }
+ else if (args(0).is_real_scalar()) {
+ pdtype = FLOAT;
+ if (data = newSharedData (sdf, 1, sizeof(float), pdtype)) {
+ writeOctScalarIntoFloat(args(0).scalar_value(), (float *) data);
+ }
+ else {
+ error("failed to get new data memory!");
+ unBlockForWriting (sdf);
+ freeSharedDataFrame (&sdf);
+ return octave_value();
+ }
+ }
+ else
+ std::cout << " no mehtod for argument conversion" << std::endl;
+
+ unBlockForWriting (sdf);
+
+ freeSharedData (sdf, &data);
+ freeSharedDataFrame (&sdf);
+
+ return octave_value();
+}
+
+