view src/uk/ac/qmul/eecs/depic/daw/referencesound/GridSound.java @ 2:c0412c81d274

Added documentation
author Fiore Martin <f.martin@qmul.ac.uk>
date Thu, 18 Feb 2016 18:35:26 +0000
parents 3074a84ef81e
children
line wrap: on
line source
/*  
 Cross-Modal DAW Prototype - Prototype of a simple Cross-Modal Digital Audio Workstation.

 Copyright (C) 2015  Queen Mary University of London (http://depic.eecs.qmul.ac.uk/)
	
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.qmul.eecs.depic.daw.referencesound;

import java.util.Timer;
import java.util.TimerTask;

import net.beadsproject.beads.core.AudioContext;
import uk.ac.qmul.eecs.depic.patterns.Range;
import uk.ac.qmul.eecs.depic.patterns.Sequence;
import uk.ac.qmul.eecs.depic.patterns.Sequence.Value;

/**
 * 
 * Sonification of the haptic grid used to edit automation points. 
 * It implements the sonification strategies we used during our studies: no reference, single 
 * reference, multiple reference. 
 * 
 * It uses an in-package modified version BeadsSequenceMapping to produce the single tones that make 
 * up the sonification. 
 * 
 *  
 *
 */
public abstract class GridSound  {
	public static final long REFERENCE_DELAY_MS = 200; 
	protected BeadsSequenceMapping mapping;
	protected Timer timer;
	public enum Type {
		NONE("none"),
		PITCH("pitch"),
		PITCH_ONE_REF("pitch one ref"),
		PITCH_MUL_REF("pitch mul ref");
		
		String toStr;
		
		Type(String s){
			toStr = s;
		}
		
		@Override
		public String toString(){
			return toStr;
		}
	}
	
	public static GridSound get(GridSound.Type type){
		
		GridSound newRepres;
				
		switch(type){
		case NONE : newRepres = new None(); break;
		case PITCH: newRepres = new Single(); break;
		case PITCH_ONE_REF : newRepres = new Ref(); break;
		case PITCH_MUL_REF : newRepres = new MulRef(); break;
		default : throw new IllegalArgumentException("Type string not recognized: " + type);
		}
		
		return newRepres;
	}
	
	protected GridSound(){
		AudioContext ac = new AudioContext();
		ac.start();
		mapping = new BeadsWaveTableSequenceMapping(ac, new Range<Float>(0.0f,0.0f),new Range<Float>(120.0f,5000.0f));
		timer = new Timer("Ref Point Timer");
	}
	
	public abstract void sound(Sequence.Value val);
	
	public abstract void ref(Sequence.Value val);
	
	
	private static class None extends GridSound {

		@Override
		public void sound(Value val) {
			// does nothing
		}

		@Override
		public void ref(Value val) {
			// does nothing
		}
	}
	
	private static class Single extends GridSound {
		
		float previousVal = Float.NaN;
		
		@Override
		public void sound(Value val) {
			if(Float.compare(val.getValue(), previousVal) != 0){
				mapping.renderValue(val);
				previousVal = val.getValue();
			};
		}

		@Override
		public void ref(Value val) {
			//does nothing
		}
	}
	
	private static class Ref extends GridSound {
		protected TimerTask lastTimerTask = new TimerTask(){public void run(){}};
		@Override
		public void sound(final Value val) {
			mapping.renderValue(val);
			
			lastTimerTask.cancel();
			
			lastTimerTask = new TimerTask(){
				
				@Override
				public void run() {
					ref(val);
				}	
			};
			timer.schedule(lastTimerTask, REFERENCE_DELAY_MS);
		}

		@Override
		public void ref(Value val) {
			mapping.renderValueOneRef(val);		
		}
	}
	
	private static class MulRef extends Ref {		

		@Override
		public void ref(Value val) {
			mapping.renderValueMulRef(val,  /*resolution =*/ 1.0f);
		}
	}
}