Package de.maramuse.soundcomp.process

Source Code of de.maramuse.soundcomp.process.Scale$ScaleElement

/*
* 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 scale is a table that maps "note names" to frequencies and other pitch related event information.
* It is instantiated per voice, not per process.
* The relevant information is queried on event generation and copied over to the event.
* Although it has a native stub for structural completeness reasons,
* it is not meant to be used in native context under any circumstances.
*/
package de.maramuse.soundcomp.process;

import java.util.Map;
import java.util.TreeMap;


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;
import de.maramuse.soundcomp.util.NotImplementedException;

public class Scale implements NamedSource {
  // a scale is a multicolumn table with multiple indexes:
  // 1. index="name" (String), 2. index="index" (integer)
  // and the following columns: frequency (real), pitch(integer), nextpitch (integer), prevpitch(integer)
  // the prev and next may be null (at the ends of the scale. it is then impossible to advance further in transposing)
  protected static class ScaleElement {
  public final String name;
  public final double frequency;
  public final int pitch;
  public final Integer nextpitch;
  public final Integer prevpitch;

  public ScaleElement(final String name, final double frequency, final int pitch,
            final Integer nextpitch, final Integer prevpitch) {
    this.name=name;
    this.frequency=frequency;
    this.pitch=pitch;
    this.nextpitch=nextpitch;
    this.prevpitch=prevpitch;
  }

  public ScaleElement(ScaleElement el) {
    this.name=el.name;
    this.frequency=el.frequency;
    this.pitch=el.pitch;
    this.nextpitch=el.nextpitch;
    this.prevpitch=el.prevpitch;
  }
  }

  private long nativeSpace;
  protected String abstractName;
  protected String instanceName;
  protected Map<String, ScaleElement> theTableByName=new TreeMap<String, ScaleElement>();
  protected Map<Integer, ScaleElement> theTableByIndex=new TreeMap<Integer, ScaleElement>();
  private static ParameterMap outputsMap=new ParameterMap();
  private static ReadOnlyMapImpl<Integer, ValueType> sourceTypes=new ReadOnlyMapImpl<Integer, ValueType>();

  public Scale(){
  NativeObjects.registerNativeObject(this);
  }
 
  public Scale(boolean s){
  }
 
  public void put(String name, double freq, int pitch, Integer next, Integer prev) {
  ScaleElement elem=new ScaleElement(name, freq, pitch, next, prev);
  theTableByName.put(name, elem);
  theTableByIndex.put(pitch, elem);
  }

  public void put(ScaleElement elem) {
  theTableByName.put(elem.name, elem);
  theTableByIndex.put(elem.pitch, elem);
  }

  /**
   * get the frequency to the note "o"
   *
   * @param o
   *          the name of the note whose frequency we want
   * @return the frequency
   */
  public double get(String o) {
  try{
    return theTableByName.get(o).frequency;
  }catch(Exception ex){
    return Double.NaN;
  }
  }

  /**
   * get the pitch (table index) to the note "o"
   *
   * @param o
   *          the name of the note whose frequency we want
   * @return the frequency. If "o" does not exist, return MIN_VALUE
   */
  public int getPitch(String o) {
  try{
    return theTableByName.get(o).pitch;
  }catch(Exception ex){
    return Integer.MIN_VALUE;
  }
  }

  /**
   * get the frequency to the note "o"
   *
   * @param o
   *          the pitch of the note whose frequency we want
   * @return the frequency
   */
  public double get(int o) {
  try{
    return theTableByIndex.get(o).frequency;
  }catch(Exception ex){
    return Double.NaN;
  }
  }

  /**
   * get the frequency of the note "o" transposed by "trans"
   *
   * @param o
   * @param trans
   * @return
   */
  public double get(String o, int trans) {
  try{
    int index=theTableByName.get(o).pitch;
    return theTableByIndex.get(index+trans).frequency;
  }catch(Exception ex){
    return Double.NaN;
  }
  }

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

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

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

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

  @Override
  public void advanceState() {
  // nothing to do
  }

  @Override
  public void advanceOutput() {
  // nothing to do
  }

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

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

  /**
   * getValue throws an exception. It is not meant to be called.
   */
  @Override
  public double getValue(int index){
  throw new NotImplementedException();
  }

  /**
   * This is called on event generation
   * @param index the pitch
   * @return the frequency for pitch "index"
   */
  public double getValueFor(int index) {
  ScaleElement elem=theTableByIndex.get(index);
  if(elem==null)throw new IllegalArgumentException("no scale entry in scale "+abstractName+" for key "+index);
  return elem.frequency;
  }

  /**
   * This is called on event generation
   * @param name the note name for this event
   * @return the frequency for the pitch "name" transposed by "transpose"
   */
  public double getValueFor(String name) {
  ScaleElement elem=theTableByName.get(name);
  if(elem==null)throw new IllegalArgumentException("no scale entry in scale "+abstractName+" for name "+name);
  return elem.frequency;
  }

  /**
   * This is called on event generation
   * @param name the note name for this event
   * @param transpose the pitch transpose value
   * @return the frequency for the pitch "name" transposed by "transpose"
   */
  public double getValueFor(String name, int transpose) {
  ScaleElement elem=theTableByName.get(name);
  if(elem==null)throw new IllegalArgumentException("no scale entry in scale "+abstractName+" for name "+name);
  int index=elem.pitch+transpose;
  elem=theTableByIndex.get(index);
  if(elem==null)throw new IllegalArgumentException("no scale entry in scale "+abstractName+" for name "+name+" transposed by "+transpose);
  return elem.frequency;
  }

  @Override
  public ReadOnlyMap<String, Parameter> outputsByName() {
  return outputsMap;
  }
}
TOP

Related Classes of de.maramuse.soundcomp.process.Scale$ScaleElement

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.