aboutsummaryrefslogtreecommitdiff
path: root/pdoctave.c
diff options
context:
space:
mode:
Diffstat (limited to 'pdoctave.c')
-rw-r--r--pdoctave.c130
1 files changed, 130 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