> Is there an easy Csound-based alternative to the SC3 patterns library? Some years ago I wrote a script to use Pbind with csound, pd etc. Here is a simple test `pbind_test.sc' // events: 16 // template: i 0.5 var score, frequencies; frequencies = Pseq(({440+100.0.rand2} ! 200)); score = Pbind( \instr, 1, \at, Pseries(0,0.1,200), \dur, Prand(({1.0.rand}!200),inf), \amp, Pseq([80,83,72,88],inf), \freq, frequencies + Pseq([0,100,200,300],inf) ); The comment `// events: ...' is optional but `// template: ...' is mandatory and it is the format of the line for the output values. The template is very simple: the keys of Pbind are between <...> and the rest of the line remains unchanged ("i" and 0.5 in the example). The `score' variable in sclang is mandatory and the Pbind to convert has to be score = Pbind(...); The arguments of the script are: Usage: scl_pbind2cols scfile [num-of-events] num-of-events overwrites the value in `// events: ...' if it exists. We can use `socat' (SOcket CAT) to run a simple sclang server socat pty,link=/tmp/sclang.in,echo=0 exec:sclang and finally, in another terminal (or we can start the server like a daemon): scl_pbind2cols pbind_test.sc i1 0 0.29935657978058 80 418.92990112305 0.5 i1 0.1 0.25428187847137 83 535.72236537933 0.5 i1 0.2 0.82031977176666 72 656.52870178223 0.5 i1 0.3 0.8511688709259 88 778.21835517883 0.5 i1 0.4 0.34435153007507 80 482.8480386734 0.5 i1 0.5 0.55086886882782 83 530.33241271973 0.5 ... Another example, only four events filtered with the `column' utility: scl_pbind2cols pbind_test.sc 4 | column -t i1 0 0.70760095119476 80 418.57472896576 0.5 i1 0.1 0.0092399120330811 83 546.263256073 0.5 i1 0.2 0.83638513088226 72 617.68080234528 0.5 i1 0.3 0.83638513088226 88 758.24090480804 0.5 We can use it in real time with csound -L /some/fifo ... and scl_pbind2cols pbind_test.sc > /some/fifo Only three lines to write a wrapper for #!/bin/bash exec > "$2" /usr/local/bin/scl_pbind2cols "$1" Ok, here is the script: #!/usr/bin/perl # scl_pbind2cols # reads a scfile and prints the values generated by a Pbind # Tito Latini use strict; use warnings; usage() if (@ARGV < 1); my ($infile, $events_) = @ARGV; die "$infile absent: $!" unless -e $infile; # sclang server started with: # socat pty,link=/tmp/sclang.in,echo=0 exec:sclang my $scinput = "/tmp/sclang.in"; check_sclang_server($scinput); my $events = $events_ || 0; my $str = ""; my $str_args = ""; my $scfifo = "/tmp/sclang.out"; unless (-p $scfifo) { use POSIX qw(mkfifo); unlink $scfifo if -e $scfifo; mkfifo($scfifo, 0600) or die "mkfifo $scfifo failed: $!"; } open(SCL, ">", $scinput) or die "Could not open $scinput: $!"; open(SCFILE, "<", $infile) or die "Could not open $infile: $!"; print SCL "var sclFIFO;\n"; while() { if ($events == 0 && $_ =~ m|//\s+events:\s+(\d+)|) { $events = ${1}; } elsif ($_ =~ m|//\s+template:\s|) { my @Ev = split(' ', $_, -1); foreach my $i (@Ev[2 .. $#Ev]) { if($i =~ "(.*)<(.*)>(.*)") { $str .= "${1}%${3} "; $str_args .= ",ev.at(\\${2})"; } else { $str .= "${i} "; } } $str = " sclFIFO = File(\"$scfifo\",\"w\"); score=score.asStream; $events.do({var ev = score.next(Event.new); if(ev.notNil, {sclFIFO.write(format(\"${str}\\n\"${str_args}))})}); close(sclFIFO)\f "; } else { print SCL; } } print SCL $str; open(FIFO, "<", $scfifo) or die "Could not open $scfifo: $!"; print while(); sub check_sclang_server { my ($scinput) = shift; if (! -e $scinput) { print STDERR <<"EOF"; no sclang server; open a terminal and run socat pty,link=$scinput,echo=0 exec:sclang EOF exit(1); } } sub usage { print STDERR "Usage: $0 scfile [num-of-events]\n"; exit(1); }