All Downloads are FREE. Search and download functionalities are using the official Maven repository.

examples.be.tarsos.dsp.example.dissonance.SensoryDissonanceCurve Maven / Gradle / Ivy

The newest version!
/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/

package be.tarsos.dsp.example.dissonance;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SensoryDissonanceCurve {
	
	private final double range;
	private final double increment = 0.005;
	
	private final List curve;
	
	private final double dstar = 0.24;
	private final double s1= 0.0207;
	private final double s2=18.96;
	private final double c1=5;
	private final double c2=-5;
	private final double a1 = -3.51;
	private final double a2 = -5.75;
	
	public SensoryDissonanceCurve(){
		this(2.3);
	}
	
	/**
	 * Calcultate the dissonance curve until this factor. 2.3 means 
	 * one octave and one sixth of an octave. 
	 * @param range
	 */
	private SensoryDissonanceCurve(double range){
		this.range = range;
		this.curve = new ArrayList();
	}
	
	
	public List calculate(List frequencies,List amplitudes){
		curve.clear();
		curve.add(new SensoryDissonanceResult(1.0, 0.0, frequencies.get(0)));
		for(double alpha = 1 + increment; alpha<=range; alpha += increment ){
			List f = new ArrayList(frequencies);
			List a = new ArrayList(amplitudes);
			for(Double frequency:frequencies){
				f.add(alpha*frequency);
			}
			for(Double amplitude:amplitudes){
				a.add(amplitude);
			}
			double d = dissonanceMeasure(f, a);
			
			curve.add(new SensoryDissonanceResult(alpha, d, frequencies.get(0)));
		}
		return curve;
	}
	
	public List valleys(List results){
		List valleys = new ArrayList();
		for(int i = 1 ; i < results.size()-1; i++){
			SensoryDissonanceResult prevResult = results.get(i-1); 
			SensoryDissonanceResult currentResult = results.get(i);
			SensoryDissonanceResult nextResult = results.get(i+1);
			if(currentResult.dissonanceValue < nextResult.dissonanceValue && currentResult.dissonanceValue < prevResult.dissonanceValue){
				double rightSlope =  (nextResult.dissonanceValue - currentResult.dissonanceValue)/increment;
				double leftSlope =  (prevResult.dissonanceValue - currentResult.dissonanceValue)/increment;				
				if(rightSlope > 0.15 && leftSlope > 0.15){
					valleys.add(currentResult);
				}
			}
		}
		return valleys;
	}
	
	public double dissonanceMeasure(final List frequencies , List amplitudes){
		
		int n = frequencies.size();
		double d = 0;
		
		Collections.sort(frequencies);
		
		//create a list with indexes
		final Integer[] indexes = new Integer[frequencies.size()];
		for(int i = 0;i() {
			@Override 
			public int compare(final Integer o1, final Integer o2) {
				return Double.compare(frequencies.get(o1), frequencies.get(o2));
			}
		});
		
		List sortedFrequencies = new ArrayList(frequencies.size());
		List sortedAmplitudes = new ArrayList(frequencies.size());
		
		//create sorted frequency and amplitude lists
		for(int i = 0;i fmin = new ArrayList(sortedFrequencies.subList(0, n - i + 1));
			for(int j = 0 ; j < fmin.size() ; j++){
				fmin.set(j, dstar / (s1*fmin.get(j)+s2));
			}
			
			List fdiff = new ArrayList();
			for(int j = i-1 ; j < sortedFrequencies.size(); j++){
				fdiff.add(sortedFrequencies.get(j) - sortedFrequencies.get(j-i+1));
			}
			
			List a = new ArrayList();
			for(int j = i - 1 ; j < sortedFrequencies.size() ; j++){
				a.add(sortedAmplitudes.get(j));
			}
			
			for(int j = 0 ; j < a.size() ; j++){
				double element= c1 * Math.exp(a1*fmin.get(j)*fdiff.get(j));
				double other = c2 * Math.exp(a2*fmin.get(j)*fdiff.get(j));
				d += a.get(j)* (element + other);
			}
			
		}
		return d;
	}
	
	
	public static void main(String...strings){
		
		List frequencies = new ArrayList();
		frequencies.add(440.0*1);
		frequencies.add(440.0*2);
		frequencies.add(440.0*3);
		frequencies.add(440.0*4);
		frequencies.add(440.0*5);
		//frequencies.add(440.0*6);
		//frequencies.add(440.0*7);
		//frequencies.add(440.0*8);
		
		List amplitudes = new ArrayList();
		amplitudes.add(Math.pow(0.88, 0));
		amplitudes.add(Math.pow(0.88, 1));
		amplitudes.add(Math.pow(0.88, 2));
		amplitudes.add(Math.pow(0.88, 3));
		amplitudes.add(Math.pow(0.88, 4));
		//amplitudes.add(Math.pow(0.88, 5));
		//amplitudes.add(Math.pow(0.88, 6));
		//amplitudes.add(Math.pow(0.88, 7));
		
		SensoryDissonanceCurve sdc = new SensoryDissonanceCurve();
		
		System.out.println("Expect  0.0049863 is " + sdc.dissonanceMeasure(frequencies,amplitudes));
		
		sdc.calculate(frequencies, amplitudes);
	}
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy