/*
* Copyright 2010 Jan Schmidt-Reinisch
*
* SoundComp - a sound processing library
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; in version 2.1
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* This is an extremely simple distortion effect.
* This element has 3 stream inputs: one low limit, the alleged signal and one high limit
* If the signal is beyond the limits, the output will be the violated limit.
* If the signal is within the limits, the output will be the signal.
* If the limits contradict, the output will be the average of the limits.
* You should prevent that from happening dynamically.
* If a limit is NaN or infinite, it will be disregarded and not influence the output
* (so upper-side-only or lower-side-only limits are possible).
*/
package de.maramuse.soundcomp.shaping;
import de.maramuse.soundcomp.process.NamedSource;
import de.maramuse.soundcomp.process.ParameterMap;
import de.maramuse.soundcomp.process.ProcessElement;
import de.maramuse.soundcomp.process.SourceStore;
import de.maramuse.soundcomp.process.StandardParameters;
import de.maramuse.soundcomp.process.Stateful;
import de.maramuse.soundcomp.process.TypeMismatchException;
import de.maramuse.soundcomp.process.UnknownConnectionException;
import de.maramuse.soundcomp.process.ValueType;
import de.maramuse.soundcomp.process.StandardParameters.Parameter;
import de.maramuse.soundcomp.util.NativeObjects;
import de.maramuse.soundcomp.util.ReadOnlyMap;
import de.maramuse.soundcomp.util.ReadOnlyMapImpl;
public class Clip implements ProcessElement, Stateful {
private String abstractName, instanceName;
private long nativeSpace;
private double _out=0d, out=0d;
public Clip() {
NativeObjects.registerNativeObject(this);
}
Clip(boolean s) {
}
private static ReadOnlyMapImpl<Integer, ValueType> destinationTypes=new ReadOnlyMapImpl<Integer, ValueType>(),
sourceTypes=new ReadOnlyMapImpl<Integer, ValueType>();
static{
sourceTypes.put(StandardParameters.OUT.i, ValueType.STREAM);
destinationTypes.put(StandardParameters.IN.i, ValueType.STREAM);
destinationTypes.put(StandardParameters.LOW.i, ValueType.STREAM);
destinationTypes.put(StandardParameters.HIGH.i, ValueType.STREAM);
}
private ReadOnlyMapImpl<Integer, SourceStore> sourceMap=new ReadOnlyMapImpl<Integer, SourceStore>();
private static ParameterMap inputsMap=new ParameterMap();
private static ParameterMap outputsMap=new ParameterMap();
static{
inputsMap.put(StandardParameters.LOW);
inputsMap.put(StandardParameters.HIGH);
inputsMap.put(StandardParameters.IN);
outputsMap.put(StandardParameters.OUT);
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.ProcessElement#getDestinationTypes()
*/
@Override
public ReadOnlyMap<Integer, ValueType> getDestinationTypes() {
return destinationTypes;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.ProcessElement#getSourceMap()
*/
@Override
public ReadOnlyMap<Integer, SourceStore> getSourceMap() {
return sourceMap;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.ProcessElement#setSource(int, de.maramuse.soundcomp.process.NamedSource, int)
*/
@Override
public void setSource(int connectionIndex, NamedSource source,
int sourceIndex) throws UnknownConnectionException,
TypeMismatchException {
if(connectionIndex==StandardParameters.IN.i||
connectionIndex==StandardParameters.LOW.i||
connectionIndex==StandardParameters.HIGH.i)
sourceMap.put(connectionIndex, new SourceStore(source, sourceIndex));
else
throw new UnknownConnectionException("attempt to provide unkown signal shaping parameter");
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.NamedSource#getSourceTypes()
*/
@Override
public ReadOnlyMap<Integer, ValueType> getSourceTypes() {
return sourceTypes;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.NamedSource#getValue(int)
*/
@Override
public double getValue(int index) {
return out;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#advanceOutput()
*/
@Override
public void advanceOutput() {
out=_out;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#advanceState()
*/
@Override
public void advanceState() {
double middle=sourceMap.get(StandardParameters.IN.i).getValue();
double low=sourceMap.get(StandardParameters.LOW.i).getValue();
double high=sourceMap.get(StandardParameters.HIGH.i).getValue();
boolean lowvalid=!Double.isInfinite(low)&&!Double.isNaN(low);
boolean highvalid=!Double.isInfinite(high)&&!Double.isNaN(high);
if(lowvalid&&highvalid){
if(low>high)
_out=low+high/2;
else if(middle<low)
_out=low;
else if(middle>high)
_out=high;
else
_out=middle;
}else if(lowvalid){
if(middle<low)
_out=low;
else
_out=middle;
}else if(highvalid){
if(middle>high)
_out=high;
else
_out=middle;
}else
_out=middle;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#getAbstractName()
*/
@Override
public String getAbstractName() {
return abstractName;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#getInstanceName()
*/
@Override
public String getInstanceName() {
return instanceName;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#setAbstractName(java.lang.String)
*/
@Override
public void setAbstractName(String abstractName) {
this.abstractName=abstractName;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.SampleAdvancer#setInstanceName(java.lang.String)
*/
@Override
public void setInstanceName(String instanceName) {
this.instanceName=instanceName;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.NativeStub#getNativeSpace()
*/
@Override
public long getNativeSpace() {
return nativeSpace;
}
@Override
public Clip clone() {
Clip clip=new Clip();
clip.abstractName=abstractName;
return clip;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.ProcessElement#outputsByName()
*/
@Override
public ReadOnlyMap<String, Parameter> outputsByName() {
return outputsMap;
}
/*
* (non-Javadoc)
*
* @see de.maramuse.soundcomp.process.ProcessElement#inputsByName()
*/
@Override
public ReadOnlyMap<String, Parameter> inputsByName() {
return inputsMap;
}
}