view src/samer/midi/MidiRecorder.java @ 0:bf79fb79ee13

Initial Mercurial check in.
author samer
date Tue, 17 Jan 2012 17:50:20 +0000
parents
children
line wrap: on
line source
/*
 *	Copyright (c) 2000, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS iS and WITHOUT ANY WARRANTY;
 *	without even the implied warranty of MERCHANTABILITY or
 *	FITNESS FOR A PARTICULAR PURPOSE.
 */

package samer.midi;
import samer.core.*;
import samer.core.types.*;
import samer.tools.*;
import samer.maths.*;
import java.util.*;
import java.io.*;
import javax.sound.midi.*;

/**
	Attempts to do some temporal smoothing on the
	imput vector. Its a bit like a median filter.
	A note doesn't switch on until the corresponding
	vector element has been above threshold for
	<countThresh> consecutive steps, and similarly
	for switching off.
  */

public class MidiRecorder extends MidiRecorderBase implements Task
{
	Vec in;
	int n;
	int [] nnums, chans;
	double [] x;
	VInteger	offset;
	VBoolean pedal;
	VDouble factor;

	public MidiRecorder(Vec input) throws Exception {

		Shell.push(node);
		factor = new VDouble("factor",128,0);
		offset = new VInteger("offset",0,0);
		pedal  = new VBoolean("pedal",false,0);
		// setAgent(this);
		// addAgent(new Saver(this));
		Shell.pop();

		in = input;
		n = in.size();
		x = in.array();

		nnums = new int[n];
		chans = new int[n];
		for (int i=0; i<n; i++) { nnums[i]=i; chans[i]=0; }
	}

	public int mapVelocity(double x) {
		int vel=(int)(factor.value*x);
		if (vel>127) vel=127;
		return vel;
	}

	public void dispose() {}
	public void starting() {}
	public void stopping() {}

	public void run()
	{
		for (int i=0; i<n; i++) {

			if (x[i]>0) {
					int nnum=nnums[i]+offset.value;
					int vel=mapVelocity(x[i]);
					noteOn(chans[i],nnum, vel);
			} else if (x[i]<0 && !pedal.value) {
					int nnum=nnums[i]+offset.value;
					noteOff(chans[i],nnum);
			}
		}
		tick();
	}
}