/* For Copyright and License see LICENSE.txt and COPYING.txt in the root directory */
package com.nerdscentral.audio.time;
import java.util.ArrayList;
import java.util.List;
import com.nerdscentral.audio.core.SFConstants;
import com.nerdscentral.audio.core.SFSignal;
import com.nerdscentral.sython.Caster;
import com.nerdscentral.sython.SFPL_Operator;
import com.nerdscentral.sython.SFPL_RuntimeException;
public class SF_Resonate implements SFPL_Operator
{
private static final long serialVersionUID = 1L;
private static class ResonantDescriptor
{
private final int delaySamples;
private final SFSignal shape;
public ResonantDescriptor(int delaySamplesIn, SFSignal shapeIn)
{
delaySamples = delaySamplesIn;
shape = shapeIn;
}
/**
* @return the delaySamples
*/
public int getDelaySamples()
{
return delaySamples;
}
/**
* @return the shape
*/
public SFSignal getShape()
{
return shape;
}
}
@Override
public String Word()
{
return Messages.getString("SF_Resonate.0"); //$NON-NLS-1$
}
@Override
public Object Interpret(Object input) throws SFPL_RuntimeException
{
List<Object> lin = Caster.makeBunch(input);
SFSignal in = Caster.makeSFSignal(lin.get(0));
lin = Caster.makeBunch(lin.get(1));
List<ResonantDescriptor> descriptors = new ArrayList<>(lin.size());
for (int i = 0; i < lin.size(); ++i)
{
List<Object> llin = Caster.makeBunch(lin.get(i));
SFSignal shape = Caster.makeSFSignal(llin.get(0));
int delay = (int) (Caster.makeDouble(llin.get(1)) * SFConstants.SAMPLE_RATE_MS);
descriptors.add(new ResonantDescriptor(delay, shape));
}
SFSignal out = in.replicate();
double r = in.getLength();
for (int n = 0; n < r; ++n)
{
double q = out.getSample(n);
boolean overflowAll = true;
endOne: for (ResonantDescriptor descriptor : descriptors)
{
SFSignal shape = descriptor.getShape();
int delay = descriptor.getDelaySamples();
int t = shape.getLength();
for (int m = 0; m < t; ++m)
{
int index = n + delay + m;
if (index >= r) break endOne;
out.setSample(index, out.getSample(index) + q * shape.getSample(m));
}
overflowAll = false;
}
if (overflowAll) break;
}
return out;
}
}