I've written a couple of methods that allow demand ugens as trig and
reset args for the Demand UGen, their values being interpreted as
times for the next trigger/reset to occur. Currently they are
assembled in a separate ugen (DurDemand), but reusing the m_prevtrig
member variables it could be methods of Demand.
Any suggestions as to where it should go best?
attached some code:
____________
void DurDemand_next_da(DurDemand *unit, int inNumSamples)
{
float *reset = ZIN(1);
float *out[MAXCHANNELS];
float prevout[MAXCHANNELS];
for (int i=0; i<unit->mNumOutputs; ++i) {
out[i] = OUT(i);
prevout[i] = unit->m_prevout[i];
}
float count = unit->m_count;
float prevreset = unit->m_prevreset;
for (int i=0; i<inNumSamples; ++i) {
float zreset = ZXP(reset);
if (zreset > 0.f && prevreset <= 0.f) {
for (int j=2; j<unit->mNumInputs; ++j) {
RESETINPUT(j);
}
RESETINPUT(0);
}
if (count <= 0.f) {
count = DEMANDINPUT(0) * unit->mRate->mSampleRate + .5f;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
float x = DEMANDINPUT(j);
//printf("in %d %g\n", k, x);
if (sc_isnan(x)) x = prevout[k];
else prevout[k] = x;
out[k][i] = x;
}
} else {
count--;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
out[k][i] = prevout[k];
}
}
prevreset = zreset;
}
unit->m_count = count;
unit->m_prevreset = prevreset;
for (int i=0; i<unit->mNumOutputs; ++i) {
unit->m_prevout[i] = prevout[i];
}
}
void DurDemand_next_dk(DurDemand *unit, int inNumSamples)
{
float zreset = ZIN0(1);
float *out[MAXCHANNELS];
float prevout[MAXCHANNELS];
for (int i=0; i<unit->mNumOutputs; ++i) {
out[i] = OUT(i);
prevout[i] = unit->m_prevout[i];
}
float count = unit->m_count;
float prevreset = unit->m_prevreset;
for (int i=0; i<inNumSamples; ++i) {
if (zreset > 0.f && prevreset <= 0.f) {
for (int j=2; j<unit->mNumInputs; ++j) {
RESETINPUT(j);
}
RESETINPUT(0);
}
if (count <= 0.f) {
count = DEMANDINPUT(0) * unit->mRate->mSampleRate + .5f;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
float x = DEMANDINPUT(j);
//printf("in %d %g\n", k, x);
if (sc_isnan(x)) x = prevout[k];
else prevout[k] = x;
out[k][i] = x;
}
} else {
count--;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
out[k][i] = prevout[k];
}
}
prevreset = zreset;
}
unit->m_count = count;
unit->m_prevreset = prevreset;
for (int i=0; i<unit->mNumOutputs; ++i) {
unit->m_prevout[i] = prevout[i];
}
}
void DurDemand_next_dd(DurDemand *unit, int inNumSamples)
{
float *out[MAXCHANNELS];
float prevout[MAXCHANNELS];
for (int i=0; i<unit->mNumOutputs; ++i) {
out[i] = OUT(i);
prevout[i] = unit->m_prevout[i];
}
float count = unit->m_count;
float reset = unit->m_prevreset;
for (int i=0; i<inNumSamples; ++i) {
if (reset <= 0.f) {
for (int j=2; j<unit->mNumInputs; ++j) {
RESETINPUT(j);
}
RESETINPUT(0);
reset = DEMANDINPUT(1) * unit->mRate->mSampleRate + .5f;
} else {
reset--;
}
if (count <= 0.f) {
count = DEMANDINPUT(0) * unit->mRate->mSampleRate + .5f;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
float x = DEMANDINPUT(j);
//printf("in %d %g\n", k, x);
if (sc_isnan(x)) x = prevout[k];
else prevout[k] = x;
out[k][i] = x;
}
} else {
count--;
for (int j=2, k=0; j<unit->mNumInputs; ++j, ++k) {
out[k][i] = prevout[k];
}
}
}
unit->m_count = count;
unit->m_prevreset = reset;
for (int i=0; i<unit->mNumOutputs; ++i) {
unit->m_prevout[i] = prevout[i];
}
}
void DurDemand_Ctor(DurDemand *unit)
{
if (INRATE(1) == calc_FullRate) {
// if(INRATE(2) == calc_DemandRate) {
// SETCALC(DurDemand_next_ad);
// } else {
SETCALC(DurDemand_next_da);
unit->m_prevreset = 0.f;
}
} else {
if(INRATE(1) == calc_DemandRate) {
SETCALC(DurDemand_next_dd);
unit->m_prevreset = DEMANDINPUT(1) * unit->mRate->mSampleRate + .5f;
} else {
SETCALC(DurDemand_next_dk);
unit->m_prevreset = 0.f;
}
}
unit->m_count = DEMANDINPUT(0) * unit->mRate->mSampleRate + .5f;
for (int i=0; i<unit->mNumOutputs; ++i) {
unit->m_prevout[i] = 0.f;
OUT0(i) = 0.f;
}
}
--
.
_______________________________________________
sc-dev mailing list
sc-dev@xxxxxxxxxxxxxxx
http://www.create.ucsb.edu/mailman/listinfo/sc-dev