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

examples.be.tarsos.dsp.example.dissonance.SpectralPeakFollowerExample 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.List;

import javax.sound.sampled.UnsupportedAudioFileException;

import be.tarsos.dsp.AudioDispatcher;
import be.tarsos.dsp.AudioEvent;
import be.tarsos.dsp.AudioProcessor;
import be.tarsos.dsp.SpectralPeakProcessor;
import be.tarsos.dsp.io.PipedAudioStream;
import be.tarsos.dsp.io.TarsosDSPAudioInputStream;

public class SpectralPeakFollowerExample {	
	private final int sampleRate = 44100;
	private final int fftsize = 32768/2;
	private final int overlap = fftsize/2;//50% overlap
	//private final int noiseFloorMedianFilterLenth = fftsize/117;//35
	//private final float noiseFloorFactor = 1.5f;
	private final String fileName;
	//private final int numberOfSpectralPeaks;
	
	/**
	 * Peaks are only allowed between the highest peak minus 2400 and plus 7200 cents (8 octaves in total)
	 */
	//private final int minimumCentsBelowHighest = 2400;//2 octaves
	//private final int maximumCentsAboveHighest = 7200;//6 octaves

	
	
	private final List magnitudesList = new ArrayList();
	private final List frequencyEstimatesList = new ArrayList();
	
	
	public SpectralPeakFollowerExample(String fileName,int numberOfSpectralPeaks){
		this.fileName = fileName;
		//this.numberOfSpectralPeaks = numberOfSpectralPeaks;
		
	}
	
	private void extractPeakListList() throws UnsupportedAudioFileException{
		PipedAudioStream f = new PipedAudioStream(fileName);
		TarsosDSPAudioInputStream stream = f.getMonoStream(sampleRate,0);
		
		final SpectralPeakProcessor spectralPeakFollower = new SpectralPeakProcessor(fftsize, overlap, sampleRate);
		AudioDispatcher dispatcher = new AudioDispatcher(stream, fftsize, overlap);
		dispatcher.addAudioProcessor(spectralPeakFollower);
		dispatcher.addAudioProcessor(new AudioProcessor() {
			@Override
			public void processingFinished() {
			}
			
			@Override
			public boolean process(AudioEvent audioEvent) {
				magnitudesList.add(spectralPeakFollower.getMagnitudes());
				frequencyEstimatesList.add(spectralPeakFollower.getFrequencyEstimates());
				return true;
			}
		});
		dispatcher.run();
	}
	
	private void processPeakListList(){
		/*
		KernelDensityEstimate kde = new KernelDensityEstimate(new KernelDensityEstimate.GaussianKernel(30), minimumCentsBelowHighest + maximumCentsAboveHighest);
		for(List spectralPeakList : peakListList){
			for(SpectralPeak spectralPeak : spectralPeakList){
				//avoids peaks more than 2 octaves below the highest peak
				if(
						spectralPeak.getRelativeFrequencyInCents() + minimumCentsBelowHighest >= 0
						&&
						spectralPeak.getRelativeFrequencyInCents() <= maximumCentsAboveHighest 
				){
					//String point = String.format("%.2f;%.2f", spectralPeak.getRelativeFrequencyInCents(),spectralPeak.getMagnitude());
					for(int i = 0 ; i < Math.log(spectralPeak.getMagnitude()* 100) ; i++){
						kde.add(spectralPeak.getRelativeFrequencyInCents() + minimumCentsBelowHighest);
					}
				}
			}
		}
		
		kde.normalize(100.0);
		double[] estimate = kde.getEstimate();
		
		//all peaks are within the largest 5 percent of the estimate
		double noiseThreshold = SpectralPeakFollower.percentile(estimate.clone(),0.95);
						
		List peakValues = new ArrayList();
		for(int i  = 1 ; i < estimate.length - 1 ;i++){
			boolean largerThanPrev = estimate[i] > estimate[i-1];
			boolean largerThanNext = estimate[i] > estimate[i+1];
			boolean largerThanNoise = estimate[i] >= noiseThreshold;
			if(largerThanNoise && largerThanNext && largerThanPrev){
				peakValues.add(estimate[i]);
			}
		}
		
		double threshold = noiseThreshold;
		if(peakValues.size()>numberOfSpectralPeaks){
			Collections.sort(peakValues);
			threshold = peakValues.get(peakValues.size()-numberOfSpectralPeaks);
		}
		
		
		System.out.println("Cent Amplitude ratio");
		for(int i  = 1 ; i < estimate.length - 1 ;i++){
			boolean largerThanPrev = estimate[i] > estimate[i-1];
			boolean largerThanNext = estimate[i] > estimate[i+1];
			boolean largerThanThreshold = estimate[i] >= threshold;
			if(largerThanThreshold && largerThanNext && largerThanPrev){
				int cents = i - minimumCentsBelowHighest;
				double ratio = 0;
				if(cents != 0){
					ratio = PitchConverter.centToRatio(cents);
				}
				System.out.println(String.format("%d %.2f %.2f",cents, estimate[i],ratio));
			}
		}
		*/
	}
	
	public static void main(String... args) throws UnsupportedAudioFileException {		
		String fileName = args[0];
		
		final int numberOfSpectralPeaks;
		if(args.length == 2){
			numberOfSpectralPeaks = Integer.parseInt(args[1]);
		}else{
			numberOfSpectralPeaks = 10;
		}
		
		SpectralPeakFollowerExample spfe = new SpectralPeakFollowerExample(fileName,numberOfSpectralPeaks);
		spfe.extractPeakListList();
		spfe.processPeakListList();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy