[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sc-dev] SF.net SVN: quarks:[2673] KeyPlayer
- To: sc-dev@xxxxxxxxxxxxxxxx
- Subject: [sc-dev] SF.net SVN: quarks:[2673] KeyPlayer
- From: decampo@xxxxxxxxxxxxxxxxxxxxx
- Date: Fri, 27 Dec 2013 23:09:58 +0000
- Dkim-signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:Content-Type:Subject:To:From:MIME-Version:Date; bh=WPo5naWd6pP9X4RIR4YFMWHX2UTEy7izxXn168DGC+E=; b=cu4+lxr8oQ4OOko5rq1n9WeTG9h7vMASda20+FYZLQYSTawbsuN5loHRdFNDZHLDCC2PVLC5mw0MrDKCoapv0VQr0pK7KUHLCSHf8vi7uqdEAQqptPJsWa7GCe6AmeVzna21ee1o6VG6YLPCvwt2POwfP21S1RUOfAcGZMsuq0E=;
- Dkim-signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x; h=Content-Transfer-Encoding:Content-Type:Subject:To:From:MIME-Version:Date; bh=WPo5naWd6pP9X4RIR4YFMWHX2UTEy7izxXn168DGC+E=; b=E4QpD0mgCI7Bz4Qnyp9ELZXPCWOEjeSFkd9mwerSdhLXlbghZqQ31Vc9slT++DIwgQk0cC92sLXV3XcC0AxrI9X2I1IULoxUv+jlgy4p+nBPytKzLLO9HhZDciDe1SW2sERb5ME9AWVHMGJVZrUeW0+MiPiB452y54Wg5fjDtKY=;
- List-id: SuperCollider developers mailing list <sc-devel.create.ucsb.edu>
- Reply-to: sc-dev@xxxxxxxxxxxxxxxx
- Sender: owner-sc-dev@xxxxxxxxxxxxxxxx
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/