﻿
var gMidiToKeyFramesParams;
{
#include "../omino_adobe_script_suite/src/shared/ominoDialogMaker.jsx"
#include "midi_reader.jsx"
 
 
function setChar(s,pos,c)
{
	while(s.length < pos)
		s += "_";
	
	s = s.substring(0,pos - 1) + c + s.substring(pos + 1,s.length);
	return s;
}
function go()
{
	
	// setting up a dialog is easy. you can add entries for basic types of
	// string and number, and checkbox and radio buttons, and the 
	// dialog is presented reasonably, with very little work.
	
	var omd = newOminoDialog("Midi File To Keyframes");

	omd.boxedText(5,"This script reads a MIDI file, and generates \n"
		+ "control text for it, matching note-on velocities to \n"
		+ "letters a-z.");
	omd.number("width","width",12);
	omd.checkbox("existing keys","deleteAllKeys",true,"delete");

	omd.openFile("midi file","midiFileName","","Choose a MIDI File",".mid");
 
	// when we "run" the dialog, we get back a result variable.
	// if you hit CANCEL, then the result is null.
	// if you hit OK, then the values are populated into the result.
	
	// note: you can kill photoshop by running the dialog from ExtendScript toolkit, then halting
	// the script with the dialog still up.
	
	omd.set(gMidiToKeyFramesParams);
	var result = omd.run();
	
	if(result == null)
		alert("Cancelled\nYou clicked \"cancel\".");
	else
	{
		gMidiToKeyFramesParams = result;

		var myComp = app.project.activeItem;
		var selectedLayers;
		if(myComp instanceof CompItem)
			selectedLayers = myComp.selectedLayers;
		else
			selectedLayers = new Array();
		
		var selectedLayer = selectedLayers[0];
		var tp = selectedLayer("Text")("Source Text");
		// TODO: delete all keyframes first
		if(result.deleteAllKeys)
		{
			var n = tp.numKeys;
			while(n--)
			{
				tp.removeKey(1);
			}
		}

		midiFile = new MidiFile(result.midiFileName);
		var notes = midiFile.notes;
		var duration = notes[notes.length - 1].time; // last event, in seconds

		alert("duration: " + duration);
		var pb = progressBar("Setting " + notes.length + " Keyframes");
		var lastValue = "";
		var lastTime = 0;
		var width = result.width;
		for(var i = 0; i < notes.length; i++)
		{
			pb.setTitle2(i);
			pb.setValue(i / notes.length);
			if(pb.isCanceled())
				break;
			var note = notes[i];
			if(note.vel > 0)
			{
				var time = note.time;
				var value = "";
				if(time == lastTime)
					value = lastValue;
				var pitch = note.pitch;
				var vel = note.vel;
				var c = String.fromCharCode(65 + vel * 25 / 127);
				value = setChar(value,pitch % width,c);
				//tp.setValueAtTime(time,value); //"-" + note.pitch + "-");
				lastValue = value;
				lastTime = time;
			}
		}
		pb.close();
		
	}
}

go();
}