aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();
+}
+
+