package jmslexamples; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLRandom; /**
Generate a CSound score file using statistical distributions of grains read from input sound file
Example of one line of output:
; ins strt dur amp skip atk rel pan
i1 0 0.01 .5 0 .0025 .0025 0.5
Assumes a CSound orc file like the following, where "aiff\marimba.aif" is the source for grains and has length 0.126 sec.
sr = 44100 ; audio sampling rate is 44.1 kHz
kr = 4410 ; control rate is tenth that Hz
ksmps = 10 ; number of samples in a control period (sr/kr)
nchnls = 2 ; number of channels of audio output
instr 1
idur = p3
iamp = p4
iskiptime = p5
iattack = p6
irelease = p7
ipan = p8
kamp linen iamp, iattack, idur, irelease
asig soundin "aiff\marimba.aif", iskiptime
arampsig = kamp * asig
outs arampsig * ipan, arampsig * (1-ipan)
endin
@author Nick Didkovsky
*/
public class GrainMaker {
int numSplatters = 1; // How many blasts of grains
int numGrains = 10; // How many grains to splatter each time
double spread = 0.5; // Time spread "left" and "right" of target time, controls Gauss bell
double outDur = 10.0; // Duration of output sound file
double inDur = 0.126; // Duration of input sound file, you must set properly by checking your file!!!
double maxGrainDur = 0.01; // Max width of grain, chosen 0..max
double minGrainDur = 0.001;
boolean useGauss = true; // Uniform statistical grain distribution or Gaussian distribution
// mutator methods follow
public void setNumSplatters(int n) {
numSplatters = n;
}
public void setNumGrains(int n) {
numGrains = n;
}
public void setSpread(double n) {
spread = n;
}
public void setOutDur(double n) {
outDur = n;
}
public void setInDur(double n) {
inDur = n;
}
public void setMaxGrainDur(double n) {
maxGrainDur = n;
}
public void setMinGrainDur(double n) {
minGrainDur = n;
}
public void setUseGauss(boolean b) {
useGauss = b;
}
// Accessor methods
public int getNumSplatters() {
return numSplatters;
}
public int getNumGrains() {
return numGrains;
}
public double getSpread() {
return spread;
}
public double getOutDur() {
return outDur;
}
public double getInDur() {
return inDur;
}
public double getMaxGrainDur() {
return maxGrainDur;
}
public double getMinGrainDur() {
return minGrainDur;
}
public boolean getUseGauss() {
return useGauss;
}
String format(double d) {
return ((int) (d * 10000)) / 10000.0 + "";
}
/** Choose a target time and generate numGrains grains within the spread of the target */
void splatter() {
double targetTime = JMSLRandom.choose(outDur);
for (int i = 0; i < numGrains; i++) {
double start;
if (useGauss)
start = JMSLRandom.gauss(spread, targetTime);
else
start = JMSLRandom.choosePlusMinus(spread) + targetTime;
double grainDur = JMSLRandom.choose() * (maxGrainDur - minGrainDur) + minGrainDur;
double amp = JMSLRandom.choose();
double skip = JMSLRandom.choose() * inDur;
double attack = minGrainDur;
double release = minGrainDur;
double pan = JMSLRandom.choose();
if (start >= 0.0) {
String startStr = format(start);
String grainDurStr = format(grainDur);
String ampStr = format(amp);
String skipStr = format(skip);
String panStr = format(pan);
JMSL.out.println(
"i1 "
+ startStr
+ " "
+ grainDurStr
+ " "
+ ampStr
+ " "
+ skipStr
+ " "
+ attack
+ " "
+ release
+ " "
+ panStr);
}
}
}
/** Nice comments for .sco file */
void writeHeader() {
JMSL.out.println("; Generated by GrainMaker.java by Nick Didkovsky, nick@didkovsky.com");
JMSL.out.println("; GrainMaker (c) 1998 Didkovsky/Nerveware, all rights reserved");
JMSL.out.println(";ins strt dur amp skip atk rel pan");
}
/** end of sco file */
void cleanup() {
JMSL.out.println("e"); // end sco file
}
/** Top level method. Blast a number of bursts of grains into and output score file */
public void makeGrains() {
writeHeader();
for (int i = 0; i < numSplatters; i++)
splatter();
cleanup();
}
public static void main(String args[]) {
GrainMaker gm = new GrainMaker();
JMSLRandom.randomize();
gm.makeGrains();
}
}