[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] SF.net SVN: quarks:[2673] KeyPlayer



Revision: 2673
          http://sourceforge.net/p/quarks/code/2673
Author:   decampo
Date:     2013-12-27 23:09:56 +0000 (Fri, 27 Dec 2013)
Log Message:
-----------
new help files, minor cleanups, updated todo notes.

Added Paths:
-----------
    KeyPlayer/Classes/
    KeyPlayer/Classes/KeyChain.sc
    KeyPlayer/Classes/KeyPlayer.sc
    KeyPlayer/Classes/KeyPlayerRec.sc
    KeyPlayer/Help/
    KeyPlayer/Help/KeyChain.html
    KeyPlayer/Help/KeyPlayer.html
    KeyPlayer/Help/KeyPlayerGui.html
    KeyPlayer/Help/KeyPlayerRec.html
    KeyPlayer/HelpSource/

Removed Paths:
-------------
    KeyPlayer/KeyChain.html
    KeyPlayer/KeyChain.sc
    KeyPlayer/KeyPlayer.html
    KeyPlayer/KeyPlayer.sc
    KeyPlayer/KeyPlayerGui.html
    KeyPlayer/KeyPlayerRec.html
    KeyPlayer/KeyPlayerRec.sc

Copied: KeyPlayer/Classes/KeyChain.sc (from rev 2667, KeyPlayer/KeyChain.sc)
===================================================================
--- KeyPlayer/Classes/KeyChain.sc	                        (rev 0)
+++ KeyPlayer/Classes/KeyChain.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,63 @@
+KeyChain {
+	classvar <all, <>verbose = false; 
+	var <key, <>list, <>index = 0, <nextIndex = 0, <nextKey, <>repeats = 1; 
+	
+	*initClass { all = () }
+	
+	*new { |key, list, index|
+		var res = all[key]; 
+		if (res.isNil) { 
+			res = super.newCopyArgs(key, list ?? { [] }, index ? 0);
+			all.put(key, res);
+		} { 
+			if (list.notNil) { res.list_(list) };
+			if (index.notNil) { res.index_(index) };
+		};
+		
+		^res
+	}
+	
+	loop { repeats = inf }
+
+	value { |...args| this.next(*args) }
+
+	next { |...args|
+		var which; 
+		index = nextIndex;
+		which = list.wrapAt(index);
+		this.findNext(which.to);
+		
+		if (which.notNil) { which.act(*args) }; 
+		
+		 if (verbose) { 
+			 "KeyChain(%) did % at %.\n".postf(key, which.key, index);
+			 "	up next: % at %.\n".postf(nextKey, nextIndex);
+		};
+	}
+
+	reset { index = 0 }
+	
+	findNext { |nextInfo| 
+		if (nextInfo.isKindOf(Symbol)) { 
+			nextIndex = list.detectIndex { |dict| dict.key == nextInfo };
+			if (nextIndex.notNil) { nextKey = nextInfo };
+		} {
+			nextIndex = nextInfo ?? { index + 1 } % list.size; 
+			nextKey = list[ nextIndex ].key;
+		}
+	}
+	
+	chooseNext { ^list.choose.to }
+	
+	act { |keys| 
+		keys.do { |key| 
+			var which;
+			which = if (key.isNumber) { 
+				list.wrapAt(key); 
+			} { 
+				list.detect { |it| it.key == key };
+			};
+			which !? { which.act };
+		};	
+	}
+}
\ No newline at end of file

Copied: KeyPlayer/Classes/KeyPlayer.sc (from rev 2667, KeyPlayer/KeyPlayer.sc)
===================================================================
--- KeyPlayer/Classes/KeyPlayer.sc	                        (rev 0)
+++ KeyPlayer/Classes/KeyPlayer.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,337 @@
+	// KeyPlayer should be able to save/write and load as code
+	//
+	// KeyPlayerGui should be a JITGui
+	// should be put itself on any window
+	// etc
+
+KeyPlayer {
+	classvar <>verbose=false, <all, gui;
+
+	var <key, <actions, <upActions, <bothActions, <pressed;
+	var <>rec;
+
+	*initClass {
+		all = ();
+	}
+	*at { |key| ^all.at(key); }
+
+	*new { arg key = \k, inDict, ignoreCase = true;
+		var kp = this.at(key);
+		if (kp.isNil) {
+			kp = super.newCopyArgs(key);
+			if (inDict.isNil, { kp.init(inDict, ignoreCase) });
+		};
+		^kp
+	}
+
+	init { arg inDict, ignoreCase = false;
+
+		all.put(key.asSymbol, this);
+
+		actions = ();
+		upActions = ();
+		pressed = ();
+		bothActions = (down: actions, up: upActions);
+
+			// this needs reworking.
+			// upactions/downactions, ignoreCase ? how?
+
+		inDict !? {
+				// it is a bothActions dict
+			[\down, \up].do { |where|
+				this.putAll(inDict[where], ignoreCase, where);
+			};
+				// else assume just keyDowns - OK?
+			inDict.keys.removeAll([\down, \up]).do { |key|
+				this.put(key, inDict[key], ignoreCase, \down);
+			}
+		};
+	}
+
+	*gui { if (gui.isNil or: { gui.w.isClosed }){ gui = KeyPlayerGui() }; ^gui.front; }
+
+	gui { ^KeyPlayerGui(this) }
+
+	makeRec { rec = KeyPlayerRec(this); }
+
+	putAll { |dict, both=false, where=\down|
+		dict.keysValuesDo{ |k, f| this.put(k, f, both, where) }
+	}
+
+	put { |char, func, both = false, where = \down|
+		if (both and: { char.isKindOf(Char) } and: { char.isAlpha }) {
+			[char.toLower, char.toUpper].do { |char|
+				this.putUni(char, func, where);
+			};
+		} {
+			this.putUni(char, func, where);
+		};
+	}
+	putUp { |char, func, both = false|
+		this.put(char, func, both, \up);
+	}
+
+	putDown { |char, func, both = false, noRep=false|
+		var wrapFunc;
+		if (noRep) {
+			wrapFunc = { |...args| if (this.isUp(char)) { func.value(*args) } }
+		};
+		this.put(char, wrapFunc ? func, both, \down);
+	}
+
+	putBoth { |char, func, both = false, noRep=false|
+		this.put(char, func, both, \down, noRep);
+		this.put(char, func, both, \up);
+	}
+
+	putUni { |charOrUni, func, where=\down|
+		bothActions[where].put(charOrUni.asUnicode, func);
+	}
+
+	isUp { |char| ^this.isDown(char).not }
+	isDown { |char| ^this.isPressed(char.asUnicode) }
+	isPressed { |char| ^pressed[char.asUnicode] ? false }
+
+	at { |char, where=\down| ^bothActions[where][char.asUnicode] }
+
+	removeAt { |char, where=\down, both=false| this.put(char, nil, both, where) }
+
+	keyAction { |char, modifiers, unicode, keycode, which=\down, press = true|
+
+		 var whichActions, action, result;
+
+		 if (verbose) { [KeyPlayer, char, modifiers, unicode, keycode].postcs; };
+
+		 if (rec.notNil) { rec.recordEvent(unicode, which) };
+
+				// call the function
+		unicode = unicode ?? { char.asUnicode };
+		whichActions = bothActions[which];
+		action = whichActions[unicode];
+
+		result = action.value(char, modifiers, unicode, keycode);
+		pressed.put(unicode, press);
+
+			// if the result is a function, that function
+			// becomes the new action for the key
+		if (result.isKindOf(Function)) {
+			whichActions[char] = result;
+		};
+	}
+	keyDown { |char, modifiers, unicode, keycode|
+		this.keyAction(char, modifiers, unicode, keycode, \down, true);
+	}
+	keyUp { |char, modifiers, unicode, keycode|
+		this.keyAction(char, modifiers, unicode, keycode, \up, false);
+	}
+
+	makeKeyAction { |which=\down, press = true|
+					// define a function to handle key downs.
+		^{ |view, char, modifiers, unicode, keycode|
+			this.keyAction(char, modifiers, unicode, keycode, which, press);
+		};
+	}
+
+	makeKeyDownAction { ^this.makeKeyAction(\down, true) }
+	makeKeyUpAction { ^this.makeKeyAction(\up, false) }
+
+	// write { |path| /* save directly to a path ... */ }
+	//
+	// read { |path| this.putAll(path.load ? ()); }
+
+	saveDoc {
+		Document("save my actions").string_(this.actions.asCompileString);
+	}
+}
+
+KeyPlayerGui {
+	classvar <>colors;
+	classvar <>lineOffsets;
+	classvar <>keyboard;
+	classvar <>keyboardNoShift;
+	classvar <>keyboardShift;
+
+	var <player;
+	var <w, <zone, <buttons, <drags, <font, <listview;
+	var <skipjack, <>activeColor;
+
+	*initClass {
+
+		colors = [
+			Color(0.8, 0.8, 0.8, 1),	// normal - 	grey
+			Color(0.8, 0.2, 0.2, 1),	// ctl		red
+			Color(0.2, 0.8, 0.2, 1),	// shift		green
+			Color(0.8, 0.8, 0.2, 1),	// alt		blue
+			Color(0.2, 1, 1, 1),		// alt shift	blue+green - cyan
+			Color(1, 1, 0.2, 1),		// ctl shift	red+green - yellow
+			Color(1, 0.2, 1, 1),		// ctl alt	red+blue - violet
+			Color(1, 1, 1, 1)		// ctl alt shift	red green blue - white
+		];
+
+		// these describe the keyboard to show;
+				// horizontal offsets for keys.
+		lineOffsets = #[42, 48, 57, 117];
+
+				// these are the keys you normally see (US, big keyb.)
+				// customise for german or other keyboard layouts.
+		keyboard = #["`1234567890-=", "QWERTYUIOP[]\\", "ASDFGHJKL;'", "ZXCVBNM,./"];
+
+			// NOT USED YET:
+				// the maps I get on my PB, US keyb., no shift
+		keyboardNoShift = #["1234567890-=", "qwertyuiop[]\\", "asdfghjkl;'", "`zxcvbnm,./"];
+				// and shifted	- /* double-quote */ only there for syntax colorize.
+		keyboardShift = #["!@#$%^&*()_+", "QWERTYUIOP{}", "ASDFGHJKL:\"|" /*"*/, "~ZXCVBNM<>?"];
+
+	}
+
+	*new { |kp, win, useList=false|
+		^super.new.init(kp, win, useList);
+	}
+
+	init { |kp, win, useList|
+		var zonebounds;
+		if (useList) {
+			zonebounds = Rect(0, 0, 480, 150);
+		} {
+			zonebounds = Rect(0, 0, 420, 170);
+		};
+
+		w = win ?? { this.makeWindow(try { kp.key } ? "KeyPlayerAll", zonebounds) };
+		zone = CompositeView(w, zonebounds);
+		zone.decorator = FlowLayout(zonebounds);
+
+		if (useList) {
+			this.makeListView;
+			zone.decorator.bounds = zonebounds.left_(64);
+			zone.decorator.top_(zone.decorator.top);
+		} {
+			this.makeButtons
+		};
+		this.makeDrags;
+
+		this.player_(kp);
+
+	}
+	makeWindow { |name, zonebounds|
+			var win = Window("keys" + name, zonebounds).front;
+			win.view.background_(Color(0.5, 0.5, 0.5, 0.0));
+			win.view.decorator = FlowLayout(win.view.bounds.moveTo(0,0));
+			^win;
+	}
+
+	front { w.front }
+
+	updateAll {
+		this.updateButtons;
+		if (player.notNil) {
+			this.updateDrags;
+			w.refresh;
+		}
+	}
+	updateButtons {
+		var keys = KeyPlayer.all.keys.asArray.sort;
+
+		var myIndex = -1;
+		if (player.notNil) { myIndex = keys.indexOf(player.key); };
+
+			// if buttons == nil, nothing
+		buttons.do {�|b, i|
+			var col = if (i == myIndex) { Color.white } { Color.grey(0.8) };
+			var key = keys[i];
+			var keyExists = keys[i].notNil;
+			b.states_([[key ? "", Color.black, col]]).enabled_(keyExists);
+		};
+
+		listview.notNil.if {
+			listview.items_(keys).value_(myIndex);
+		};
+	}
+	updateDrags { |which = 0|
+		var downKeys = player.actions.keys;
+		var upKeys = player.upActions.keys;
+
+			// do it for "A", "a";
+
+		drags.keysValuesDo { |uni, drag|
+			var val = 0;
+			if (downKeys.includes(uni)) { val = val + 1 };
+			if (upKeys.includes(uni)) { val = val + 2 };
+			drag.background_(colors[val])
+		}
+	}
+	makeButtons {
+		var keys = KeyPlayer.all.keys.asArray.sort;
+		buttons = 10.collect { |i|
+			Button(zone, Rect(0, 0, 36, 16)).states_([[ keys[i] ? "-" ]])
+				.action_({ |b|
+					var nuKP = KeyPlayer.all[b.states[0][0]];
+					if (nuKP.notNil) { this.player_(nuKP); };
+					this.updateAll;
+				})
+		};
+	//	buttons[keys.indexOf(player.key)].focus;
+	}
+
+	makeListView {
+		listview = ListView(zone, Rect(2,2,60,25));
+		listview.bounds_(Rect(2,2,60,130));
+
+	}
+
+	player_ { |nuplayer|
+		if (nuplayer.isNil) { ^this };
+
+		player = nuplayer;
+		w.view.keyDownAction_(player.makeKeyDownAction);
+		w.view.keyUpAction_(player.makeKeyUpAction);
+	}
+
+	makeDrags {
+
+		font = Font("Courier-Bold", 14);
+		drags = ();
+
+				// make the rows of the keyboard
+		keyboard.do {|row, i|
+			row.do {|key| this.makeKey(key) };
+			if (i==0) { this.makeKey(127.asAscii, "del", 38 @ 24) };
+			if (i==2) { this.makeKey($\r, "retrn", 46 @ 24) };
+			zone.decorator.nextLine;
+			zone.decorator.shift(lineOffsets[i]);
+		};
+
+//		zone.decorator.shift(lineOffsets.last.neg);
+//				// make the last row
+//		[\norm, \shift, \ctrl, \alt].do { |lab, i|
+//			Button(zone, Rect(0,0,36,18))
+//				.states_([[lab]])
+//				.action_{ ("not used yet:" + lab).postln };
+//		};
+
+		this.makeKey($ , "space", 150 @ 24);
+		this.makeKey(3.asAscii, "enter", 48 @ 24);
+
+				// this is maybe unnecessary?
+		skipjack = SkipJack({ 8.do { |i| this.updateAll; } }, 1, { zone.isClosed }, "KPgui");
+	}
+
+	runUpdate { skipjack.start }
+	stopUpdate { skipjack.stop }
+
+	makeKey { |char, keyname, bounds|
+		var v;
+		keyname = keyname ? char.asString;
+		bounds = bounds ? (24 @ 24);
+
+		v = DragBoth(zone, bounds);
+		v.font = font;
+		v.string = keyname;
+		v.align = \center;
+		v.setBoth = false;
+//		v.acceptDrag = {
+//			View.currentDrag.isKindOf(Function)
+//		};
+		drags.put(char.toLower.asUnicode, v);
+	//	v.action = { this.put(char.toLower, v.object, true) };
+	}
+}
\ No newline at end of file

Copied: KeyPlayer/Classes/KeyPlayerRec.sc (from rev 2667, KeyPlayer/KeyPlayerRec.sc)
===================================================================
--- KeyPlayer/Classes/KeyPlayerRec.sc	                        (rev 0)
+++ KeyPlayer/Classes/KeyPlayerRec.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,95 @@
+ /*** could be unified with CtLoop, maybe with a superclass EventLoop. ****/
+
+// maybe do automatic recording always?
+// if so, problem: we must know which keys to record,
+// and which not (e.g. rec on/off controls).
+// good enough for playing with it now, extend later...
+
+// only record keys in use?
+// declare nonRec keys in player or in rec?
+/* show rec/play state on gui:
+    recBut, playBut, forkBut,
+    recOn, playOn, speed, loop,
+    numLists, select curr list,
+*/
+
+KeyPlayerRec {
+	classvar <>verbose = false;
+
+	var <>player, <>list, <>lists;
+	var <>isOn=false, <>loop = true, <>speed = 1;
+	var then, playOnceFunc, task;
+
+	*new { |player|
+		^super.new.player_(player).init;
+	}
+
+	init {
+		lists = List[];
+
+		playOnceFunc = {
+		if (verbose) { "KeyPlayRec starts!".postln; };
+		list.do { |trip|
+			var time, char, type, unicode;
+			#time, char, type = trip;
+			unicode = char.asUnicode;
+			(time / speed.value).wait;
+			player.keyAction(char, which: type);
+		};
+		if (verbose) { "KeyPlayRec done.".postln; };
+		};
+
+		task = TaskProxy({
+			this.stopRec;
+			playOnceFunc.value;
+			if (loop) {
+				task.play
+			} {
+				("done: kp" + player.key).postln;
+			}
+		});
+	}
+
+	startRec {
+		if (verbose) { ("recording keys: kp" + player.key).postln; };
+		then = nil;
+		isOn = true;
+		list = List.new;
+	}
+
+	stopRec {
+		if (isOn) {
+			if (verbose) { ("stopRec: kp" + player.key).postln };
+			// record final wait time
+			this.recordEvent(\end, \down);
+			isOn = false;
+			lists.add(list);
+		};
+	}
+
+	recordEvent { |char, type=\down|
+		var now = thisThread.seconds;
+		var event;
+		if (isOn) {
+			then = then ? now;
+			event = [now - then, char, type];
+			list.add(event);
+			then = now;
+			if (verbose) {
+				"KPR % : recording %.\n".postf(player.key, event);
+			};
+		}
+	}
+
+	play { task.play; }
+
+	playOnce { this.stopRec; Task({ playOnceFunc.value; }).play; }
+
+	toggleRec { if (isOn) { this.stopRec } { this.startRec } }
+
+	togglePlay {
+		if (task.isActive) { task.stop } { task.play };
+	}
+
+	changeSpeed { |factor=1| speed = speed * factor }
+}

Copied: KeyPlayer/Help/KeyChain.html (from rev 2667, KeyPlayer/KeyChain.html)
===================================================================
--- KeyPlayer/Help/KeyChain.html	                        (rev 0)
+++ KeyPlayer/Help/KeyChain.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,134 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.32">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #dc0000}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000}
+p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #1000d0}
+p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #008a00}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {font: 9.0px Monaco}
+span.s3 {color: #000000}
+span.s4 {color: #1000d0}
+span.s5 {color: #008a00}
+span.s6 {color: #737373}
+span.s7 {color: #dc0000}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>KeyChain</b></span><span class="s2"> <span class="Apple-tab-span">	</span></span><b>a named chain of actions.</b></p>
+<p class="p2"><br></p>
+<p class="p2"><br></p>
+<p class="p1">A KeyChain is a named chain of actions.<span class="Apple-converted-space"> </span></p>
+<p class="p1">It can run these in sequence, or based on transition functions.<span class="Apple-converted-space"> </span></p>
+<p class="p1">It can be used nicely with <b>KeyPlayer</b>.<span class="Apple-converted-space"> </span></p>
+<p class="p2"><span class="Apple-tab-span">	</span></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// a single function</p>
+<p class="p4">a = <span class="s4">KeyChain</span>($a, [(key: <span class="s5">\x</span>, act: { <span class="s6">"act"</span>.scramble.postln })]);</p>
+<p class="p4">a.next;</p>
+<p class="p4">a.next;</p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// KeyChain($a) is a named proxy, so you either create or access it by name:<span class="Apple-converted-space"> </span></p>
+<p class="p6">KeyChain<span class="s3">($a);</span></p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// You can change its list by accessing it with a second argument:</p>
+<p class="p4">b = <span class="s4">KeyChain</span>($a, [(key: <span class="s5">\x</span>, act: { <span class="s6">"bong"</span>.scramble.postln })]);</p>
+<p class="p5"><br></p>
+<p class="p4">a === b; <span class="s7">// true!</span></p>
+<p class="p4">a = <span class="s4">KeyChain</span>($a);</p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// a, b, and equivalent now:<span class="Apple-converted-space"> </span></p>
+<p class="p4">b.next; ""</p>
+<p class="p4">a.next; <span class="s3">""</span></p>
+<p class="p4"><span class="s4">KeyChain</span>($a).next</p>
+<p class="p5"><br></p>
+<p class="p4">a.dump</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3">(<span class="Apple-tab-span">	</span></span>// a simple sequence</p>
+<p class="p6">KeyChain<span class="s3">($a, [</span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\x</span>, act: { <span class="s6">"xanadu"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\y</span>, act: { <span class="s6">"yakk"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\z</span>, act: { <span class="s6">"zonk"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>]);</p>
+<p class="p4">)</p>
+<p class="p4">b.next;</p>
+<p class="p4">a.next;</p>
+<p class="p5"><br></p>
+<p class="p4"><span class="s4">KeyChain</span>($a).next;</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p4"><span class="Apple-tab-span">	</span>// a KeyPlayer for it:<span class="Apple-converted-space"> </span></p>
+<p class="p4">KeyPlayer(\chain);</p>
+<p class="p7">KeyPlayer.gui;</p>
+<p class="p7">KeyPlayer(\chain).putBoth($a, { <span class="s4">KeyChain</span>($a).next });</p>
+<p class="p5"><br></p>
+<p class="p7">KeyPlayer(\chain).bothActions.postcs;</p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// tell it where to go next with 'to' key</p>
+<p class="p3"><span class="Apple-tab-span">	</span>// does this retrigger, even though it should not<span class="Apple-converted-space"> </span></p>
+<p class="p3"><span class="Apple-tab-span">	</span>// (it was off earlier)?<span class="Apple-converted-space"> </span></p>
+<p class="p4">(</p>
+<p class="p6">KeyChain<span class="s3">($a, [</span></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// name, what, what next</p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\boing</span>, act: { <span class="s5">\boing</span>.postln }, to: { <span class="s6">"next: "</span>.post; [<span class="s5">\boing</span>, <span class="s5">\tak</span>].choose.postln }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tak</span>, act: { <span class="s5">\tak</span>.postln }, to: <span class="s5">\boom</span>),<span class="Apple-converted-space"> </span></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span>(key: </span><span class="s5">\boom</span><span class="s3">, act: { </span><span class="s5">\boom</span><span class="s3">.postln }), </span>// default is next in chain, wraps<span class="Apple-converted-space"> </span></p>
+<p class="p4">], 0)</p>
+<p class="p4">)</p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// get more info</p>
+<p class="p4"><span class="s4">KeyChain</span>.verbose = <span class="s4">true</span>;</p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p5"><br></p>
+<p class="p6">KeyChain<span class="s3">.verbose = </span>false<span class="s3">;</span></p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// more complex sequence:</p>
+<p class="p4">(</p>
+<p class="p6">KeyChain<span class="s3">($a, [</span></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// name, what, what next</p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\boing</span>, act: { <span class="s5">\boing</span>.postln }, to: { [<span class="s5">\boing</span>, <span class="s5">\tak</span>].choose }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tak</span>, act: { <span class="s5">\tak</span>.postln }, to: <span class="s5">\boom</span>),<span class="Apple-converted-space"> </span></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span>(key: </span><span class="s5">\boom</span><span class="s3">, act: { </span><span class="s5">\boom</span><span class="s3">.postln }), </span>// default is next in chain, wraps<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tsk</span>, act: { <span class="s5">\tsk</span>.postln }),<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\chak</span>, act: { <span class="s5">\chak</span>.postln }, to: { a.chooseNext })</p>
+<p class="p4">], 0)</p>
+<p class="p4">)</p>
+<p class="p5"><br></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p4">a.next; <span class="s6">""</span></p>
+<p class="p5"><br></p>
+<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// do multiple actions at once</p>
+<p class="p4">a.act(0)</p>
+<p class="p4">a.act(<span class="s5">\boom</span>)</p>
+<p class="p4">a.act(<span class="s5">\chak</span>)</p>
+<p class="p4">a.act([<span class="s5">\boom</span>, <span class="s5">\chak</span>])</p>
+<p class="p8"><span class="s3">a.act([</span>\boom<span class="s3">, </span>\chak<span class="s3">, </span>\tak<span class="s3">])</span></p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+</body>
+</html>

Copied: KeyPlayer/Help/KeyPlayer.html (from rev 2667, KeyPlayer/KeyPlayer.html)
===================================================================
--- KeyPlayer/Help/KeyPlayer.html	                        (rev 0)
+++ KeyPlayer/Help/KeyPlayer.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,170 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.32">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #001db9}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
+p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #213ba1; min-height: 14.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco}
+p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #483131}
+p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #782727}
+p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #961e1e}
+p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #961e1f}
+p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #606060}
+p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #dc0000}
+p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #737373}
+p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #3c3232}
+p.p15 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #213ba1}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {font: 10.0px Monaco}
+span.s3 {font: 12.0px Helvetica; color: #000000}
+span.s4 {color: #213ba1}
+span.s5 {color: #65652b}
+span.s6 {color: #203ba1}
+span.s7 {color: #000000}
+span.s8 {color: #0428b3}
+span.s9 {color: #606060}
+span.s10 {color: #961e1e}
+span.s11 {color: #001db9}
+span.s12 {color: #483131}
+span.s13 {color: #1000d0}
+span.s14 {color: #008a00}
+span.s15 {color: #2f4399}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>KeyPlayer</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple keyboard interface</b></p>
+<p class="p2"><br></p>
+<p class="p1">KeyPlayer allows using the computer keyboard keys for<span class="Apple-converted-space"> </span></p>
+<p class="p1">executing functions when given keys are pressed or released<span class="Apple-converted-space"> </span></p>
+<p class="p1">(keyDown and keyUp).</p>
+<p class="p2"><br></p>
+<p class="p3"><span class="s3">see also </span>KeyPlayerGui, KeyPlayerRec, KeyChain</p>
+<p class="p4"><br></p>
+<p class="p1"><b>class methods:</b></p>
+<p class="p4"><br></p>
+<p class="p5"><br></p>
+<p class="p6">k = <span class="s4">KeyPlayer</span>(<span class="s5">\k</span>);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// create an instance</p>
+<p class="p6"><span class="s6">KeyPlayer</span>(<span class="s5">\k</span>) == k;<span class="Apple-tab-span">	</span>// same name accesses same instance</p>
+<p class="p4"><br></p>
+<p class="p7"><span class="s4">KeyPlayer</span><span class="s7">.all;<span class="Apple-tab-span">	</span></span>// all instances live here</p>
+<p class="p4"><br></p>
+<p class="p8"><span class="s8">KeyPlayer</span><span class="s7">.verbose_(</span><span class="s8">true</span><span class="s7">);<span class="Apple-tab-span">	</span></span>// debugging, posts:</p>
+<p class="p8"><span class="Apple-tab-span">	</span>// [KeyPlayer, char, modifiers, unicode, keycode]</p>
+<p class="p5"><br></p>
+<p class="p6"><span class="s4">KeyPlayer</span>.verbose_(false);<span class="Apple-tab-span">	</span></p>
+<p class="p4"><br></p>
+<p class="p6">KeyPlayer.gui;<span class="Apple-tab-span">	</span>// shows up to 10 keyplayers</p>
+<p class="p4"><br></p>
+<p class="p1"><b>instance methods:<span class="Apple-converted-space"> </span></b></p>
+<p class="p4"><br></p>
+<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// put in some functions</p>
+<p class="p6">k.put($a, { <span class="s9">"A down!"</span>.postln });<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s10">// or equivalent:</span></p>
+<p class="p6">k.putDown($a, { <span class="s9">"A down!"</span>.postln });</p>
+<p class="p9"><span class="s7">k.actions;<span class="Apple-tab-span">	</span></span>// they are stored here by unicode numbers</p>
+<p class="p4"><br></p>
+<p class="p10"><span class="s7"><span class="Apple-tab-span">	</span>// </span>upActions are separate</p>
+<p class="p6">k.putUp($a, { <span class="s9">"A up!"</span>.postln });</p>
+<p class="p6">k.upActions;<span class="Apple-tab-span">	</span></p>
+<p class="p4"><br></p>
+<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// both dictionaries are kept here:<span class="Apple-converted-space"> </span></p>
+<p class="p6">k.bothActions.postcs; <span class="s9">""</span>;</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// you can put things in both:</p>
+<p class="p6">k.putBoth($a, { <span class="s9">"A upOrDown!"</span>.postln });</p>
+<p class="p4"><br></p>
+<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// execute keyActions by hand<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// - also try them when the window is in front,<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// and one of the buttons focused.</p>
+<p class="p6">k.keyDown($a);</p>
+<p class="p6">k.keyUp($a);</p>
+<p class="p6">k.keyDown($a.asUnicode);</p>
+<p class="p6">k.keyUp($a.asUnicode);</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="s11">KeyPlayer</span>.verbose_(<span class="s11">false</span>);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p4"><br></p>
+<p class="p7"><span class="s7"><span class="Apple-tab-span">	</span></span>// avoid retriggering keyDowns: try holding the s-key down<span class="Apple-converted-space"> </span></p>
+<p class="p6">k.putDown($s, { <span class="s9">"yo again"</span>.postln }, noRep: <span class="s4">true</span>);</p>
+<p class="p6">k.putUp($s, { <span class="s9">"yo again"</span>.reverse.postln });</p>
+<p class="p4"><br></p>
+<p class="p6">k.putDown($s, { <span class="s9">"yo again"</span>.postln });<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s12">// retriggers by default</span></p>
+<p class="p4"><br></p>
+<p class="p6">g = k.gui;</p>
+<p class="p7"><span class="s7"><span class="Apple-tab-span">	</span></span>// remove actions:</p>
+<p class="p6">k.removeAt($a);</p>
+<p class="p6">k.removeAt($a, <span class="s5">\up</span>);</p>
+<p class="p6">k.upActions;</p>
+<p class="p6">k.removeAt($a, <span class="s5">\down</span>);</p>
+<p class="p6">k.actions;</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// make a KeyPlayerRec for it ...<span class="Apple-converted-space">  </span>see KeyPlayerRec.help for details</p>
+<p class="p6">k.makeRec;<span class="Apple-tab-span">	</span></p>
+<p class="p6">k.rec; <span class="Apple-tab-span">	</span>// and it is here</p>
+<p class="p4"><br></p>
+<p class="p1"><b>examples:</b></p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// the random keyboard:<span class="Apple-converted-space"> </span></p>
+<p class="p6">(</p>
+<p class="p6">s.latency = nil;<span class="Apple-tab-span">	</span>// make sure we respond quickly</p>
+<p class="p6"><span class="s4">thisThread</span>.randSeed = 2008;</p>
+<p class="p11">"qwertzuiopasdfghjklyxcvbnm"<span class="s7">.do { </span><span class="s4">|char|</span><span class="s7"><span class="Apple-converted-space"> </span></span></p>
+<p class="p6"><span class="Apple-tab-span">	</span>var note = (midinote: rrand(36, 96), dur: rrand(0.1, 1.0));</p>
+<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\rand).put(char, { <span class="s4">|char|</span> char.postln; note.postln.play });</p>
+<p class="p6">};</p>
+<p class="p6">KeyPlayer.gui.front;</p>
+<p class="p6">)</p>
+<p class="p4"><br></p>
+<p class="p6">KeyPlayer(\rand).bothActions</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// random keyboard, no retrig, hold until release with keyUp</p>
+<p class="p6">(</p>
+<p class="p12"><span class="s7">q = q ? ();<span class="Apple-tab-span">	</span></span>// create a dict to keep things:<span class="Apple-converted-space"> </span></p>
+<p class="p6">q.notes = ();</p>
+<p class="p6">q.synths = ();</p>
+<p class="p12"><span class="s13">thisThread</span><span class="s7">.randSeed = 2008; </span>// it is not that new</p>
+<p class="p4"><br></p>
+<p class="p13">"qwertzuiopasdfghjklyxcvbnm"<span class="s7">.do { </span><span class="s13">|char|</span><span class="s7"><span class="Apple-converted-space"> </span></span></p>
+<p class="p6"><span class="Apple-tab-span">	</span>q.notes.put(char, rrand(36, 96));</p>
+<p class="p4"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\hold).putDown(char, { <span class="s13">|char|</span><span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>char.post;<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths[char].release;</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths.put(char, <span class="s13">Synth</span>(<span class="s14">\default</span>, [<span class="s14">\freq</span>, q.notes[char].postln.midicps]));</p>
+<p class="p6"><span class="Apple-tab-span">	</span>}, noRep: true);</p>
+<p class="p4"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\hold).putUp(char.postln, { <span class="s13">|char|</span> q.synths.removeAt(char).release });</p>
+<p class="p6">};</p>
+<p class="p6">KeyPlayer.gui.front;</p>
+<p class="p6">)</p>
+<p class="p4"><br></p>
+<p class="p6">KeyPlayer(\px);</p>
+<p class="p14">// stop and resume a proxyspace:</p>
+<p class="p6">p = <span class="s15">ProxySpace</span>.push;</p>
+<p class="p6">KeyPlayer(\px).put($p, { p.do(<span class="s15">_</span>.pause) });</p>
+<p class="p6">KeyPlayer(\px).put($r, { p.do(<span class="s15">_</span>.resume) });</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// David Cottle example IIRC<span class="Apple-converted-space"> </span></p>
+<p class="p6">~test = { <span class="s15">SinOsc</span>.ar(<span class="s15">LFNoise0</span>.kr([10, 15], 200, [300, 500])) * 0.2 };</p>
+<p class="p6">~test.play;</p>
+<p class="p4"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>// re-send or rebuild the sound</p>
+<p class="p6">(</p>
+<p class="p6">~test = {<span class="Apple-converted-space"> </span></p>
+<p class="p15"><span class="s7"><span class="Apple-tab-span">	</span></span>SinOsc<span class="s7">.ar(</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s4">LFNoise0</span>.kr([10, 15] * exprand(0.5, 4.0), 200, [300, 500])<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>* exprand(1.0, 4.0)</p>
+<p class="p6"><span class="Apple-tab-span">	</span>) * XLine.kr(0.5, 0.005, exprand(0.1, 10), doneAction: 2);</p>
+<p class="p6">};</p>
+<p class="p6">KeyPlayer(\px).put($t, { ~test.send });</p>
+<p class="p6">KeyPlayer(\px).put($u, { ~test.rebuild });</p>
+<p class="p6">)</p>
+</body>
+</html>

Copied: KeyPlayer/Help/KeyPlayerGui.html (from rev 2667, KeyPlayer/KeyPlayerGui.html)
===================================================================
--- KeyPlayer/Help/KeyPlayerGui.html	                        (rev 0)
+++ KeyPlayer/Help/KeyPlayerGui.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,34 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.32">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {font: 10.0px Monaco}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>KeyPlayerGui</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple gui for KeyPlayer</b></p>
+<p class="p2"><br></p>
+<p class="p1">Several aspects of this class could be made more flexible;</p>
+<p class="p1">supporting different display sizes, keyboard layouts,<span class="Apple-converted-space"> </span></p>
+<p class="p1">and ways of switching between several KeyPlayers may be useful.</p>
+<p class="p3"><br></p>
+<p class="p1">Dragging and dropping actions could also be supported;<span class="Apple-converted-space"> </span></p>
+<p class="p1">not sure how to do that consistently with keyUp actions, retriggering,<span class="Apple-converted-space"> </span></p>
+<p class="p1">putting things on shifted keys, etc.</p>
+<p class="p2"><br></p>
+<p class="p1"><b>see KeyPlayer for examples!</b></p>
+<p class="p3"><b></b><br></p>
+<p class="p3"><b></b><br></p>
+<p class="p3"><b></b><br></p>
+</body>
+</html>

Copied: KeyPlayer/Help/KeyPlayerRec.html (from rev 2667, KeyPlayer/KeyPlayerRec.html)
===================================================================
--- KeyPlayer/Help/KeyPlayerRec.html	                        (rev 0)
+++ KeyPlayer/Help/KeyPlayerRec.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -0,0 +1,82 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.32">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #dc0000}
+p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #1000d0}
+p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco}
+p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #737373}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {font: 10.0px Monaco}
+span.s3 {color: #000000}
+span.s4 {color: #008a00}
+span.s5 {color: #1000d0}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>KeyPlayerRec</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple recorder for KeyPlayer</b></p>
+<p class="p2"><br></p>
+<p class="p1">KeyPlayerRec can record a series of key presses made with KeyPlayer,<span class="Apple-converted-space"> </span></p>
+<p class="p1">and play it back with variable speed.</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p1"><b>class methods:</b></p>
+<p class="p3"><br></p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// *new needs a KeyPlayer object</p>
+<p class="p5">KeyPlayer<span class="s3">(</span><span class="s4">\kRec</span><span class="s3">);</span></p>
+<p class="p5">KeyPlayer<span class="s3">.gui;</span></p>
+<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).makeRec;</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// or make rec explicitly:<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// r = KeyPlayerRec.new();</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// k.rec = r;</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p1"><b>examples:</b></p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// random keyboard:<span class="Apple-converted-space"> </span></p>
+<p class="p6">(</p>
+<p class="p6"><span class="s5">var</span> notes = ();</p>
+<p class="p6"><span class="s5">thisThread</span>.randSeed = 2008;</p>
+<p class="p7">"qwertzuiopasdfghjklyxcvbnm"<span class="s3">.do { </span><span class="s5">|char|</span><span class="s3"><span class="Apple-converted-space"> </span></span></p>
+<p class="p3"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>notes.put(char, rrand(36, 96));</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).put(char, { <span class="s5">|char|</span><span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// recording added here!</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.recordEvent(char, <span class="s4">\down</span>);</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>char.postln;<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>(midinote: notes[char]).play<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span>});</p>
+<p class="p6">};</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// use extra keys for record and play on/off</p>
+<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).putDown($,, { <span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.toggleRec }, noRep: <span class="s5">true</span>);</p>
+<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).putDown($., { <span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.togglePlay }, noRep: <span class="s5">true</span>);</p>
+<p class="p6">)</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// record a sequence now:</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// bring window to front,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// type ',' to start rec, type a few letter keys;</p>
+<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// type ',' to stop rec, type '.' to toggle playback</p>
+<p class="p3"><br></p>
+<p class="p5"><span class="s3">k = </span>KeyPlayer<span class="s3">(</span><span class="s4">\kRec</span><span class="s3">);</span></p>
+<p class="p3"><br></p>
+<p class="p4"><span class="s3">k.rec.task.play;<span class="Apple-tab-span">	</span></span>// play it by hand</p>
+<p class="p4"><span class="s3">k.rec.list;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the list of recorded events</p>
+<p class="p6">k.rec.list.printAll;</p>
+<p class="p4"><span class="s3">k.rec.isOn;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// recording now or not?</p>
+<p class="p3"><br></p>
+<p class="p4">// maybe do automatic recording?<span class="Apple-converted-space"> </span></p>
+<p class="p4">// if so, problem: we must know which keys to record,<span class="Apple-converted-space"> </span></p>
+<p class="p4">// and which not (e.g. rec on/off controls).</p>
+<p class="p3"><br></p>
+<p class="p4">// good enough for playing with it now, extend later...</p>
+<p class="p3"><br></p>
+</body>
+</html>

Deleted: KeyPlayer/KeyChain.html
===================================================================
--- KeyPlayer/KeyChain.html	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyChain.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,134 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Style-Type" content="text/css">
-<title></title>
-<meta name="Generator" content="Cocoa HTML Writer">
-<meta name="CocoaVersion" content="1038.32">
-<style type="text/css">
-p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
-p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
-p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #dc0000}
-p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000}
-p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000; min-height: 12.0px}
-p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #1000d0}
-p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
-p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #008a00}
-span.s1 {font: 18.0px Helvetica}
-span.s2 {font: 9.0px Monaco}
-span.s3 {color: #000000}
-span.s4 {color: #1000d0}
-span.s5 {color: #008a00}
-span.s6 {color: #737373}
-span.s7 {color: #dc0000}
-span.Apple-tab-span {white-space:pre}
-</style>
-</head>
-<body>
-<p class="p1"><span class="s1"><b>KeyChain</b></span><span class="s2"> <span class="Apple-tab-span">	</span></span><b>a named chain of actions.</b></p>
-<p class="p2"><br></p>
-<p class="p2"><br></p>
-<p class="p1">A KeyChain is a named chain of actions.<span class="Apple-converted-space"> </span></p>
-<p class="p1">It can run these in sequence, or based on transition functions.<span class="Apple-converted-space"> </span></p>
-<p class="p1">It can be used nicely with <b>KeyPlayer</b>.<span class="Apple-converted-space"> </span></p>
-<p class="p2"><span class="Apple-tab-span">	</span></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// a single function</p>
-<p class="p4">a = <span class="s4">KeyChain</span>($a, [(key: <span class="s5">\x</span>, act: { <span class="s6">"act"</span>.scramble.postln })]);</p>
-<p class="p4">a.next;</p>
-<p class="p4">a.next;</p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// KeyChain($a) is a named proxy, so you either create or access it by name:<span class="Apple-converted-space"> </span></p>
-<p class="p6">KeyChain<span class="s3">($a);</span></p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// You can change its list by accessing it with a second argument:</p>
-<p class="p4">b = <span class="s4">KeyChain</span>($a, [(key: <span class="s5">\x</span>, act: { <span class="s6">"bong"</span>.scramble.postln })]);</p>
-<p class="p5"><br></p>
-<p class="p4">a === b; <span class="s7">// true!</span></p>
-<p class="p4">a = <span class="s4">KeyChain</span>($a);</p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// a, b, and equivalent now:<span class="Apple-converted-space"> </span></p>
-<p class="p4">b.next; ""</p>
-<p class="p4">a.next; <span class="s3">""</span></p>
-<p class="p4"><span class="s4">KeyChain</span>($a).next</p>
-<p class="p5"><br></p>
-<p class="p4">a.dump</p>
-<p class="p5"><br></p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3">(<span class="Apple-tab-span">	</span></span>// a simple sequence</p>
-<p class="p6">KeyChain<span class="s3">($a, [</span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\x</span>, act: { <span class="s6">"xanadu"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\y</span>, act: { <span class="s6">"yakk"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\z</span>, act: { <span class="s6">"zonk"</span>.scramble.postln }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>]);</p>
-<p class="p4">)</p>
-<p class="p4">b.next;</p>
-<p class="p4">a.next;</p>
-<p class="p5"><br></p>
-<p class="p4"><span class="s4">KeyChain</span>($a).next;</p>
-<p class="p5"><br></p>
-<p class="p5"><br></p>
-<p class="p4"><span class="Apple-tab-span">	</span>// a KeyPlayer for it:<span class="Apple-converted-space"> </span></p>
-<p class="p4">KeyPlayer(\chain);</p>
-<p class="p7">KeyPlayer.gui;</p>
-<p class="p7">KeyPlayer(\chain).putBoth($a, { <span class="s4">KeyChain</span>($a).next });</p>
-<p class="p5"><br></p>
-<p class="p7">KeyPlayer(\chain).bothActions.postcs;</p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// tell it where to go next with 'to' key</p>
-<p class="p3"><span class="Apple-tab-span">	</span>// does this retrigger, even though it should not<span class="Apple-converted-space"> </span></p>
-<p class="p3"><span class="Apple-tab-span">	</span>// (it was off earlier)?<span class="Apple-converted-space"> </span></p>
-<p class="p4">(</p>
-<p class="p6">KeyChain<span class="s3">($a, [</span></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// name, what, what next</p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\boing</span>, act: { <span class="s5">\boing</span>.postln }, to: { <span class="s6">"next: "</span>.post; [<span class="s5">\boing</span>, <span class="s5">\tak</span>].choose.postln }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tak</span>, act: { <span class="s5">\tak</span>.postln }, to: <span class="s5">\boom</span>),<span class="Apple-converted-space"> </span></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span>(key: </span><span class="s5">\boom</span><span class="s3">, act: { </span><span class="s5">\boom</span><span class="s3">.postln }), </span>// default is next in chain, wraps<span class="Apple-converted-space"> </span></p>
-<p class="p4">], 0)</p>
-<p class="p4">)</p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// get more info</p>
-<p class="p4"><span class="s4">KeyChain</span>.verbose = <span class="s4">true</span>;</p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p5"><br></p>
-<p class="p6">KeyChain<span class="s3">.verbose = </span>false<span class="s3">;</span></p>
-<p class="p5"><br></p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// more complex sequence:</p>
-<p class="p4">(</p>
-<p class="p6">KeyChain<span class="s3">($a, [</span></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// name, what, what next</p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\boing</span>, act: { <span class="s5">\boing</span>.postln }, to: { [<span class="s5">\boing</span>, <span class="s5">\tak</span>].choose }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tak</span>, act: { <span class="s5">\tak</span>.postln }, to: <span class="s5">\boom</span>),<span class="Apple-converted-space"> </span></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span>(key: </span><span class="s5">\boom</span><span class="s3">, act: { </span><span class="s5">\boom</span><span class="s3">.postln }), </span>// default is next in chain, wraps<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\tsk</span>, act: { <span class="s5">\tsk</span>.postln }),<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="Apple-tab-span">	</span>(key: <span class="s5">\chak</span>, act: { <span class="s5">\chak</span>.postln }, to: { a.chooseNext })</p>
-<p class="p4">], 0)</p>
-<p class="p4">)</p>
-<p class="p5"><br></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p4">a.next; <span class="s6">""</span></p>
-<p class="p5"><br></p>
-<p class="p3"><span class="s3"><span class="Apple-tab-span">	</span></span>// do multiple actions at once</p>
-<p class="p4">a.act(0)</p>
-<p class="p4">a.act(<span class="s5">\boom</span>)</p>
-<p class="p4">a.act(<span class="s5">\chak</span>)</p>
-<p class="p4">a.act([<span class="s5">\boom</span>, <span class="s5">\chak</span>])</p>
-<p class="p8"><span class="s3">a.act([</span>\boom<span class="s3">, </span>\chak<span class="s3">, </span>\tak<span class="s3">])</span></p>
-<p class="p5"><br></p>
-<p class="p5"><br></p>
-</body>
-</html>

Deleted: KeyPlayer/KeyChain.sc
===================================================================
--- KeyPlayer/KeyChain.sc	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyChain.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,63 +0,0 @@
-KeyChain {
-	classvar <all, <>verbose = false; 
-	var <key, <>list, <>index = 0, <nextIndex = 0, <nextKey, <>repeats = 1; 
-	
-	*initClass { all = () }
-	
-	*new { |key, list, index|
-		var res = all[key]; 
-		if (res.isNil) { 
-			res = super.newCopyArgs(key, list ?? { [] }, index ? 0);
-			all.put(key, res);
-		} { 
-			if (list.notNil) { res.list_(list) };
-			if (index.notNil) { res.index_(index) };
-		};
-		
-		^res
-	}
-	
-	loop { repeats = inf }
-
-	value { |...args| this.next(*args) }
-
-	next { |...args|
-		var which; 
-		index = nextIndex;
-		which = list.wrapAt(index);
-		this.findNext(which.to);
-		
-		if (which.notNil) { which.act(*args) }; 
-		
-		 if (verbose) { 
-			 "KeyChain(%) did % at %.\n".postf(key, which.key, index);
-			 "	up next: % at %.\n".postf(nextKey, nextIndex);
-		};
-	}
-
-	reset { index = 0 }
-	
-	findNext { |nextInfo| 
-		if (nextInfo.isKindOf(Symbol)) { 
-			nextIndex = list.detectIndex { |dict| dict.key == nextInfo };
-			if (nextIndex.notNil) { nextKey = nextInfo };
-		} {
-			nextIndex = nextInfo ?? { index + 1 } % list.size; 
-			nextKey = list[ nextIndex ].key;
-		}
-	}
-	
-	chooseNext { ^list.choose.to }
-	
-	act { |keys| 
-		keys.do { |key| 
-			var which;
-			which = if (key.isNumber) { 
-				list.wrapAt(key); 
-			} { 
-				list.detect { |it| it.key == key };
-			};
-			which !? { which.act };
-		};	
-	}
-}
\ No newline at end of file

Deleted: KeyPlayer/KeyPlayer.html
===================================================================
--- KeyPlayer/KeyPlayer.html	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyPlayer.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,170 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Style-Type" content="text/css">
-<title></title>
-<meta name="Generator" content="Cocoa HTML Writer">
-<meta name="CocoaVersion" content="1038.32">
-<style type="text/css">
-p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
-p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
-p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #001db9}
-p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
-p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #213ba1; min-height: 14.0px}
-p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco}
-p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #483131}
-p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #782727}
-p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #961e1e}
-p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #961e1f}
-p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #606060}
-p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #dc0000}
-p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #737373}
-p.p14 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #3c3232}
-p.p15 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #213ba1}
-span.s1 {font: 18.0px Helvetica}
-span.s2 {font: 10.0px Monaco}
-span.s3 {font: 12.0px Helvetica; color: #000000}
-span.s4 {color: #213ba1}
-span.s5 {color: #65652b}
-span.s6 {color: #203ba1}
-span.s7 {color: #000000}
-span.s8 {color: #0428b3}
-span.s9 {color: #606060}
-span.s10 {color: #961e1e}
-span.s11 {color: #001db9}
-span.s12 {color: #483131}
-span.s13 {color: #1000d0}
-span.s14 {color: #008a00}
-span.s15 {color: #2f4399}
-span.Apple-tab-span {white-space:pre}
-</style>
-</head>
-<body>
-<p class="p1"><span class="s1"><b>KeyPlayer</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple keyboard interface</b></p>
-<p class="p2"><br></p>
-<p class="p1">KeyPlayer allows using the computer keyboard keys for<span class="Apple-converted-space"> </span></p>
-<p class="p1">executing functions when given keys are pressed or released<span class="Apple-converted-space"> </span></p>
-<p class="p1">(keyDown and keyUp).</p>
-<p class="p2"><br></p>
-<p class="p3"><span class="s3">see also </span>KeyPlayerGui, KeyPlayerRec, KeyChain</p>
-<p class="p4"><br></p>
-<p class="p1"><b>class methods:</b></p>
-<p class="p4"><br></p>
-<p class="p5"><br></p>
-<p class="p6">k = <span class="s4">KeyPlayer</span>(<span class="s5">\k</span>);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// create an instance</p>
-<p class="p6"><span class="s6">KeyPlayer</span>(<span class="s5">\k</span>) == k;<span class="Apple-tab-span">	</span>// same name accesses same instance</p>
-<p class="p4"><br></p>
-<p class="p7"><span class="s4">KeyPlayer</span><span class="s7">.all;<span class="Apple-tab-span">	</span></span>// all instances live here</p>
-<p class="p4"><br></p>
-<p class="p8"><span class="s8">KeyPlayer</span><span class="s7">.verbose_(</span><span class="s8">true</span><span class="s7">);<span class="Apple-tab-span">	</span></span>// debugging, posts:</p>
-<p class="p8"><span class="Apple-tab-span">	</span>// [KeyPlayer, char, modifiers, unicode, keycode]</p>
-<p class="p5"><br></p>
-<p class="p6"><span class="s4">KeyPlayer</span>.verbose_(false);<span class="Apple-tab-span">	</span></p>
-<p class="p4"><br></p>
-<p class="p6">KeyPlayer.gui;<span class="Apple-tab-span">	</span>// shows up to 10 keyplayers</p>
-<p class="p4"><br></p>
-<p class="p1"><b>instance methods:<span class="Apple-converted-space"> </span></b></p>
-<p class="p4"><br></p>
-<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// put in some functions</p>
-<p class="p6">k.put($a, { <span class="s9">"A down!"</span>.postln });<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s10">// or equivalent:</span></p>
-<p class="p6">k.putDown($a, { <span class="s9">"A down!"</span>.postln });</p>
-<p class="p9"><span class="s7">k.actions;<span class="Apple-tab-span">	</span></span>// they are stored here by unicode numbers</p>
-<p class="p4"><br></p>
-<p class="p10"><span class="s7"><span class="Apple-tab-span">	</span>// </span>upActions are separate</p>
-<p class="p6">k.putUp($a, { <span class="s9">"A up!"</span>.postln });</p>
-<p class="p6">k.upActions;<span class="Apple-tab-span">	</span></p>
-<p class="p4"><br></p>
-<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// both dictionaries are kept here:<span class="Apple-converted-space"> </span></p>
-<p class="p6">k.bothActions.postcs; <span class="s9">""</span>;</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// you can put things in both:</p>
-<p class="p6">k.putBoth($a, { <span class="s9">"A upOrDown!"</span>.postln });</p>
-<p class="p4"><br></p>
-<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// execute keyActions by hand<span class="Apple-converted-space"> </span></p>
-<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// - also try them when the window is in front,<span class="Apple-converted-space"> </span></p>
-<p class="p9"><span class="s7"><span class="Apple-tab-span">	</span></span>// and one of the buttons focused.</p>
-<p class="p6">k.keyDown($a);</p>
-<p class="p6">k.keyUp($a);</p>
-<p class="p6">k.keyDown($a.asUnicode);</p>
-<p class="p6">k.keyUp($a.asUnicode);</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="s11">KeyPlayer</span>.verbose_(<span class="s11">false</span>);<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
-<p class="p4"><br></p>
-<p class="p7"><span class="s7"><span class="Apple-tab-span">	</span></span>// avoid retriggering keyDowns: try holding the s-key down<span class="Apple-converted-space"> </span></p>
-<p class="p6">k.putDown($s, { <span class="s9">"yo again"</span>.postln }, noRep: <span class="s4">true</span>);</p>
-<p class="p6">k.putUp($s, { <span class="s9">"yo again"</span>.reverse.postln });</p>
-<p class="p4"><br></p>
-<p class="p6">k.putDown($s, { <span class="s9">"yo again"</span>.postln });<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s12">// retriggers by default</span></p>
-<p class="p4"><br></p>
-<p class="p6">g = k.gui;</p>
-<p class="p7"><span class="s7"><span class="Apple-tab-span">	</span></span>// remove actions:</p>
-<p class="p6">k.removeAt($a);</p>
-<p class="p6">k.removeAt($a, <span class="s5">\up</span>);</p>
-<p class="p6">k.upActions;</p>
-<p class="p6">k.removeAt($a, <span class="s5">\down</span>);</p>
-<p class="p6">k.actions;</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// make a KeyPlayerRec for it ...<span class="Apple-converted-space">  </span>see KeyPlayerRec.help for details</p>
-<p class="p6">k.makeRec;<span class="Apple-tab-span">	</span></p>
-<p class="p6">k.rec; <span class="Apple-tab-span">	</span>// and it is here</p>
-<p class="p4"><br></p>
-<p class="p1"><b>examples:</b></p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// the random keyboard:<span class="Apple-converted-space"> </span></p>
-<p class="p6">(</p>
-<p class="p6">s.latency = nil;<span class="Apple-tab-span">	</span>// make sure we respond quickly</p>
-<p class="p6"><span class="s4">thisThread</span>.randSeed = 2008;</p>
-<p class="p11">"qwertzuiopasdfghjklyxcvbnm"<span class="s7">.do { </span><span class="s4">|char|</span><span class="s7"><span class="Apple-converted-space"> </span></span></p>
-<p class="p6"><span class="Apple-tab-span">	</span>var note = (midinote: rrand(36, 96), dur: rrand(0.1, 1.0));</p>
-<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\rand).put(char, { <span class="s4">|char|</span> char.postln; note.postln.play });</p>
-<p class="p6">};</p>
-<p class="p6">KeyPlayer.gui.front;</p>
-<p class="p6">)</p>
-<p class="p4"><br></p>
-<p class="p6">KeyPlayer(\rand).bothActions</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// random keyboard, no retrig, hold until release with keyUp</p>
-<p class="p6">(</p>
-<p class="p12"><span class="s7">q = q ? ();<span class="Apple-tab-span">	</span></span>// create a dict to keep things:<span class="Apple-converted-space"> </span></p>
-<p class="p6">q.notes = ();</p>
-<p class="p6">q.synths = ();</p>
-<p class="p12"><span class="s13">thisThread</span><span class="s7">.randSeed = 2008; </span>// it is not that new</p>
-<p class="p4"><br></p>
-<p class="p13">"qwertzuiopasdfghjklyxcvbnm"<span class="s7">.do { </span><span class="s13">|char|</span><span class="s7"><span class="Apple-converted-space"> </span></span></p>
-<p class="p6"><span class="Apple-tab-span">	</span>q.notes.put(char, rrand(36, 96));</p>
-<p class="p4"><span class="Apple-tab-span">	</span></p>
-<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\hold).putDown(char, { <span class="s13">|char|</span><span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>char.post;<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths[char].release;</p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths.put(char, <span class="s13">Synth</span>(<span class="s14">\default</span>, [<span class="s14">\freq</span>, q.notes[char].postln.midicps]));</p>
-<p class="p6"><span class="Apple-tab-span">	</span>}, noRep: true);</p>
-<p class="p4"><span class="Apple-tab-span">	</span></p>
-<p class="p6"><span class="Apple-tab-span">	</span>KeyPlayer(\hold).putUp(char.postln, { <span class="s13">|char|</span> q.synths.removeAt(char).release });</p>
-<p class="p6">};</p>
-<p class="p6">KeyPlayer.gui.front;</p>
-<p class="p6">)</p>
-<p class="p4"><br></p>
-<p class="p6">KeyPlayer(\px);</p>
-<p class="p14">// stop and resume a proxyspace:</p>
-<p class="p6">p = <span class="s15">ProxySpace</span>.push;</p>
-<p class="p6">KeyPlayer(\px).put($p, { p.do(<span class="s15">_</span>.pause) });</p>
-<p class="p6">KeyPlayer(\px).put($r, { p.do(<span class="s15">_</span>.resume) });</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// David Cottle example IIRC<span class="Apple-converted-space"> </span></p>
-<p class="p6">~test = { <span class="s15">SinOsc</span>.ar(<span class="s15">LFNoise0</span>.kr([10, 15], 200, [300, 500])) * 0.2 };</p>
-<p class="p6">~test.play;</p>
-<p class="p4"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>// re-send or rebuild the sound</p>
-<p class="p6">(</p>
-<p class="p6">~test = {<span class="Apple-converted-space"> </span></p>
-<p class="p15"><span class="s7"><span class="Apple-tab-span">	</span></span>SinOsc<span class="s7">.ar(</span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s4">LFNoise0</span>.kr([10, 15] * exprand(0.5, 4.0), 200, [300, 500])<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>* exprand(1.0, 4.0)</p>
-<p class="p6"><span class="Apple-tab-span">	</span>) * XLine.kr(0.5, 0.005, exprand(0.1, 10), doneAction: 2);</p>
-<p class="p6">};</p>
-<p class="p6">KeyPlayer(\px).put($t, { ~test.send });</p>
-<p class="p6">KeyPlayer(\px).put($u, { ~test.rebuild });</p>
-<p class="p6">)</p>
-</body>
-</html>

Deleted: KeyPlayer/KeyPlayer.sc
===================================================================
--- KeyPlayer/KeyPlayer.sc	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyPlayer.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,331 +0,0 @@
-
-KeyPlayer {
-	classvar <>verbose=false, <all, gui; 
-	
-	var <>key, <actions, <upActions, <bothActions, <pressed; 
-	var <>rec; 
-	 
-	*initClass { 
-		all = (); 
-	}
-	*at { |key| ^all.at(key); }	
-
-	*new { arg key = \k, inDict, ignoreCase = true; 
-		var kp = this.at(key); 
-		if (kp.isNil) { 
-			kp = super.new.key_(key); 
-			if (inDict.isNil, { kp.init(inDict, ignoreCase) });
-		};
-		^kp
-	}
-	
-	init { arg inDict, ignoreCase = false;
-				
-		all.put(key.asSymbol, this); 
-		
-		actions = ();
-		upActions = ();
-		pressed = ();
-		bothActions = (down: actions, up: upActions);
-			
-			// this needs reworking.
-			// upactions/downactions, ignoreCase ? how? 
-		inDict !? { 
-				// it is a bothActions dict
-			[\down, \up].do { |where| 
-				this.putAll(inDict[where], ignoreCase, where);
-			};
-				// else assume just keyDowns - OK?
-			inDict.keys.removeAll([\down, \up]).do { |key|
-				this.put(key, inDict[key], ignoreCase, \down);
-			}
-		};
-	}
-	
-	*gui { if (gui.isNil or: { gui.w.isClosed }){ gui = KeyPlayerGui() }; ^gui.front; }
-	
-	gui { ^KeyPlayerGui(this) }
-	
-	makeRec { rec = KeyPlayerRec(this); }
-	
-	putAll { |dict, both=false, where=\down| 
-		dict.keysValuesDo{ |k, f| this.put(k, f, both, where) }
-	}
-	
-	put { |char, func, both = false, where = \down| 
-		if (both and: { char.isKindOf(Char) } and: { char.isAlpha }) { 
-			[char.toLower, char.toUpper].do { |char|
-				this.putUni(char, func, where); 
-			};
-		} {
-			this.putUni(char, func, where); 
-		}; 
-	}
-	putUp { |char, func, both = false| 
-		this.put(char, func, both, \up);
-	}
-	
-	putDown { |char, func, both = false, noRep=false| 
-		var wrapFunc;
-		if (noRep) { 
-			wrapFunc = { |...args| if (this.isUp(char)) { func.value(*args) } }
-		};
-		this.put(char, wrapFunc ? func, both, \down);
-	}
-	
-	putBoth { |char, func, both = false, noRep=false| 
-		this.put(char, func, both, \down, noRep);
-		this.put(char, func, both, \up);
-	}
-	
-	putUni { |charOrUni, func, where=\down| 
-		bothActions[where].put(charOrUni.asUnicode, func);	}
-	isUp { |char| ^this.isDown(char).not }
-	isDown { |char| ^pressed[char.asUnicode] ? false }
-	
-	at { |char, where=\down| ^bothActions[where][char.asUnicode] }
-	
-	removeAt { |char, where=\down, both=false| this.put(char, nil, both, where) }
-	
-	keyAction { |char, modifiers, unicode, keycode, which=\down, press = true| 
-
-		 var whichActions, action, result;	
-
-		 if (verbose) { [KeyPlayer, char, modifiers, unicode, keycode].postcs; };
-		 
-		 if (rec.notNil) { rec.recordEvent(unicode, which) };
-
-				// call the function
-		unicode = unicode ?? { char.asUnicode };
-		whichActions = bothActions[which];
-		action = whichActions[unicode]; 
-		
-		result = action.value(char, modifiers, unicode, keycode);
-		pressed.put(unicode, press);
-		
-			// if the result is a function, that function 
-			// becomes the new action for the key
-		if (result.isKindOf(Function)) {
-			whichActions[char] = result;
-		};
-	}
-	keyDown { |char, modifiers, unicode, keycode| 
-		this.keyAction(char, modifiers, unicode, keycode, \down, true);
-	}
-	keyUp { |char, modifiers, unicode, keycode| 
-		this.keyAction(char, modifiers, unicode, keycode, \up, false);
-	}
-	
-	makeKeyAction { |which=\down, press = true| 
-					// define a function to handle key downs.
-		^{ |view, char, modifiers, unicode, keycode|
-			this.keyAction(char, modifiers, unicode, keycode, which, press);
-		};
-	}
-	
-	makeKeyDownAction { ^this.makeKeyAction(\down, true) }
-	makeKeyUpAction { ^this.makeKeyAction(\up, false) }
-
-	write { |path| /* save directly to a path ... */ }
-	
-	read { |path| this.putAll(path.load ? ()); } 
-	
-	save2 { 
-		Document("save me").string_(this.actions.asCompileString);
-	}
-}
-	// should be a JITGui 
-	// should be put itself on any window 
-	// etc 
-	
-KeyPlayerGui { 
-	classvar <>colors; 
-	classvar <>lineOffsets; 
-	classvar <>keyboard; 
-	classvar <>keyboardNoShift; 
-	classvar <>keyboardShift;
-	
-	var <player;
-	var <w, <zone, <buttons, <drags, <font, <listview; 
-	var <skipjack, <>activeColor;
-
-	*initClass { 
-		
-		colors = [
-			Color(0.8, 0.8, 0.8, 1),	// normal - 	grey
-			Color(0.8, 0.2, 0.2, 1),	// ctl		red
-			Color(0.2, 0.8, 0.2, 1),	// shift		green
-			Color(0.8, 0.8, 0.2, 1),	// alt		blue
-			Color(0.2, 1, 1, 1),		// alt shift	blue+green - cyan
-			Color(1, 1, 0.2, 1),		// ctl shift	red+green - yellow
-			Color(1, 0.2, 1, 1),		// ctl alt	red+blue - violet
-			Color(1, 1, 1, 1)		// ctl alt shift	red green blue - white
-		];
-
-		// these describe the keyboard to show;
-				// horizontal offsets for keys.
-		lineOffsets = #[42, 48, 57, 117];
-		
-				// these are the keys you normally see (US, big keyb.)
-				// customise for german or other keyboard layouts. 
-		keyboard = #["`1234567890-=", "QWERTYUIOP[]\\", "ASDFGHJKL;'", "ZXCVBNM,./"];
-
-			// NOT USED YET:
-				// the maps I get on my PB, US keyb., no shift
-		keyboardNoShift = #["1234567890-=", "qwertyuiop[]\\", "asdfghjkl;'", "`zxcvbnm,./"];
-				// and shifted	- /* double-quote */ only there for syntax colorize.
-		keyboardShift = #["!@#$%^&*()_+", "QWERTYUIOP{}", "ASDFGHJKL:\"|" /*"*/, "~ZXCVBNM<>?"]; 
-		
-	}
-	
-	*new { |kp, win, useList=false| 
-		^super.new.init(kp, win, useList);
-	}
-	
-	init { |kp, win, useList|
-		var zonebounds;
-		if (useList) { 
-			zonebounds = Rect(0, 0, 480, 150);
-		} { 
-			zonebounds = Rect(0, 0, 420, 170);
-		};
-
-		w = win ?? { this.makeWindow(try { kp.key } ? "KeyPlayerAll", zonebounds) };
-		zone = CompositeView(w, zonebounds);
-		zone.decorator = FlowLayout(zonebounds); 
-
-		if (useList) { 
-			this.makeListView;
-			zone.decorator.bounds = zonebounds.left_(64);
-			zone.decorator.top_(zone.decorator.top);
-		} { 
-			this.makeButtons 
-		};
-		this.makeDrags;
-
-		this.player_(kp); 
-
-	}
-	makeWindow { |name, zonebounds|
-			var win = Window("keys" + name, zonebounds).front; 
-			win.view.background_(Color(0.5, 0.5, 0.5, 0.0));
-			win.view.decorator = FlowLayout(win.view.bounds.moveTo(0,0)); 
-			^win;
-	}
-	
-	front { w.front }
-	
-	updateAll { 
-		this.updateButtons;
-		if (player.notNil) { 
-			this.updateDrags;
-			w.refresh;
-		}
-	}
-	updateButtons { 
-		var keys = KeyPlayer.all.keys.asArray.sort;
-		
-		var myIndex = -1;
-		if (player.notNil) { myIndex = keys.indexOf(player.key); }; 
-		
-			// if buttons == nil, nothing
-		buttons.do {\xCA|b, i| 
-			var col = if (i == myIndex) { Color.white } { Color.grey(0.8) };
-			var key = keys[i]; 
-			var keyExists = keys[i].notNil;
-			b.states_([[key ? "", Color.black, col]]).enabled_(keyExists);
-		};
-		
-		listview.notNil.if { 
-			listview.items_(keys).value_(myIndex);
-		};
-	}
-	updateDrags { |which = 0| 
-		var downKeys = player.actions.keys; 
-		var upKeys = player.upActions.keys; 
-		
-			// do it for "A", "a";
-
-		drags.keysValuesDo { |uni, drag| 
-			var val = 0;
-			if (downKeys.includes(uni)) { val = val + 1 };
-			if (upKeys.includes(uni)) { val = val + 2 };
-			drag.background_(colors[val])
-		}
-	}
-	makeButtons { 
-		var keys = KeyPlayer.all.keys.asArray.sort;
-		buttons = 10.collect { |i| 
-			Button(zone, Rect(0, 0, 36, 16)).states_([[ keys[i] ? "-" ]])
-				.action_({ |b| 
-					var nuKP = KeyPlayer.all[b.states[0][0]];
-					if (nuKP.notNil) { this.player_(nuKP); };
-					this.updateAll;
-				})
-		}; 
-	//	buttons[keys.indexOf(player.key)].focus;
-	}
-	
-	makeListView { 
-		listview = ListView(zone, Rect(2,2,60,25));
-		listview.bounds_(Rect(2,2,60,130));
-
-	}
-	
-	player_ { |nuplayer| 
-		if (nuplayer.isNil) { ^this };
-		
-		player = nuplayer;
-		w.view.keyDownAction_(player.makeKeyDownAction);
-		w.view.keyUpAction_(player.makeKeyUpAction);
-	}
-	
-	makeDrags {
-	
-		font = Font("Courier-Bold", 14);
-		drags = (); 
-				
-				// make the rows of the keyboard 
-		keyboard.do {|row, i| 
-			row.do {|key| this.makeKey(key) };
-			if (i==0) { this.makeKey(127.asAscii, "del", 38 @ 24) };
-			if (i==2) { this.makeKey($\r, "retrn", 46 @ 24) };
-			zone.decorator.nextLine;
-			zone.decorator.shift(lineOffsets[i]);
-		};	
-		
-//		zone.decorator.shift(lineOffsets.last.neg);
-//				// make the last row
-//		[\norm, \shift, \ctrl, \alt].do { |lab, i| 
-//			Button(zone, Rect(0,0,36,18))
-//				.states_([[lab]])
-//				.action_{ ("not used yet:" + lab).postln };
-//		};
-		
-		this.makeKey($ , "space", 150 @ 24);
-		this.makeKey(3.asAscii, "enter", 48 @ 24);
-
-				// this is maybe unnecessary?
-		skipjack = SkipJack({ 8.do { |i| this.updateAll; } }, 1, { zone.isClosed }, "KPgui");
-	}
-
-	runUpdate { skipjack.start }
-	stopUpdate { skipjack.stop }
-	
-	makeKey { |char, keyname, bounds|
-		var v;
-		keyname = keyname ? char.asString;
-		bounds = bounds ? (24 @ 24);
-	
-		v = DragBoth(zone, bounds);
-		v.font = font;
-		v.string = keyname;
-		v.align = \center;
-		v.setBoth = false;
-//		v.acceptDrag = {
-//			View.currentDrag.isKindOf(Function)
-//		};
-		drags.put(char.toLower.asUnicode, v);
-	//	v.action = { this.put(char.toLower, v.object, true) };
-	}
-}
\ No newline at end of file

Deleted: KeyPlayer/KeyPlayerGui.html
===================================================================
--- KeyPlayer/KeyPlayerGui.html	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyPlayerGui.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,34 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Style-Type" content="text/css">
-<title></title>
-<meta name="Generator" content="Cocoa HTML Writer">
-<meta name="CocoaVersion" content="1038.32">
-<style type="text/css">
-p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
-p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
-p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
-span.s1 {font: 18.0px Helvetica}
-span.s2 {font: 10.0px Monaco}
-span.Apple-tab-span {white-space:pre}
-</style>
-</head>
-<body>
-<p class="p1"><span class="s1"><b>KeyPlayerGui</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple gui for KeyPlayer</b></p>
-<p class="p2"><br></p>
-<p class="p1">Several aspects of this class could be made more flexible;</p>
-<p class="p1">supporting different display sizes, keyboard layouts,<span class="Apple-converted-space"> </span></p>
-<p class="p1">and ways of switching between several KeyPlayers may be useful.</p>
-<p class="p3"><br></p>
-<p class="p1">Dragging and dropping actions could also be supported;<span class="Apple-converted-space"> </span></p>
-<p class="p1">not sure how to do that consistently with keyUp actions, retriggering,<span class="Apple-converted-space"> </span></p>
-<p class="p1">putting things on shifted keys, etc.</p>
-<p class="p2"><br></p>
-<p class="p1"><b>see KeyPlayer for examples!</b></p>
-<p class="p3"><b></b><br></p>
-<p class="p3"><b></b><br></p>
-<p class="p3"><b></b><br></p>
-</body>
-</html>

Deleted: KeyPlayer/KeyPlayerRec.html
===================================================================
--- KeyPlayer/KeyPlayerRec.html	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyPlayerRec.html	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,82 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta http-equiv="Content-Style-Type" content="text/css">
-<title></title>
-<meta name="Generator" content="Cocoa HTML Writer">
-<meta name="CocoaVersion" content="1038.32">
-<style type="text/css">
-p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
-p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
-p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px}
-p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #dc0000}
-p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #1000d0}
-p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco}
-p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #737373}
-span.s1 {font: 18.0px Helvetica}
-span.s2 {font: 10.0px Monaco}
-span.s3 {color: #000000}
-span.s4 {color: #008a00}
-span.s5 {color: #1000d0}
-span.Apple-tab-span {white-space:pre}
-</style>
-</head>
-<body>
-<p class="p1"><span class="s1"><b>KeyPlayerRec</b></span><span class="s2"><span class="Apple-tab-span">	</span></span><b>a simple recorder for KeyPlayer</b></p>
-<p class="p2"><br></p>
-<p class="p1">KeyPlayerRec can record a series of key presses made with KeyPlayer,<span class="Apple-converted-space"> </span></p>
-<p class="p1">and play it back with variable speed.</p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p1"><b>class methods:</b></p>
-<p class="p3"><br></p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// *new needs a KeyPlayer object</p>
-<p class="p5">KeyPlayer<span class="s3">(</span><span class="s4">\kRec</span><span class="s3">);</span></p>
-<p class="p5">KeyPlayer<span class="s3">.gui;</span></p>
-<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).makeRec;</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// or make rec explicitly:<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// r = KeyPlayerRec.new();</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// k.rec = r;</p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p1"><b>examples:</b></p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// random keyboard:<span class="Apple-converted-space"> </span></p>
-<p class="p6">(</p>
-<p class="p6"><span class="s5">var</span> notes = ();</p>
-<p class="p6"><span class="s5">thisThread</span>.randSeed = 2008;</p>
-<p class="p7">"qwertzuiopasdfghjklyxcvbnm"<span class="s3">.do { </span><span class="s5">|char|</span><span class="s3"><span class="Apple-converted-space"> </span></span></p>
-<p class="p3"><br></p>
-<p class="p6"><span class="Apple-tab-span">	</span>notes.put(char, rrand(36, 96));</p>
-<p class="p3"><span class="Apple-tab-span">	</span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).put(char, { <span class="s5">|char|</span><span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// recording added here!</p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.recordEvent(char, <span class="s4">\down</span>);</p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>char.postln;<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>(midinote: notes[char]).play<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span">	</span>});</p>
-<p class="p6">};</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// use extra keys for record and play on/off</p>
-<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).putDown($,, { <span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.toggleRec }, noRep: <span class="s5">true</span>);</p>
-<p class="p6"><span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).putDown($., { <span class="s5">KeyPlayer</span>(<span class="s4">\kRec</span>).rec.togglePlay }, noRep: <span class="s5">true</span>);</p>
-<p class="p6">)</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// record a sequence now:</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// bring window to front,<span class="Apple-converted-space"> </span></p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// type ',' to start rec, type a few letter keys;</p>
-<p class="p4"><span class="s3"><span class="Apple-tab-span">	</span></span>// type ',' to stop rec, type '.' to toggle playback</p>
-<p class="p3"><br></p>
-<p class="p5"><span class="s3">k = </span>KeyPlayer<span class="s3">(</span><span class="s4">\kRec</span><span class="s3">);</span></p>
-<p class="p3"><br></p>
-<p class="p4"><span class="s3">k.rec.task.play;<span class="Apple-tab-span">	</span></span>// play it by hand</p>
-<p class="p4"><span class="s3">k.rec.list;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the list of recorded events</p>
-<p class="p6">k.rec.list.printAll;</p>
-<p class="p4"><span class="s3">k.rec.isOn;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// recording now or not?</p>
-<p class="p3"><br></p>
-<p class="p4">// maybe do automatic recording?<span class="Apple-converted-space"> </span></p>
-<p class="p4">// if so, problem: we must know which keys to record,<span class="Apple-converted-space"> </span></p>
-<p class="p4">// and which not (e.g. rec on/off controls).</p>
-<p class="p3"><br></p>
-<p class="p4">// good enough for playing with it now, extend later...</p>
-<p class="p3"><br></p>
-</body>
-</html>

Deleted: KeyPlayer/KeyPlayerRec.sc
===================================================================
--- KeyPlayer/KeyPlayerRec.sc	2013-12-26 23:54:10 UTC (rev 2672)
+++ KeyPlayer/KeyPlayerRec.sc	2013-12-27 23:09:56 UTC (rev 2673)
@@ -1,62 +0,0 @@
- /*** could be unified with CtLoop, maybe with a superclass EventLoop. ****/ 
-
-KeyPlayerRec { 
-	classvar <>verbose = false; 
-	
-	var <>isOn=false, <>list, <>player;
-	var <then, <task, <>speed = 1, <>loop = true;
-	
-	*new { |player| 
-		^super.new.player_(player);
-	}
-	
-	startRec { 
-		("recording keys: kp" + player.key).postln;
-		isOn = true; 
-		then = nil;
-		list = List.new; 
-		task = TaskProxy({ 
-			this.playFunc;
-			if (loop) { task.play } { 
-				("done: kp" + player.key).postln; 
-			}
-		});
-	}
-		
-	stopRec { 
-		if (verbose) { ("stopRec: kp" + player.key).postln }; 
-		isOn = false;
-	}
-		
-	recordEvent { |char, type=\down|
-		var now = thisThread.seconds;
-		if (isOn) {\xCA
-			then = then ? now;
-			list.add([now - then, char, type]);
-			then = now;
-		}
-	}
-	playFunc {  
-		if (verbose) { "KeyPlayRec starts!".postln; }; 
-		list.do { |trip| 
-			var time, char, type, unicode; 
-			#time, char, type = trip;
-			unicode = char.asUnicode; 
-			(time / speed.value).wait;
-			player.keyAction(char, which: type);	
-		};
-		if (verbose) { "KeyPlayRec done.".postln; };
-	}
-	
-		// play should play with a task proxy?
-		// how to do looping? 
-	playOnce { Task({ this.playFunc }).play; }
-		
-	toggleRec { if (isOn) { this.stopRec } { this.startRec } }
-	play { if (isOn) { this.stopRec }; this.playOnce; }
-	togglePlay { 
-		if (isOn) { this.stopRec }; 
-		if (task.isActive) { task.stop } { task.play };
-	}
-	changeSpeed { |factor=1| speed = speed * factor }
-}

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


_______________________________________________
sc-dev mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/