Skip to content

Instantly share code, notes, and snippets.

@tedthetrumpet
Created January 22, 2023 07:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tedthetrumpet/027fd8c5f1ea645b285d3f90642dbe40 to your computer and use it in GitHub Desktop.
Save tedthetrumpet/027fd8c5f1ea645b285d3f90642dbe40 to your computer and use it in GitHub Desktop.
Stuck on implementing constrained random walk with rests in SuperCollider
Pjsline2 : Pattern {
var <>lo, <>hi, <>step, <>length;
*new { arg lo=0, hi=12, step=[2,3], length=inf;
^super.newCopyArgs(lo, hi, step, length)
}
storeArgs { ^[lo,hi,step,length] }
embedInStream { arg inval;
var cur;
var curBefore;
var stepWas;
var loStr = lo.asStream, loVal;
var hiStr = hi.asStream, hiVal;
var stepStr = step.asStream, stepVal;
loVal = loStr.next(inval);
hiVal = hiStr.next(inval);
stepVal = stepStr.next(inval);
cur = rrand(loVal, hiVal); // start at random point?
if(loVal.isNil or: { hiVal.isNil } or: { stepVal.isNil }) { ^inval };
length.value(inval).do {
loVal = loStr.next(inval);
hiVal = hiStr.next(inval);
stepVal = stepStr.next(inval);
if(loVal.isNil or: { hiVal.isNil } or: { stepVal.isNil }) { ^inval };
curBefore = cur;
cur = this.calcNext(cur, stepVal, stepWas).fold(loVal, hiVal);
stepWas = cur - curBefore;
// need to do the calculation and testing up here?
inval = cur.yield;
};
^inval;
}
calcNext { arg cur, step, stepWas;
var nextStep;
nextStep = step.choose;
nextStep * [1,-1].choose;
if(nextStep == stepWas) {
cur = Rest();
^cur // if we return Rest() then it ruins the calculation of stepWas above
} {
cur = cur + nextStep;
^cur;
};
}
}
Pjsline : Pattern {
var <>lo, <>hi, <>step, <>length;
*new { arg lo=0, hi=12, step=[2,3], length=inf;
^super.newCopyArgs(lo, hi, step, length)
}
storeArgs { ^[lo,hi,step,length] }
embedInStream { arg inval;
var cur;
var loStr = lo.asStream, loVal;
var hiStr = hi.asStream, hiVal;
var stepStr = step.asStream, stepVal;
loVal = loStr.next(inval);
hiVal = hiStr.next(inval);
stepVal = stepStr.next(inval);
cur = rrand(loVal, hiVal);
if(loVal.isNil or: { hiVal.isNil } or: { stepVal.isNil }) { ^inval };
length.value(inval).do {
loVal = loStr.next(inval);
hiVal = hiStr.next(inval);
stepVal = stepStr.next(inval);
if(loVal.isNil or: { hiVal.isNil } or: { stepVal.isNil }) { ^inval };
cur = this.calcNext(cur, stepVal).fold(loVal, hiVal);
inval = cur.yield;
};
^inval;
}
calcNext { arg cur, step;
// this is the function that makes the new step
// so need to get rid of repeated steps here
step = step * [1,-1].choose; // randomly up or down
// choose a nextStep nextStep = step.choose
// choose a direction nextStep = nextStep * [1,-1].choose
// now we have -3,-2,2, or 3, for example
// how do we know what the last step was?
// we don't?
// we know what the current value is, before we make the step
// we don't know what the value before was
// or do we? in which case could infer the last step by, er, subracting?
^cur + step.choose;
}
}
// from hjh
Pantibis : FilterPattern {
embedInStream { |inval|
var stream = pattern.asStream;
var previous, next;
while {
next = stream.next(inval);
next.notNil
} {
if(next == previous) {
inval = Rest(next).yield;
} {
previous = next;
inval = next.yield;
};
};
^inval
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment