package ddf.minim.ugens; import ddf.minim.UGen; /** * GranulateRandom is randomly varying version of GranulateSteady. * Rather than have fixed values for grain length, space length, * and fade length, it has min and max values for each so that each * grain is different from the last. * * @example Synthesis/granulateRandomExample * * @related GranulateSteady * @related UGen * * @author Anderson Mills * */ public class GranulateRandom extends UGen { /** * The default input is "audio." * * @related GranulateRandom */ public UGenInput audio; /** * Controls the minimum length of each grain. * * @related GranulateRandom */ public UGenInput grainLenMin; /** * Controls the minimum space between each grain. * * @related GranulateRandom */ public UGenInput spaceLenMin; /** * Controls the minimum length of the fade in and fade out. * * @related GranulateRandom */ public UGenInput fadeLenMin; /** * Controls the maximum length of each grain. * * @related GranulateRandom */ public UGenInput grainLenMax; /** * Controls the maximum space between each grain. * * @related GranulateRandom */ public UGenInput spaceLenMax; /** * Controls the maximum length of the fade in and fade out. * * @related GranulateRandom */ public UGenInput fadeLenMax; // variables to determine the current placement WRT a grain private boolean insideGrain; private float timeSinceGrainStart; private float timeSinceGrainStop; private float timeStep; // variables to keep track of the grain value ranges private float fadeLength = 0.0025f; private float grainLength = 0.010f; private float spaceLength = 0.020f; private float fadeLengthMin = 0.0025f; private float grainLengthMin = 0.010f; private float spaceLengthMin = 0.020f; private float fadeLengthMax = 0.0025f; private float grainLengthMax = 0.010f; private float spaceLengthMax = 0.020f; private float minAmp = 0.0f; private float maxAmp = 1.0f; /** * Constructor for GranulateRandom. * grainLengthMin, minimum grain length of each grain, defaults to 10 msec. * spaceLengthMin, minimum space between each grain, defaults to 20 msec. * fadeLengthMin, minimum length of the linear fade in and fade out of the i * grain envelope, defaults to 2.5 msec. * grainLengthMax, maximum grain length of each grain, defaults to 100 msec. * spaceLengthMax, maximum space between each grain, defaults to 200 msec. * fadeLengthMax, maximum length of the linear fade in and fade out of the * grain envelope, defaults to 25 msec. * * minAmp, minimum amplitude of the envelope, defaults to 0. * maxAmp, maximum amplitude of the envelope, defaults to 1. */ public GranulateRandom() { this( 0.010f, 0.020f, 0.0025f, 0.10f, 0.20f, 0.025f, 0.0f, 1.0f ); } /** * Constructor for GranulateRandom. * minAmp, minimum amplitude of the envelope, defaults to 0. * maxAmp, maximum amplitude of the envelope, defaults to 1. * * @param grainLengthMin * float: minimum grain length of each grain in seconds * @param spaceLengthMin * float: minimum space between each grain in seconds * @param fadeLengthMin * float: minimum length of the linear fade in and fade out of the grain envelope in seconds * @param grainLengthMax * float: maximum grain length of each grain in seconds * @param spaceLengthMax * float: maximum space between each grain in seconds * @param fadeLengthMax * float: maximum length of the linear fade in and fade out of the grain envelope in seconds */ public GranulateRandom(float grainLengthMin, float spaceLengthMin, float fadeLengthMin, float grainLengthMax, float spaceLengthMax, float fadeLengthMax ) { this( grainLengthMin, spaceLengthMin, fadeLengthMin, grainLengthMax, spaceLengthMax, fadeLengthMax, 0.0f, 1.0f ); } /** * Constructor for GranulateRandom * * @param grainLengthMin * float: minimum grain length of each grain in seconds * @param spaceLengthMin * float: minimum space between each grain in seconds * @param fadeLengthMin * float: minimum length of the linear fade in and fade out of the grain envelope in seconds * @param grainLengthMax * float: maximum grain length of each grain in seconds * @param spaceLengthMax * float: maximum space between each grain in seconds * @param fadeLengthMax * float: maximum length of the linear fade in and fade out of the grain envelope in seconds * @param minAmp * float: minimum amplitude of the envelope * @param maxAmp * float: maximum amplitude of the envelope */ public GranulateRandom(float grainLengthMin, float spaceLengthMin, float fadeLengthMin, float grainLengthMax, float spaceLengthMax, float fadeLengthMax, float minAmp, float maxAmp) { super(); // jam3: These can't be instantiated until the uGenInputs ArrayList // in the super UGen has been constructed audio = new UGenInput(InputType.AUDIO); grainLenMin = new UGenInput( InputType.CONTROL ); spaceLenMin = new UGenInput( InputType.CONTROL ); fadeLenMin = new UGenInput( InputType.CONTROL ); grainLenMax = new UGenInput( InputType.CONTROL ); spaceLenMax = new UGenInput( InputType.CONTROL ); fadeLenMax = new UGenInput( InputType.CONTROL ); setAllParameters( grainLengthMin, spaceLengthMin, fadeLengthMin, grainLengthMax, spaceLengthMax, fadeLengthMax, minAmp, maxAmp ); insideGrain = false; timeSinceGrainStart = 0.0f; timeSinceGrainStop = 0.0f; timeStep = 0.0f; } /** * Use this method to notify GranulateRandom that the sample rate has changed. */ protected void sampleRateChanged() { timeStep = 1.0f/sampleRate(); } /** * Immediately sets all public class members concerning time to new values. * * @param grainLengthMin * float: minimum grain length of each grain in seconds * @param spaceLengthMin * float: minimum space between each grain in seconds * @param fadeLengthMin * float: minimum length of the linear fade in and fade out of the grain envelope in seconds * @param grainLengthMax * float: maximum grain length of each grain in seconds * @param spaceLengthMax * float: maximum space between each grain in seconds * @param fadeLengthMax * float: maximum length of the linear fade in and fade out of the grain envelope in seconds * * @related GranulateRandom */ public void setAllTimeParameters(float grainLengthMin, float spaceLengthMin, float fadeLengthMin, float grainLengthMax, float spaceLengthMax, float fadeLengthMax) { setAllParameters(grainLengthMin, spaceLengthMin, fadeLengthMin, grainLengthMax, spaceLengthMax, fadeLengthMax, minAmp, maxAmp); } /** * Immediately sets all public class members to new values. * * @param grainLengthMin * float: minimum grain length of each grain in seconds * @param spaceLengthMin * float: minimum space between each grain in seconds * @param fadeLengthMin * float: minimum length of the linear fade in and fade out of the grain envelope in seconds * @param grainLengthMax * float: maximum grain length of each grain in seconds * @param spaceLengthMax * float: maximum space between each grain in seconds * @param fadeLengthMax * float: maximum length of the linear fade in and fade out of the grain envelope in seconds * @param minAmp * float: minimum amplitude of the envelope * @param maxAmp * float: maximum amplitude of the envelope * * @related GranulateRandom */ public void setAllParameters(float grainLengthMin, float spaceLengthMin, float fadeLengthMin, float grainLengthMax, float spaceLengthMax, float fadeLengthMax, float minAmp, float maxAmp) { grainLenMin.setLastValue(grainLengthMin); grainLenMax.setLastValue(grainLengthMax); fadeLenMin.setLastValue(fadeLengthMin); fadeLenMax.setLastValue(fadeLengthMax); spaceLenMin.setLastValue(spaceLengthMin); spaceLenMax.setLastValue(spaceLengthMax); this.grainLengthMin = grainLengthMin; this.spaceLengthMin = spaceLengthMin; this.fadeLengthMin = fadeLengthMin; this.grainLengthMax = grainLengthMax; this.spaceLengthMax = spaceLengthMax; this.fadeLengthMax = fadeLengthMax; this.minAmp = minAmp; this.maxAmp = maxAmp; } // This makes sure that fadeLength isn't more than half the grainLength private void checkFadeLength() { fadeLength = Math.min( fadeLength, grainLength/2.0f ); } // This is just a helper function to generate a random number between two others. // TODO place randomBetween somewhere more generic and useful. private float randomBetween( float min, float max ) { return (max - min)*(float)Math.random() + min; } // Make the samples. Must make the samples @Override protected void uGenerate( float[] channels ) { if ( insideGrain ) // inside a grain { // start with an amplitude at maxAmp float amp = maxAmp; if ( timeSinceGrainStart < fadeLength ) // inside the rise { // linear fade in amp *= timeSinceGrainStart/fadeLength; } else if ( timeSinceGrainStart > ( grainLength - fadeLength ) ) // inside the decay { // linear fade out amp *= ( grainLength - timeSinceGrainStart )/fadeLength; } // generate the sample for(int i = 0; i < channels.length; i++) { channels[i] = amp*audio.getLastValues()[i]; } // increment time timeSinceGrainStart += timeStep; if ( timeSinceGrainStart > grainLength ) // just after a grain { // stop the grain timeSinceGrainStop = 0.0f; insideGrain = false; // set a new spaceLength spaceLengthMin = spaceLenMin.getLastValue(); spaceLengthMax = spaceLenMax.getLastValue(); spaceLength = randomBetween( spaceLengthMin, spaceLengthMax ); } } else // outside a grain { for(int i = 0; i < channels.length; i++) { channels[i] = minAmp; } // increment time timeSinceGrainStop += timeStep; if (timeSinceGrainStop > spaceLength) // just inside a grain again { // start the grain timeSinceGrainStart = 0.0f; insideGrain = true; // set a new grain length grainLengthMin = grainLenMin.getLastValue(); grainLengthMax = grainLenMax.getLastValue(); grainLength = randomBetween( grainLengthMin, grainLengthMax ); // set a new fade length fadeLengthMin = fadeLenMin.getLastValue(); fadeLengthMax = fadeLenMax.getLastValue(); fadeLength = randomBetween( fadeLengthMin, fadeLengthMax ); // make sure the fade length is correct checkFadeLength(); } } } }