External SoundObject

The external SoundObject is a generic object that allows you to write script within blue to be executed outside of blue and have the generated score be brought back in. The way this is implemented, blue will read in anything that the external program writes to stdout. for most scripting languages, this equates to a "print()" command of some sort in your script.

The external SoundObject's editor takes in two inputs, a script and a commandline to run on that script. technically, when blue is in the score generating pass and comes to an external SoundObject, the external SoundObject writes your script to a temp file, then runs the commandline given, either swapping “$infile” with the name of the temporary file generated, or appending the name of the temporary file to the end of the commandline if no “$infile” is found.

A Simple Example

Let's say you're writing a simple perl script:

 print "i1 0 2 3 4 5\n"

and you for your commandline you use:

perl

or perhaps:

/usr/bin/perl $infile

When blue goes to generate a .CSD file and comes across your external SoundObject, what will happen is that:

  1. Your script will get written to a temp file (for this example, let's say it's "/tmp/temp4253.txt")

  2. blue executes the commandline given with that temp file.

    1. For the first commandline, it'll then run:

      perl /tmp/temp4253.txt
    2. For the second commandline, it'll then run:

      /usr/bin/perl /tmp/temp4253.txt
  3. perl runs, and will print "i1 0 2 3 4 5\n" to stdout

  4. blue will get that output from perl, then bring that back in, convert it to blue Note class.

  5. blue then will shift the note over to the start time of your external SoundObject, then scale the note to the duration of the SoundObject.

And that's it!

Note. In general, all time values for start are from time-zero within the SoundObject. This is like taking a three notes: you know one starts at the beginning, one starts 1 second later, and one starts 2 seconds later. No matter where you put those three notes, the relationship of that block of notes is the same, one at the beginning, one 2 seconds later, etc. so it is with SoundObjects in blue. When you make a script to generate notes, have it start at time zero and let blue do the scaling and translation of time for the SoundObject. blue was made this way so that no matter what you generate within the block, the generated notes will start at the start of the SoundObject and will last the duration of the SoundObject.

A More Complex Example

Now, any script that has a commandline that can execute on a file will work with blue. so, as another example, let's say you want to use Python and you're using the pmask library. You have both of these installed on your system and you know they work fine because you've tested them outside of blue. Now, let's say you wrote the following Python script (which really, was written by Hans Mikelson as a an example for using pmask, taken from the CSound Magazine):

from pmask import *

    
     density = Mask(UniformRandom(), PowerSegment([(0.0,
 0.03),  (20.0, 0.5)], 3.0), PowerSegment([(0.0, 0.08), (20.0, 1.0)], 3.0))
     duration = Mask(UniformRandom(), PowerSegment([(0.0, 
 0.4), (20.0, 3.0)], 1.0), PowerSegment([(0.0, 0.8), (20.0, 5.0)], 1.0))
     frequency_mask = Mask(UniformRandom(), PowerSegment([(0.0,
  3000.0), (20.0, 90.0)], 1.0), PowerSegment([(0.0, 5000.0), (20.0, 150.0)],
  1.0))
     frequency = Quantizer(frequency_mask, LinearSegment([(0.0,
  400.0), (20.0, 50.0)]), 0.95)

     index = Mask(UniformRandom(), PowerSegment([(0.0,
2.0),   (20.0, 3.0)], 1.0), PowerSegment([(0.0, 3.0), (20.0, 5.0)], 1.0))
     panorama = Range(0, 1)
    
     amplitude = Lorenz('x')
    
     ss = ScoreSection(0.0, 20.0, 1, density, duration, 
frequency,  index, panorama, amplitude)

    
     print str(ss)

and you tested it outside of blue and it worked fine. Well, now you could create an external SoundObject in blue, paste in this script, set the commandline to "python", and now have the notes imported into blue.

Using a Score Generating Language

Let's try a non-scripting example now and use Mark Williamson's drum pattern scoring utility to generate a drum pattern(available at http://www.junklight.com). Mark's utility is itself a perl script, but it takes in a text file using a scoring language he developed.

copying in the example drum.pat file into the scripting area:

instrument1 "i1 $now .2 2000 2.2 0"
instrument2 "i1 $now .2 2000 2.4 1"
instrument3 "i1 $now .1 2000 4 1"
instrument4 "i1 $now .2 2000 1.6 0.5"

instrument5 "i1 $now .1 2000 4 0"
pattern1 1 1 1 
pattern2 1 1

pattern3 1 1 1 1
pattern4 1 1 1 1 1 1 1 1
pattern5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
plist1 1 2
ilist1 3 5 

bar length 1 second
time error .01
# poly rhythm example
loop 5 

 play 1 with 1
 play 2 with 2

endloop
# straight 4/4

loop 5  
 play 2 with 1
 play 3 with 3


endloop

loop 5 
 play plist 1 with 4

 play 4 with ilist 1 

 play 3 with 1
endloop


loop 5 
 play plist 1 with 4
 play 5 with ilist 1 

 play 4 with 1

endloop

Having unzipped the drumscript.zip into my home direcotory, I used the following commandline:

perl /home/steven/drumText/drums.pl -input

I ran the test button and got... nothing! I got alot of exceptions printed to the console. Running the drum script outside of blue, I saw that by default, some logging information was being printed (the name of the infile and input). Modifying mark's perl script a bit to comment out those two print statements, I reran the script within blue and... success! The generated output from mark's script successfully was rebrought back into blue.

Notes on Score Generating Programs and the External SoundObject

Score generation programs can either print out to stdout or write out to a file. If writing out to a file, care must be taken to use the $outfile parameter of the External SoundObject so that after the external program finishes, blue will know to grab the file's contents back into blue.