aboutsummaryrefslogtreecommitdiff
path: root/supercollider
diff options
context:
space:
mode:
authorKjetil S. Matheussen <ksvalast@users.sourceforge.net>2004-01-20 16:56:23 +0000
committerKjetil S. Matheussen <ksvalast@users.sourceforge.net>2004-01-20 16:56:23 +0000
commit5a2a3440f0c4558258c19a694e1c5d550db06a37 (patch)
tree82a99cbb9710cdd8cde3bad0307573fc03e7c4aa /supercollider
parent84afa8ecc7a7cd68f3477d2ea348c7ff4748a6aa (diff)
Various tools to make supercollider more convenient to use within PD
svn path=/trunk/; revision=1271
Diffstat (limited to 'supercollider')
-rw-r--r--supercollider/example/fileplayer.sc18
-rw-r--r--supercollider/example/help-sc.pd33
-rw-r--r--supercollider/example/supertest.py45
-rw-r--r--supercollider/extMain.sc18
-rwxr-xr-xsupercollider/k_sc~/gendasc.py49
-rw-r--r--supercollider/k_sc~/help-k_sc~.pd8
-rw-r--r--supercollider/k_sc~/k_sc~.c147
-rw-r--r--supercollider/k_sc~/makefile90
-rwxr-xr-xsupercollider/python/OSC.py230
-rw-r--r--supercollider/python/supercollider.py121
10 files changed, 759 insertions, 0 deletions
diff --git a/supercollider/example/fileplayer.sc b/supercollider/example/fileplayer.sc
new file mode 100644
index 00000000..f8e880c4
--- /dev/null
+++ b/supercollider/example/fileplayer.sc
@@ -0,0 +1,18 @@
+
+/*
+ Short example of a supercollider3 synth.
+ -Kjetil S. Matheussen, 2004.
+
+ To load this one from inside PD, call:'
+
+ server.evalSynth("fileplayer")
+
+*/
+
+
+arg out=0,bufnum,rate=100,pan=0;
+
+Out.ar( out,
+ Pan2.ar(PlayBuf.ar(1,bufnum,rate/100,0,0,1),pan/100,0.8)
+)
+
diff --git a/supercollider/example/help-sc.pd b/supercollider/example/help-sc.pd
new file mode 100644
index 00000000..41492c59
--- /dev/null
+++ b/supercollider/example/help-sc.pd
@@ -0,0 +1,33 @@
+#N canvas 447 151 646 543 10;
+#X obj 366 242 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 -68 256;
+#X obj 455 237 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 -57.4803 256;
+#X obj 458 207 hsl 128 15 -100 100 0 0 empty empty empty -2 -6 0 8
+-262144 -1 -1 2700 1;
+#X msg 366 218 -120;
+#X obj 273 110 dac~;
+#X msg 50 274 reload;
+#X msg 109 171 start /home/kjetil/mus2840/hh1.wav;
+#X msg 288 265 stop;
+#X msg 365 267 rate \$1;
+#X msg 455 264 pan \$1;
+#X obj 260 66 from_sc~;
+#X obj 71 325 pyext supertest supertest;
+#X text 15 15 Play a soundfile on the supercollider server.;
+#X text 333 67 <- We get the supercollider sound here.;
+#X text 432 503 -Kjetil S. Matheussen \, 2004;
+#X msg 28 487 \; pd dsp 1;
+#X obj 28 456 loadbang;
+#X connect 0 0 8 0;
+#X connect 1 0 9 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 5 0 11 0;
+#X connect 6 0 11 1;
+#X connect 7 0 11 1;
+#X connect 8 0 11 1;
+#X connect 9 0 11 1;
+#X connect 10 0 4 0;
+#X connect 10 1 4 1;
+#X connect 16 0 15 0;
diff --git a/supercollider/example/supertest.py b/supercollider/example/supertest.py
new file mode 100644
index 00000000..d48b7164
--- /dev/null
+++ b/supercollider/example/supertest.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+
+import pyext,os,traceback
+from supercollider import *
+
+
+class supertest(pyext._class):
+ _inlets=1
+ _outlets=0
+
+ def start_1(self,arg):
+ try:
+ self.buffer=BufferRead(self.server,arg)
+ self.bsynth=Synth(self.server,"fileplayer",["bufnum",self.buffer.id])
+ except:
+ traceback.print_exc()
+
+ def stop_1(self):
+ try:
+ del self.bsynth
+ except:
+ traceback.print_exc()
+
+ def pan_1(self,val):
+ try:
+ self.bsynth.set("pan",val)
+ except:
+ traceback.print_exc()
+
+ def rate_1(self,rate):
+ try:
+ self.bsynth.set("rate",rate)
+ except:
+ traceback.print_exc()
+
+ def __init__(self):
+ try:
+ self.server=localServer;
+ self.server.dumpOSC(3)
+ self.server.evalSynth("fileplayer");
+ except:
+ traceback.print_exc()
+
+
diff --git a/supercollider/extMain.sc b/supercollider/extMain.sc
new file mode 100644
index 00000000..56ec7660
--- /dev/null
+++ b/supercollider/extMain.sc
@@ -0,0 +1,18 @@
++ Main {
+ startup {
+ super.startup;
+ // set the 's' interpreter variable to the default server.
+ interpreter.s = Server.local;
+ Server.local.options.numOutputBusChannels = 8;
+ Server.local.options.numInputBusChannels = 8;
+ Server.local.options.memSize = 8192;
+ }
+
+ shutdown { // at recompile, quit
+ //Server.quitAll;
+ //super.shutdown;
+ }
+
+ newSCWindow {
+ }
+}
diff --git a/supercollider/k_sc~/gendasc.py b/supercollider/k_sc~/gendasc.py
new file mode 100755
index 00000000..a68cc140
--- /dev/null
+++ b/supercollider/k_sc~/gendasc.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+#/* --------------------------- gendasc ----------------------------------- */
+#/* ;; Kjetil S. Matheussen, 2004. */
+#/* */
+#/* This program is free software; you can redistribute it and/or */
+#/* modify it under the terms of the GNU General Public License */
+#/* as published by the Free Software Foundation; either version 2 */
+#/* of the License, or (at your option) any later version. */
+#/* */
+#/* This program 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 General Public License for more details. */
+#/* */
+#/* You should have received a copy of the GNU General Public License */
+#/* along with this program; if not, write to the Free Software */
+#/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#/* */
+#/* ---------------------------------------------------------------------------- */
+
+
+import sys,string,xreadlines
+
+
+path=sys.argv[1]
+if path[-1]=="/":
+ filename=path+"d_dac.c"
+else:
+ filename=path+"/"+"d_dac.c"
+
+
+success=0
+for line in xreadlines.xreadlines(open(filename,"r")):
+ line=string.replace(line,'adc','from_sc')
+ line=string.replace(line,'dac','to_sc')
+ line=string.replace(line,"(t_newmethod)from_sc_new","(t_newmethod)from_sc_newnew")
+ line=string.replace(line,"(t_newmethod)to_sc_new","(t_newmethod)to_sc_newnew")
+ sys.stdout.write(line)
+ if line=='#include "m_pd.h"\n':
+ print 'static void *from_sc_newnew(t_symbol *s, int argc, t_atom *argv);'
+ print 'static void *to_sc_newnew(t_symbol *s, int argc, t_atom *argv);'
+ success=1
+
+if success==0:
+ print "Fix gendasc.py script."
+
+
+
diff --git a/supercollider/k_sc~/help-k_sc~.pd b/supercollider/k_sc~/help-k_sc~.pd
new file mode 100644
index 00000000..e25d9500
--- /dev/null
+++ b/supercollider/k_sc~/help-k_sc~.pd
@@ -0,0 +1,8 @@
+#N canvas 0 0 450 300 10;
+#X obj 197 62 from_sc~;
+#X obj 292 84 to_sc~;
+#X obj 285 43 osc~ 500;
+#X obj 200 131 dac~;
+#X connect 0 0 3 0;
+#X connect 0 1 3 1;
+#X connect 2 0 1 0;
diff --git a/supercollider/k_sc~/k_sc~.c b/supercollider/k_sc~/k_sc~.c
new file mode 100644
index 00000000..2b743ad9
--- /dev/null
+++ b/supercollider/k_sc~/k_sc~.c
@@ -0,0 +1,147 @@
+/* --------------------------- k_sc~ ----------------------------------- */
+/* ;; Kjetil S. Matheussen, 2004. */
+/* */
+/* This program is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU General Public License */
+/* as published by the Free Software Foundation; either version 2 */
+/* of the License, or (at your option) any later version. */
+/* */
+/* This program 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 General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* */
+/* ---------------------------------------------------------------------------- */
+
+
+
+#include "fromto.c"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <jack/jack.h>
+
+
+static int num_ins=0;
+static int num_outs=0;
+
+static int getnumjackchannels(jack_client_t *client,char *regstring){
+ int lokke=0;
+ const char **ports=jack_get_ports(client,regstring,"",0);
+ if(ports==NULL) return 0;
+ while(ports[lokke]!=NULL){
+ lokke++;
+ }
+ return lokke;
+}
+
+static void setupjack(void){
+ static bool inited=false;
+ int lokke;
+ int num_sc_in,num_sc_out;
+
+ jack_client_t *client;
+
+ if(inited==true) return;
+
+ if(sys_audioapi!=API_JACK){
+ post("Error. k_sc~ will not work without jack as the sound API.");
+ goto apiwasnotjack;
+ }
+
+ client=jack_client_new("k_sc_tilde");
+
+ num_sc_in=getnumjackchannels(client,"SuperCollider:in_*");
+ num_sc_out=getnumjackchannels(client,"SuperCollider:out_*");
+
+ if(num_sc_in==0 || num_sc_out==0){
+ post("Error. No Supercollider jack ports found.");
+ goto nosupercolliderportsfound;
+ }
+
+ num_ins=sys_get_inchannels();
+ num_outs=sys_get_outchannels();
+
+ {
+ int t1[1]={0};
+ int t2[1]={0};
+ int t3[1]={num_sc_out+num_ins};
+ int t4[1]={num_sc_in+num_outs};
+ sys_close_audio();
+ sys_open_audio(1,t1,
+ 1,t3,
+ 1,t2,
+ 1,t4,
+ sys_getsr(),sys_schedadvance/1000,1);
+ }
+
+ for(lokke=0;lokke<num_sc_in;lokke++){
+ char temp[500];
+ char temp2[500];
+ sprintf(temp,"pure_data_0:output%d",lokke+num_outs);
+ sprintf(temp2,"SuperCollider:in_%d",lokke+1);
+ jack_connect(client,temp,temp2);
+ sprintf(temp,"alsa_pcm:capture_%d",lokke+1);
+ jack_disconnect(client,temp,temp2);
+ }
+ for(lokke=0;lokke<num_sc_out;lokke++){
+ char temp[500];
+ char temp2[500];
+ sprintf(temp,"pure_data_0:input%d",lokke+num_ins);
+ sprintf(temp2,"SuperCollider:out_%d",lokke+1);
+ jack_connect(client,temp2,temp);
+ sprintf(temp,"alsa_pcm:playback_%d",lokke+1);
+ jack_disconnect(client,temp2,temp);
+ }
+
+ inited=true;
+
+ nosupercolliderportsfound:
+ jack_client_close(client);
+
+
+ apiwasnotjack:
+ return;
+}
+
+static void *from_sc_newnew(t_symbol *s, int argc, t_atom *argv){
+ int lokke;
+ t_from_sc *x;
+ setupjack();
+ x=from_sc_new(s,argc,argv);
+
+ for(lokke=0;lokke<x->x_n;lokke++){
+ x->x_vec[lokke]+=num_outs;
+ }
+ return x;
+}
+
+static void *to_sc_newnew(t_symbol *s, int argc, t_atom *argv){
+ int lokke;
+ t_to_sc *x;
+ setupjack();
+ x=to_sc_new(s,argc,argv);
+
+ for(lokke=0;lokke<x->x_n;lokke++){
+ x->x_vec[lokke]+=num_ins;
+ }
+ return x;
+}
+
+
+static void k_sc_tilde_setup(void){
+ d_to_sc_setup();
+}
+
+
+void from_sc_tilde_setup(void){
+ k_sc_tilde_setup();
+}
+
+void to_sc_tilde_setup(void){
+ k_sc_tilde_setup();
+}
diff --git a/supercollider/k_sc~/makefile b/supercollider/k_sc~/makefile
new file mode 100644
index 00000000..3d3eb639
--- /dev/null
+++ b/supercollider/k_sc~/makefile
@@ -0,0 +1,90 @@
+NAME=k_sc~
+CSYM=k_sc_tilde
+
+current: pd_linux
+
+# ----------------------- NT -----------------------
+
+pd_nt: $(NAME).dll
+
+.SUFFIXES: .dll
+
+PDNTCFLAGS = /W3 /WX /O2 /G6 /DNT /DPD /nologo
+VC="C:\Programme\Microsoft Visual Studio\VC98"
+
+PDNTINCLUDE = /I. /Ic:\pd\tcl\include /Ic:\pd\src /I$(VC)\include /Iinclude
+
+PDNTLDIR = $(VC)\Lib
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDNTLDIR)\user32.lib \
+ $(PDNTLDIR)\uuid.lib \
+ c:\pd\bin\pd.lib \
+
+.c.dll:
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+ link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB)
+
+# ----------------------- IRIX 5.x -----------------------
+
+pd_irix5: $(NAME).pd_irix5
+
+.SUFFIXES: .pd_irix5
+
+SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2
+
+SGIINCLUDE = -I../../src
+
+.c.pd_irix5:
+ cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o
+ rm $*.o
+
+# ----------------------- IRIX 6.x -----------------------
+
+pd_irix6: $(NAME).pd_irix6
+
+.SUFFIXES: .pd_irix6
+
+SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -Ofast=ip32
+
+.c.pd_irix6:
+ cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
+ ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o
+ rm $*.o
+
+# ----------------------- LINUX i386 -----------------------
+
+pd_linux: fromto.c $(NAME).pd_linux
+
+.SUFFIXES: .pd_linux
+
+LINUXCFLAGS = -DPD -DUNIX -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+PDSRCDIR=../../src
+LINUXINCLUDE = -I$(PDSRCDIR)
+
+.c.pd_linux: fromto,c
+ gcc $(LINUXCFLAGS) $(LINUXINCLUDE) -g -o $*.o -c $*.c
+ ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm -ljack
+ strip --strip-unneeded $*.pd_linux
+ rm -f $*.o ../$*.pd_linux
+ ln -s $*/$*.pd_linux ..
+ ln -sf $*/$*.pd_linux ../from_sc~.pd_linux
+ ln -sf $*/$*.pd_linux ../to_sc~.pd_linux
+
+# ----------------------------------------------------------
+
+fromto.c: gendasc.py
+ ./gendasc.py $(PDSRCDIR) >fromto.c
+
+install:
+ cp help-*.pd ../../doc/5.reference
+
+clean:
+ rm -f *.o *.pd_* so_locations fromto.c *~
diff --git a/supercollider/python/OSC.py b/supercollider/python/OSC.py
new file mode 100755
index 00000000..7c3c20f5
--- /dev/null
+++ b/supercollider/python/OSC.py
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+# ======================================================================
+# file: OSC.py
+# author: stefan kersten <steve@k-hornz.de>
+# contents: OSC client module for python
+# license: public domain
+# ======================================================================
+# $Id: OSC.py,v 1.1 2004-01-20 16:54:44 ksvalast Exp $
+# ======================================================================
+# copyright (c) 2000 stefan kersten
+# ======================================================================
+# this module provides simple OSC client functionality
+# usage examples down at the end of the file
+# ======================================================================
+
+__revision__ = "$Revision: 1.1 $"
+
+# ======================================================================
+# imports
+
+import cStringIO, exceptions, math, socket, struct, time, types
+
+# ======================================================================
+# constants
+
+SECONDS_UTC_TO_UNIX_EPOCH = 2208988800.0
+FLOAT_TO_INT_SCALE = pow(2.0, 32.0)
+
+# ======================================================================
+# types
+
+class Value:
+ """Abstract OSC value."""
+ def __init__(self, value):
+ self.value = value
+
+ def binary_value(self):
+ pass
+
+ def type_tag(self):
+ pass
+
+class Int(Value):
+ """32 bit integer value."""
+ def __init__(self, value):
+ Value.__init__(self, long(value))
+
+ def binary_value(self):
+ return struct.pack('!l', self.value)
+
+ def type_tag(self):
+ return 'i'
+
+class Float(Value):
+ """32 bit floating point value."""
+ def __init__(self, value):
+ Value.__init__(self, float(value))
+
+ def binary_value(self):
+ return struct.pack('!f', self.value)
+
+ def type_tag(self):
+ return 'f'
+
+class String(Value):
+ """Null-terminated string padded to multiples of 4 byte."""
+ def __init__(self, value):
+ Value.__init__(self, str(value))
+
+ def binary_value(self):
+ v = self.value
+ l = len(v)
+ return struct.pack('%ds%dx' % (l, self.pad_amount(l)), v)
+
+ def type_tag(self):
+ return 's'
+
+ def pad_amount(self, len):
+ return 4 - (len % 4)
+
+class Time(Value):
+ """64 bit timetag in NTP format."""
+ def __init__(self, value):
+ Value.__init__(self, float(value))
+
+ def __add__(self, time):
+ return Time(float(self.value + time.value))
+
+ def binary_value(self):
+ t = self.value
+ # FIXME: how to convert without overflows?
+ s = long(t)
+ f = long(math.fmod(t, 1.0)*FLOAT_TO_INT_SCALE)
+ return struct.pack('!LL', s, f)
+
+# ======================================================================
+# utilities
+
+time_module = time
+def time():
+ """Return current time as float in OSC format."""
+ return SECONDS_UTC_TO_UNIX_EPOCH + time_module.time()
+
+# ======================================================================
+# classes
+
+class Packet:
+ """Abstract base class for all OSC-related containers.
+
+ Has methods for retrieving the proper binary representation
+ and its size.
+ """
+ def __init__(self, packets):
+ stream = cStringIO.StringIO()
+ self._write_contents(packets, stream)
+ self._data = stream.getvalue()
+
+ def get_packet(self):
+ """Return the binary representation of the receiver's contents.
+
+ This data is in the proper OSC format and can be sent over a
+ socket.
+ """
+ return self._data
+
+ def get_size(self):
+ """Return the size of the receiver's binary data."""
+ return len(self._data)
+
+ def _write_contents(self, packets, stream):
+ """Write packets on stream.
+
+ Private.
+
+ Override in subclasses for specific behavior.
+ """
+ pass
+
+ def __repr__(self):
+ return '<' + \
+ str(self.__class__.__name__) + \
+ ' instance, size=' + \
+ str(self.get_size()) + \
+ '>'
+
+ def sendto(self, host, port):
+ """Send the receiver's data through a UDP socket."""
+ s = socket.socket(socket.SOCK_DGRAM, socket.AF_INET)
+ packet = self.get_packet()
+ s.sendto(packet, (host, port))
+ s.close()
+
+ def sendlocal(self, port):
+ """Send the receiver's data through a UDP socket locally."""
+ self.sendto('localhost', port)
+
+def _value(x):
+ """Convert x(int, float or string) to an OSC object."""
+ t = type(x)
+ if t == types.FloatType:
+ return Float(x)
+ if t == types.IntType or t == types.LongType:
+ return Int(x)
+ # return string representation as default
+ return String(str(x))
+
+class Message(Packet):
+ """Single OSC message with arguments.
+
+ Message(address, *args) -> Message
+
+ address -- OSC address string
+ *args -- message argument list
+ """
+ def __init__(self, address, args=[]):
+ Packet.__init__(self, [String(address)] + map(lambda x: _value(x), args))
+
+ def _write_contents(self, args, stream):
+ t_stream = cStringIO.StringIO() # tag stream
+ v_stream = cStringIO.StringIO() # value stream
+ # open signature string
+ t_stream.write(',')
+ # collect tags and arguments
+ for v in args[1:]:
+ t_stream.write(v.type_tag())
+ v_stream.write(v.binary_value())
+ # write address
+ stream.write(args[0].binary_value())
+ # write signature
+ stream.write(String(t_stream.getvalue()).binary_value())
+ # write arguments
+ stream.write(v_stream.getvalue())
+
+class Bundle(Packet):
+ """OSC container type with timing information.
+
+ Bundle(time, packets) -> Bundle
+
+ time -- floating point timetag in OSC units
+ packets -- array of Packet(s)
+ """
+ def __init__(self, time, packets):
+ Packet.__init__(self, [Time(time)] + packets)
+
+ def _write_contents(self, args, stream):
+ # write '#bundle' preamble
+ stream.write(String('#bundle').binary_value())
+ # write timetag
+ stream.write(args[0].binary_value())
+ # write packets, prefixed with a byte count
+ for packet in args[1:]:
+ data = packet.get_packet()
+ size = len(data)
+ stream.write(Int(size).binary_value())
+ stream.write(data)
+
+def test(port):
+ """Some example messages and bundles, sent to port."""
+ Message("/filter/cutoff", [145.1232]).sendlocal(port)
+ Message("/http", ["www dot k-hornz dot de", 12, 3.41, "bulb"]).sendlocal(port)
+ #print Int(len(Message("/msg").get_packet())).binary_value()
+ Bundle(0.1, [Message("/fubar")]).sendlocal(port)
+ Bundle(time(), [Message("/msg", [1.0, "+", 1, 61, "0"]), Message("/bang!")]).sendlocal(port)
+
+if __name__ == "__main__":
+ """Run dumpOSC on port 10000."""
+ test(10000)
+
+# EOF
+# ======================================================================
diff --git a/supercollider/python/supercollider.py b/supercollider/python/supercollider.py
new file mode 100644
index 00000000..9a4ff3f0
--- /dev/null
+++ b/supercollider/python/supercollider.py
@@ -0,0 +1,121 @@
+
+#/* --------------------------- supercollider.py ----------------------------------- */
+#/* ;; Kjetil S. Matheussen, 2004. */
+#/* */
+#/* This program is free software; you can redistribute it and/or */
+#/* modify it under the terms of the GNU General Public License */
+#/* as published by the Free Software Foundation; either version 2 */
+#/* of the License, or (at your option) any later version. */
+#/* */
+#/* This program 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 General Public License for more details. */
+#/* */
+#/* You should have received a copy of the GNU General Public License */
+#/* along with this program; if not, write to the Free Software */
+#/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#/* */
+#/* ---------------------------------------------------------------------------- */
+
+
+
+# This file is far from complete, but its a start.
+# -Kjetil.
+
+
+import OSC,tempfile,xreadlines,os,time
+
+standardport=57110
+startnode=1001;
+startbuffer=0;
+
+sc_head=0
+sc_tail=1
+sc_before=2
+sc_after=3
+sc_replace=4
+
+
+# For some crazy reason, the sclang command tells the server to quits when exiting.
+# To fix that strange and unpleasant behaviour, uncommnet the following lines in etc. etc. etc.
+
+
+class Server:
+ def __init__(self,magic,port=standardport):
+ if magic!=1234:
+ print "Server.__init__: Are you sure you know what you are doing?"
+ print "Seems like probably wanted to use the 'localServer' variable."
+ self.port=port
+ self.freenode=startnode;
+ self.freebuffer=startbuffer;
+ def sendMsg(self,command,*args):
+ OSC.Message(command,args).sendlocal(self.port)
+ def sendgetMsg(self,command,*args):
+ apply(self.sendMsg,[command]+list(args))
+ time.sleep(1)
+ def dumpOSC(self,code):
+ self.sendMsg("dumpOSC",code);
+ def nextNodeID(self):
+ self.freenode+=1;
+ return self.freenode-1
+ def nextBufferID(self):
+ self.freebuffer+=1;
+ return self.freebuffer-1;
+ def loadSynthDef(self,name):
+ self.sendgetMsg("/d_load",name)
+ def loadSynthDefDir(self,dir):
+ self.sendMsg("/d_loadDir",dir)
+ def evalSynth(self,synthname):
+ tmpname=tempfile.mktemp(".sc")
+ outfile=open(tmpname,"w")
+ outfile.write('SynthDef("'+synthname+'",{')
+ for line in xreadlines.xreadlines(open(synthname+".sc","r")):
+ outfile.write(line)
+ tmpname2=tempfile.mktemp("")
+ outfile.write('}).writeDefFile("'+tmpname2+'");\n')
+ outfile.close()
+ os.system("sclang "+tmpname)
+ tmpname2+=synthname+".scsyndef"
+ self.loadSynthDef(tmpname2)
+ os.system("rm "+tmpname+" "+tmpname2)
+
+localServer=Server(1234)
+
+class Node:
+ def __del__(self):
+ self.server.sendMsg("/n_free",self.id)
+ def set(self,*args):
+ apply(self.server.sendMsg,["/n_set",self.id]+list(args))
+
+
+class Synth(Node):
+ def __init__(self,server,name,args=[],position=sc_tail):
+ self.server=server
+ self.id=server.nextNodeID()
+ apply(self.server.sendMsg,["/s_new",name,self.id,position,0]+args)
+
+
+class BufferSuper:
+ def __init__(self,server,numFrames=0,numChannels=1,filename="",startFrame=0):
+ self.server=server
+ self.id=server.nextBufferID()
+ if numChannels==-1:
+ server.sendMsg("/b_allocRead",self.id,filename,startFrame,numFrames,0)
+ else:
+ server.sendMsg("/b_alloc",self.id,numFrames,numChannels,0)
+
+ def __del__(self):
+ self.server.sendMsg("/b_free",self.id)
+
+
+class Buffer(BufferSuper):
+ def __init__(self,server,numFrames,numChannels=1):
+ BufferSuper.__init__(self,server,numFrames,numChannels)
+
+class BufferRead(BufferSuper):
+ def __init__(self,server,filename,startFrame=0,numFrames=0):
+ BufferSuper.__init__(self,server,numFrames,-1,filename,startFrame)
+
+
+