Package de.maramuse.soundcomp.shaping

Source Code of de.maramuse.soundcomp.shaping.Third

package de.maramuse.soundcomp.shaping;

/*
* 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 a distortion third order characteristics effect for nonlinear signal distortion
*
* previous to applying the characteristics, the signal has to be clipped to [-1; 1]
*
* theory for the characteristics:
*
* 2 branches: first for (x of ymax) <=1:
*
* y=ax-bx^3
*
* derived y' = a - 3bx^2
*
* Extrema at y'=0: a-3bx^2=0 => Xn=sqr(a/3b)
*
* Values of Extrema:
*
* y=a*sqr(a/3b) -  b * a/3b * sqr(a/3b) = a*sqr(a/3b) - a/3 * sqr(a/3b) = 2/3 a sqr(a/3b) = 2/3 a Xn
*
* Therefore y(Extrema)=1 : y=1 => a = 3/(2Xn)
* for b: 1 = 3/2 - b Xn^3 => b Xn^3 = 1/2, b = 1/2 Xn^-3
*
* Function therefore y = (3/2 Xn^-1) x - (1/2 Xn^-3)x^3
*
* Minimum: Xn=1, y=1: a=3/2, b=1/2
* Maximum: y(1)=-1
*
* -1 = 3/2 Xn^-1 - 1/2 Xn^-3
* 1 = 1/2 Xn^-3 - 3/2 Xn^-1
* Xn = -3/2 + 1/2 Xn^-2
*
* Xn^3 - 1/2 + 3/2 Xn^2 = 0
*
* Xn (min) = 0.5, a(max)=3,   b(max)=4
* Xn (max) = 1.0, a(min)=3/2, b(min)=1/2
*
* a=3/2 Xn^-1; b=(1/2 Xn^3) = 4/27 a^3
*
* Branch for x(Extrema)>1:
*
* Only condition is y(1)=1, so: 1 = a - b. Limits are a < 3/2, b < 1/2.
* Linear solution is a(min)=1, b(min)=0
*
* Final Parametrisation:
*  Linear at a=1, b=0. Then increment a until a=1.5, let b grow by the same.
*  Then until a=3, b=4/27*a^3.
*  Since the characteristics parameter m should be 0<=m<=1,
*  a = 2 * m +1
*  b = ((m<0.25)?(a-1):(4/27*a^3));
*
* Input signal must be limited to [-1; 1]
* characteristics parameter must be clipped to [0; 1]
*
* @author jssr67
*
*/
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.ReadOnlyMap;
import de.maramuse.soundcomp.util.ReadOnlyMapImpl;
import de.maramuse.soundcomp.util.NativeObjects;

public class Third implements ProcessElement, Stateful {
  public long nativeSpace=-1;

  public Third() {
  NativeObjects.registerNativeObject(this);
  }

  Third(boolean s) {
  }

  private static ReadOnlyMapImpl<Integer, ValueType> destMap=new ReadOnlyMapImpl<Integer, ValueType>(),
    sourceMap=new ReadOnlyMapImpl<Integer, ValueType>();
  static{
  sourceMap.put(StandardParameters.OUT.i, ValueType.STREAM);
  destMap.put(StandardParameters.IN.i, ValueType.STREAM);
  destMap.put(StandardParameters.NONLINEARITY.i, ValueType.STREAM);
  }

  private final ReadOnlyMapImpl<Integer, SourceStore> sourceStoreMap=new ReadOnlyMapImpl<Integer, SourceStore>();
  private static ParameterMap inputsMap=new ParameterMap();
  private static ParameterMap outputsMap=new ParameterMap();
  static{
  inputsMap.put(StandardParameters.NONLINEARITY);
  inputsMap.put(StandardParameters.IN);
  outputsMap.put(StandardParameters.OUT);
  }
  SourceStore nonlin, in;
  double nonlinval, inval, outval=0d, _outval=0d;
  String instanceName, abstractName;

  @Override
  public ReadOnlyMap<Integer, ValueType> getDestinationTypes() {
  return destMap;
  }

  @Override
  public void setSource(int connectionIndex, NamedSource source,
            int sourceIndex) throws UnknownConnectionException,
      TypeMismatchException {
  SourceStore ss=new SourceStore(source, sourceIndex);
  sourceStoreMap.put(connectionIndex, ss);
  if(!source.getSourceTypes().containsKey(sourceIndex))
    throw new UnknownConnectionException("attempt to set invalid signal shaping source");
  if(connectionIndex==StandardParameters.IN.i){
    in=ss;
  }else if(connectionIndex==StandardParameters.NONLINEARITY.i){
    nonlin=ss;
  }else
    throw new UnknownConnectionException("attempt to provide unkown signal shaping parameter");
  }

  @Override
  public ReadOnlyMap<Integer, ValueType> getSourceTypes() {
  return sourceMap;
  }

  @Override
  public double getValue(int index) {
  return outval;
  }

  @Override
  public void advanceState() {
  nonlinval=Math.abs(nonlin.getValue());
  if(nonlinval>1.0)
    nonlinval=1.0;
  inval=in.getValue();
  if(inval<-1.0)
    inval=-1.0;
  else if(inval>1.0)
    inval=1.0;
  double a=2*nonlinval+1d;
  double b=((nonlinval<0.25) ? (a-1) : (4d/27d*a*a*a));
  _outval=a*inval-b*inval*inval*inval;
  }

  @Override
  public void advanceOutput() {
  outval=_outval;
  }

  @Override
  public String getInstanceName() {
  return instanceName;
  }

  @Override
  public void setInstanceName(String instanceName) {
  this.instanceName=instanceName;
  }

  @Override
  public String getAbstractName() {
  return abstractName;
  }

  @Override
  public void setAbstractName(String abstractName) {
  this.abstractName=abstractName;
  }

  @Override
  public long getNativeSpace() {
  return nativeSpace;
  }

  @Override
  public ReadOnlyMap<Integer, SourceStore> getSourceMap() {
  return sourceStoreMap;
  }

  /**
   * @see de.maramuse.soundcomp.process.ProcessElement#clone()
   */
  @Override
  public Third clone() {
  Third c=new Third();
  c.abstractName=abstractName;
  return c;
  }

  /*
   * (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;
  }
}
TOP

Related Classes of de.maramuse.soundcomp.shaping.Third

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.