package de.maramuse.soundcomp.generator;
/*
* 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
*/
/**
* A sawtooth generator generating a periodic rising ramp only sawtooth signal in the value range [0, 1[
*
* This is the common base for many phase accumulating oscillators in SoundComp. the range [0,1[ is then
* interpreted as one complete oscillation period (e.g. stretched to 0..2pi for a sine)
*
* It provides the following control inputs:
* - frequency in Hz
* - sync: reset and hold the phase on input value==1 (level sensitive, not transient sensitive!)
* - syncphase: the initial value the phase is set to when sync==1; default is 0
* (only the fractional part is taken, the integer part disregarded)
*/
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.GlobalParameters;
import de.maramuse.soundcomp.util.NativeObjects;
import de.maramuse.soundcomp.util.ReadOnlyMap;
import de.maramuse.soundcomp.util.ReadOnlyMapImpl;
public class UnitySawTooth implements ProcessElement, Stateful {
private long nativeSpace;
private double sampleRate=GlobalParameters.get().getSampleRate();
public UnitySawTooth() {
NativeObjects.registerNativeObject(this);
}
UnitySawTooth(boolean s) {
}
private static final ReadOnlyMapImpl<Integer, ValueType> destTypeMap=new ReadOnlyMapImpl<Integer, ValueType>();
static{
destTypeMap.put(StandardParameters.FREQUENCY.i, ValueType.STREAM);
destTypeMap.put(StandardParameters.SYNCPHASE.i, ValueType.STREAM);
destTypeMap.put(StandardParameters.SYNC.i, ValueType.STREAM);
}
protected static final ReadOnlyMapImpl<Integer, ValueType> sourceTypeMap=new ReadOnlyMapImpl<Integer, ValueType>();
static{
sourceTypeMap.put(StandardParameters.OUT.i, ValueType.STREAM);
}
private static ParameterMap inputsMap=new ParameterMap();
private static ParameterMap outputsMap=new ParameterMap();
static{
inputsMap.put(StandardParameters.FREQUENCY);
inputsMap.put(StandardParameters.SYNC);
inputsMap.put(StandardParameters.SYNCPHASE);
outputsMap.put(StandardParameters.OUT);
}
private final ReadOnlyMapImpl<Integer, SourceStore> sourceStoreMap=new ReadOnlyMapImpl<Integer, SourceStore>();
protected double phase=0d;
protected double val=0d, _val=0d;
SourceStore freq=null;
SourceStore sync=null;
SourceStore syncphase=null;
private String instanceName, abstractName;
@Override
public ReadOnlyMap<Integer, ValueType> getDestinationTypes() {
return destTypeMap;
}
@Override
public void setSource(int connection, NamedSource source,
int sourceIndex) throws UnknownConnectionException,
TypeMismatchException {
if(connection==StandardParameters.FREQUENCY.i){
if(source.getSourceTypes().containsKey(sourceIndex)){
freq=new SourceStore(source, sourceIndex);
sourceStoreMap.put(connection, freq);
}else
throw new UnknownConnectionException("unknown source for generator frequency");
}else if(connection==StandardParameters.SYNC.i){
if(source.getSourceTypes().containsKey(sourceIndex)){
sync=new SourceStore(source, sourceIndex);
sourceStoreMap.put(connection, sync);
}else
throw new UnknownConnectionException("unkown source for generator sync");
}else if(connection==StandardParameters.SYNCPHASE.i){
if(source.getSourceTypes().containsKey(sourceIndex)){
syncphase=new SourceStore(source, sourceIndex);
sourceStoreMap.put(connection, syncphase);
}else
throw new UnknownConnectionException("unkown source for generator syncphase");
}else
throw new UnknownConnectionException("attempt to set unknown generator parameter");
}
@Override
public ReadOnlyMap<Integer, ValueType> getSourceTypes() {
return sourceTypeMap;
}
@Override
public double getValue(int index) {
return val;
}
@Override
public void advanceState() {
if(freq!=null)
phase+=freq.getValue()/sampleRate;
phase=phase-Math.floor(phase);
if(sync!=null)
if(sync.getValue()==1d){
if(syncphase!=null)
phase=syncphase.getValue();
else
phase=0d;
}
_val=phase;
}
@Override
public void advanceOutput() {
val=_val;
}
@Override
public String getAbstractName() {
return abstractName;
}
@Override
public String getInstanceName() {
return instanceName;
}
@Override
public void setAbstractName(String abstractName) {
this.abstractName=abstractName;
}
@Override
public void setInstanceName(String instanceName) {
this.instanceName=instanceName;
}
@Override
public long getNativeSpace() {
return nativeSpace;
}
@Override
public ReadOnlyMap<Integer, SourceStore> getSourceMap() {
return sourceStoreMap;
}
/**
* @see de.maramuse.soundcomp.process.ProcessElement#clone()
*/
@Override
public UnitySawTooth clone() {
UnitySawTooth c=new UnitySawTooth();
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;
}
}