[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[sc-dev] SF.net SVN: quarks:[2683] Wavesets
- To: sc-dev@xxxxxxxxxxxxxxxx
- Subject: [sc-dev] SF.net SVN: quarks:[2683] Wavesets
- From: decampo@xxxxxxxxxxxxxxxxxxxxx
- Date: Mon, 30 Dec 2013 21:43:15 +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=qBuqBhbHTVRfDs/7MBH6zanERwkXSW5NYmRAFa9RlL4=; b=s+dO8iO5SfRf9PrXr1qc9GhAYjbLi9B7aSz70UMvNbHKKz/j3X34VQGWUrxMzK6y8mnSQ3a9+tzhx1TOnvJcyjgiJri7QBFWqSi/jcelE51eehEvlPrLwyFzXCEqWliEFNtEa7xcBH/YPTJ5ka+km0qKhrHyNvDP9N7fqPObEd4=;
- 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=qBuqBhbHTVRfDs/7MBH6zanERwkXSW5NYmRAFa9RlL4=; b=b7fhRJlChWrB739bQmYOvZ99i9GKhQHEFxK0QLkq9Q/yg+NyNpiy/t2yem0VSsKYv3ud9Z3vuZbwXPiU5QQ17gKNUOrbrDXkTnbKUR9RMr2720dw8J+iWqMjrWtdLN9Kq+iwdAGBC1s8gbEI6X8g/5kYAmFuMyBEzS2a9VhOOwQ=;
- List-id: SuperCollider developers mailing list <sc-devel.create.ucsb.edu>
- Reply-to: sc-dev@xxxxxxxxxxxxxxxx
- Sender: owner-sc-dev@xxxxxxxxxxxxxxxx
Revision: 2683
http://sourceforge.net/p/quarks/code/2683
Author: decampo
Date: 2013-12-30 21:43:00 +0000 (Mon, 30 Dec 2013)
Log Message:
-----------
new help file, test and fix examples in 3.7.0.
Added Paths:
-----------
Wavesets/Classes/
Wavesets/Classes/Wavesets.sc
Wavesets/Help/
Wavesets/Help/Wavesets.html
Wavesets/HelpSource/
Wavesets/HelpSource/Wavesets.schelp
Removed Paths:
-------------
Wavesets/Wavesets.html
Wavesets/Wavesets.sc
Copied: Wavesets/Classes/Wavesets.sc (from rev 2676, Wavesets/Wavesets.sc)
===================================================================
--- Wavesets/Classes/Wavesets.sc (rev 0)
+++ Wavesets/Classes/Wavesets.sc 2013-12-30 21:43:00 UTC (rev 2683)
@@ -0,0 +1,246 @@
+// Analyses a soundfile's data into wavesets.
+// keep all wavesets objects in global var all.
+// only works for single channels.
+
+/*****
+SCDoc.indexAllDocuments;
+to do:
+ analyse turnaround points better:
+ reverse-interpolate where between samples
+ the actual turnaround point would be,
+ and store them in vars <fracMaxima, <fracMinima.
+*****/
+
+Wavesets {
+
+ classvar <>minLength = 10; // reasonable? => 4.4 kHz maxFreq.
+ classvar <all, formatDict;
+ classvar <>defaultInst = \wvst0;
+
+ var <signal, <name, <numFrames, <sampleRate;
+ var <xings, <lengths, <fracXings, <fracLengths,
+ <amps, <maxima, <minima;
+ var <numXings, <minSet, <maxSet, <avgLength, <sqrAvgLength,
+ <minAmp, <maxAmp, <avgAmp, <sqrAvgAmp;
+ var <>path, <buffer;
+
+ *prepareSynthDefs {
+ SynthDef(\wvst0, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;
+ var phasor = Phasor.ar(0, BufRateScale.ir(buf) * playRate, 0, length) + start;
+ var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
+ var snd = BufRd.ar(1, buf, phasor) * env;
+
+ OffsetOut.ar(out, Pan2.ar(snd, pan));
+ }, \ir.dup(8)).add;
+
+ SynthDef(\wvst1gl, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, playRate2 = 1, sustain = 1,
+ amp=0.2, pan;
+ var playRateEnv = Line.ar(playRate, playRate2, sustain);
+ var phasor = Phasor.ar(0, BufRateScale.ir(buf) * playRateEnv, 0, length) + start;
+ var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
+ var snd = BufRd.ar(1, buf, phasor) * env;
+
+ OffsetOut.ar(out, Pan2.ar(snd, pan));
+ }, \ir.dup(8)).add;
+ }
+
+ *new { arg name, sig, sampleRate;
+ ^super.new.init(name, sig, sampleRate);
+ }
+
+ *from { arg path, name, toBuffer = true, server;
+ var f, sig, ws;
+
+ f = SoundFile.new;
+ if (f.openRead(path).not) {
+ ("Wavesets.from: File" + path + "not found.").warn;
+ ^nil
+ };
+ if (f.numChannels > 1) {
+ ("File" + path + "has" + f.numChannels + "chans."
+ "Wavesets only works on mono signals, so please ...").warn;
+ // could also take first chan...
+ ^nil
+ };
+ // sampleFormat is not updated correctly in SoundFile.
+
+ sig = (formatDict[f.sampleFormat] ? Signal).newClear(f.numFrames);
+ name = name ?? { PathName(path).fileName.basename; };
+ f.readData(sig);
+ f.close;
+
+ ws = this.new(name.asSymbol, sig, f.sampleRate);
+ ws.path = path;
+ if (toBuffer) { ws.toBuffer(server) };
+
+ ^ws
+ }
+
+ toBuffer { |server|
+ server = server ? Server.default;
+ buffer = buffer ?? { Buffer(server) };
+ buffer.allocRead(path, completionMessage: {|buf|["/b_query",buf.bufnum]});
+ }
+
+ init { arg argName, argSig, argSampleRate;
+
+ if (all.at(argName).notNil and: { all.at(argName).signal.size == argSig.size },
+ {
+ ("// waveset" + argName + "seems identical to existing.\n"
+ "// ignored.").postln;
+ ^all.at(argName);
+ }
+ );
+ name = argName;
+ signal = argSig;
+ numFrames = argSig.size;
+ sampleRate = argSampleRate ? Server.default.sampleRate;
+ all.put(name, this);
+ this.analyse;
+ }
+
+ *clear { all = IdentityDictionary.new; }
+
+ *initClass {
+ this.clear;
+ formatDict = (
+ 'int8': Int16Array,
+ 'int16': Int16Array,
+ 'mulaw': Int16Array,
+ 'alaw': Int16Array,
+ 'int24': Int32Array,
+ 'int32': Int32Array,
+ 'float': Signal
+ );
+ }
+
+ *at { |key| ^all[key] }
+
+ analyse { arg finishFunc;
+ // var chunkSize = 400, pause = 0.01; // not used yet
+
+ xings = Array.new;
+ amps = Array.new;
+ lengths = Array.new;
+ fracXings = Array.new;
+ maxima = Array.new; // indices of possible turnaround points
+ minima = Array.new; //
+ ( "Analysing" + name + "...").postcln;
+
+ this.analyseFromTo;
+ this.calcAverages;
+ ("Finished signal" + name + ":" + numXings + " xings.").postcln;
+ }
+
+ calcAverages { // useful statistics.
+ // calculate maxAmp, minAmp, avgAmp, sqAvgAmp;
+ // and maxSet, minSet, avgLength, sqAvgLength;
+
+ numXings = xings.size;
+ minSet = lengths.minItem;
+ maxSet = lengths.maxItem;
+ minAmp = amps.minItem;
+ maxAmp = amps.maxItem;
+
+ fracLengths = fracXings.drop(1) - fracXings.drop(-1);
+
+ avgLength = xings.last - xings.first / numXings;
+ sqrAvgLength = ( lengths.squared.sum / ( numXings - 1) ).sqrt;
+
+ avgAmp = amps.sum / numXings;
+ sqrAvgAmp = (amps.squared.sum / numXings).sqrt;
+
+ ^this;
+ }
+
+ // should eventually support analysis in blocks in realtime.
+
+ analyseFromTo { arg startFrame = 0, endFrame;
+ var lengthCount = 0, prevSample = 0.0,
+ maxSamp = 0.0, minSamp = 0.0,
+ maxAmpIndex, minAmpIndex,
+ wavesetAmp, frac;
+
+ // find xings, store indices, lengths, and amps.
+
+ startFrame = max(0, startFrame);
+ endFrame = (endFrame ? signal.size - 1).min(signal.size - 1);
+
+ ( startFrame to: endFrame ).do({ arg i;
+ var thisSample;
+ thisSample = signal.at(i);
+
+ // if Xing from non-positive to positive:
+ if ( (prevSample <= 0.0) and: (thisSample > 0.0) and: (lengthCount >= minLength),
+
+ {
+
+ if (xings.notEmpty, {
+ // if we already have a first waveset,
+ // keep results from analysis:
+ wavesetAmp = max(maxSamp, minSamp.abs);
+ amps = amps.add(wavesetAmp);
+ lengths = lengths.add(lengthCount);
+ maxima = maxima.add(maxAmpIndex);
+ minima = minima.add(minAmpIndex);
+ });
+
+ xings = xings.add(i);
+
+ // lin interpol for fractional crossings
+ frac = prevSample / (prevSample - thisSample);
+ fracXings = fracXings.add( i - 1 + frac );
+
+ // reset vars for next waveset
+ maxSamp = 0.0;
+ minSamp = 0.0;
+ lengthCount = 0;
+ }
+ );
+ lengthCount = lengthCount + 1;
+ if (thisSample > maxSamp) { maxSamp = thisSample; maxAmpIndex = i };
+ if (thisSample < minSamp) { minSamp = thisSample; minAmpIndex = i };
+ prevSample = thisSample;
+ });
+ }
+ // convenience methods:
+ plot { |startWs=0, length=1|
+ var data = this.frameFor(startWs, length, false).postln;
+ var segment = signal.copyRange(data[0], data[0] + data[1] - 1);
+ var peak = max(segment.maxItem, segment.minItem.abs);
+ segment.plot("Waveset" + name +
+ ": startWs" + startWs +
+ ", length" + length +
+ ", sustain" + data[2].round(0.000001),
+ minval: peak.neg,
+ maxval: peak);
+ }
+
+ eventFor { |startWs=0, numWs=5, repeats=3, playRate=1, useFrac = true|
+ var start, length, sustain1;
+ #start, length, sustain1 = this.frameFor(startWs, numWs, useFrac);
+ ^(start: start,
+ length: length,
+ sustain: sustain1 / playRate * repeats,
+ playRate: playRate,
+ buf: buffer,
+ instrument: defaultInst,
+ wsAmp: this.ampFor(startWs, numWs)
+ )
+ }
+
+ ampFor { |startWs, length=1|
+ ^amps.copyRange(startWs, startWs + length - 1).maxItem;
+ }
+
+ frameFor { arg startWs, numWs = 1, useFrac = true;
+ var whichXings = if (useFrac) { fracXings } { xings };
+ var startFrame = whichXings.clipAt(startWs);
+ var endFrame = whichXings.clipAt(startWs + numWs);
+ var length = endFrame - startFrame;
+ var sustain = length / sampleRate;
+
+ ^[startFrame, length, sustain]
+ }
+
+}
Copied: Wavesets/Help/Wavesets.html (from rev 2676, Wavesets/Wavesets.html)
===================================================================
--- Wavesets/Help/Wavesets.html (rev 0)
+++ Wavesets/Help/Wavesets.html 2013-12-30 21:43:00 UTC (rev 2683)
@@ -0,0 +1,358 @@
+<!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="949.46">
+<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: 9.0px Monaco; min-height: 12.0px}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
+p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
+p.p9 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #782727}
+p.p10 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco}
+p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
+p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #782727}
+p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+p.p14 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #0428b3}
+p.p15 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
+p.p16 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica; min-height: 17.0px}
+p.p17 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #4d4d4d}
+p.p18 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #484d3c}
+p.p19 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #303e67}
+p.p20 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Lucida Grande}
+p.p21 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #6b5150}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {color: #000000}
+span.s3 {color: #0428b3}
+span.s4 {color: #782727}
+span.s5 {color: #0a2eb5}
+span.s6 {color: #303e67}
+span.s7 {color: #484d3c}
+span.s8 {color: #556b17}
+span.s9 {color: #4d4d4d}
+span.s10 {font: 9.0px Monaco}
+span.s11 {color: #961e1e}
+span.s12 {color: #001db9}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>Wavesets<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b></span><b>analyse soundfiles into short fragments for granular synthesis</b></p>
+<p class="p2"><br></p>
+<p class="p1"><b>Inherits from: Object</b></p>
+<p class="p3"><br></p>
+<p class="p1">Wavesets analyses soundfiles into short fragments called wavesets, and keeps these waveset data.</p>
+<p class="p1">It can support a variety of waveset based synthesis instruments.</p>
+<p class="p2"><br></p>
+<p class="p1">By Trevor Wishart's definition, a waveset is a segment of an audio signal between<span class="Apple-converted-space"> </span></p>
+<p class="p1">one non-positive to positive zero crossing and the next. [ see T. Wishart (1994): Audible Design. ]</p>
+<p class="p1">Note that this definition only applies to mono signals.</p>
+<p class="p2"><span class="Apple-tab-span"> </span></p>
+<p class="p4"><b>Creation / Class Methods</b></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*from (path, name, toBuffer)</b></p>
+<p class="p7"><b><span class="Apple-tab-span"> </span></b></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>Read a soundfile, analyse the signal, read the file to a buffer</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>path </b>- the path to the soundfile</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>name </b>- a name by which to keep the new wavesets in a global dictionary</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>toBuffer </b>- a boolean whether to load the file to a buffer immediately.</p>
+<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p9"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// a first little example</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Server</span>.default = s = <span class="s3">Server</span>.internal; s.boot;</p>
+<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// make a wavesets from a soundfile</p>
+<p class="p11"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = </span><span class="s3">Wavesets</span><span class="s2">.from(</span>"sounds/a11wlk01.wav"<span class="s2">);<span class="Apple-tab-span"> </span></span></p>
+<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.dump;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// contains mainly analysis data<span class="Apple-converted-space"> </span></p>
+<p class="p3"><span class="s4"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(200, 1);<span class="Apple-tab-span"> </span></span>// plot a single waveset</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.signal.copyRange(w.xings[600], w.xings[601]).plot;</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(600, 1);<span class="Apple-tab-span"> </span><span class="s4">// a single</span></p>
+<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(600, 5);<span class="Apple-tab-span"> </span></span>// a group of five contiguous wavesets</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.buffer;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.buffer.play;</p>
+<p class="p5"><span class="Apple-tab-span"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Wavesets</span>.prepareSynthDefs;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// startWs</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 5, repeats: 2).postln.play;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 2, playRate: 1, repeats: 5).postln.play;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 2, playRate: 0.5, repeats: 5).postln.play;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(700, 20, 5, 1).play;</p>
+<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span>(</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>fork {<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>666.do { <span class="s3">|i|</span><span class="Apple-converted-space"> </span></p>
+<p class="p10"><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="s3">var</span> ev = w.eventFor(i * 5, 2, 5, exprand(0.5, 1.0));<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.put(\pan, 1.0.rand2).play;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.sustain.wait;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span>)</p>
+<p class="p5"><br></p>
+<p class="p5"><span class="Apple-tab-span"> </span></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*new (name, sig, sampleRate)</b></p>
+<p class="p7"><b><span class="Apple-tab-span"> </span></b></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>Make a Wavesets from a signal directly - not typical usage, but may be needed sometimes.</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>name </b>- a name by which to keep the new wavesets in a global dictionary</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>sig </b>- the signal to be analysed Explanation of sig. Default value is nil. Other information.</p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>sampleRate </b>- Explanation of sampleRate. Default value is nil. Other information.</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>all</b><span class="Apple-tab-span"> </span>A dictionary where all the wavesets are kept by name.<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Existing wavesets in .all are not re-analysed.</p>
+<p class="p14"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>Wavesets<span class="s2">.all;</span></p>
+<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*at (key)</b><span class="Apple-tab-span"> </span>Access a Wavesets by its name.<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>key </b>- The name to look up</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>g = <span class="s5">Wavesets</span>.at('a11wlk01.wav');</p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*clear<span class="Apple-tab-span"> </span></b>Clear the global dictionary</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Wavesets</span>.clear;</p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*minLength</b><span class="Apple-tab-span"> </span>set the shortest length (in frames) that will still be treated as a waveset. Shorter<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>wavesets are merged with their neighbors.<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p7"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>*prepareSynthDefs </b><span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>prepare some Synthdefs to be used with wavesets.<span class="Apple-converted-space"> <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></p>
+<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p5"><br></p>
+<p class="p15"><b>Accessing Instance and Class Variables</b></p>
+<p class="p7"><span class="Apple-tab-span"> </span></p>
+<p class="p6"><span class="Apple-tab-span"> </span><b>signal <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the audio signal that was analysed.<span class="Apple-converted-space"> </span></p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>name <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the wavesets name in the global dictionary</p>
+<p class="p1"><span class="Apple-tab-span"> </span><b>buffer</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a buffer on the server that was created from the same soundfile</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>numFrames <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the number of frames</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>sampleRate <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the sample rate of the signal, default is Server.default.sampleRate</p>
+<p class="p3"><span class="Apple-converted-space"> </span></p>
+<p class="p7"><br></p>
+<p class="p6"><b>The following variables are analysis result lists</b></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>xings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>all integer indices of the zero crossings found</p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>numXings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>total number of zero crossings found</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>lengths<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>lengths of all wavesets</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>amps<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>peak amplitude of every waveset</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>maxima<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>indices of positive maximum value in every waveset</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>minima<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>indices of negative minimum value in every waveset</p>
+<p class="p2"><b><span class="Apple-tab-span"> </span></b></p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>fracXings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the calculated fractional zerocrossing points.</p>
+<p class="p1"><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>this allows for more precise pitch information</p>
+<p class="p1"><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>and waveset transitions, resulting in smoother sound.</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>fracLengths<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>fractional lengths - in effect, waveset 'pitch'.</p>
+<p class="p2"><b><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></b></p>
+<p class="p1"><b>These are overall statistics of the entire wavesets<span class="Apple-tab-span"> </span></b></p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>minSet<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>shorted waveset</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>maxSet<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>longest waveset</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>avgLength<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>average length of all wavesets</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>sqrAvgLength<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>weighted average length - so bigger wavesets have a larger impact</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>minAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>softest waveset amplitude</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>maxAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>loudest waveset amplitude</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>avgAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>average amplitude of the entire waveset</p>
+<p class="p1"><b><span class="Apple-tab-span"> </span>sqrAvgAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>weighted average of (squared) amplitude of the entire waveset</p>
+<p class="p2"><br></p>
+<p class="p7"><br></p>
+<p class="p6"><b>Some utility instance methods:</b></p>
+<p class="p7"><br></p>
+<p class="p6"><span class="Apple-tab-span"> </span><b>toBuffer(server)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>load the analysed soundfile to the buffer.</p>
+<p class="p7"><span class="Apple-tab-span"> </span></p>
+<p class="p1"><span class="Apple-tab-span"> </span><b>frameFor(startWs, numWs, useFrac)<span class="Apple-tab-span"> </span></b><span class="Apple-tab-span"> </span></p>
+<p class="p1"><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>calculate startFrame, length in frames, and duration<span class="Apple-converted-space"> </span></p>
+<p class="p1"><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>for a waveset or group. useFrac = true means use fractional crossings.<span class="Apple-converted-space"> </span></p>
+<p class="p1"><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>true by default.</p>
+<p class="p2"><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></p>
+<p class="p1"><span class="Apple-tab-span"> </span><b>ampFor(startWs, length)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>maximum amp that occurs in a waveset or group.</p>
+<p class="p2"><span class="Apple-tab-span"> </span></p>
+<p class="p1"><span class="Apple-tab-span"> </span><b>eventFor(startWs, numWs, repeats, playRate, useFrac)</b></p>
+<p class="p1"><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>generate an event for a given combination of start waveset index,</p>
+<p class="p1"><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>number of wavesets, repeats, playback rate, and use of fractional crossings.</p>
+<p class="p2"><br></p>
+<p class="p6"><b><span class="Apple-tab-span"> </span>plot (startWs, length)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>plot a waveset or group for a given waveset index and length.</p>
+<p class="p2"><span class="Apple-tab-span"> </span></p>
+<p class="p2"><span class="Apple-tab-span"> </span></p>
+<p class="p15"><b>Examples</b></p>
+<p class="p3"><br></p>
+<p class="p13">The simplest usage is to ask the waveset to prepare an event for you.</p>
+<p class="p3"><br></p>
+<p class="p11"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = </span><span class="s3">Wavesets</span><span class="s2">.from(</span>"sounds/a11wlk01.wav"<span class="s2">);<span class="Apple-tab-span"> </span></span></p>
+<p class="p3"><br></p>
+<p class="p10"><span class="Apple-tab-span"> </span>(</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>fork {<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>666.do { <span class="s3">|i|</span><span class="Apple-converted-space"> </span></p>
+<p class="p10"><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="s3">var</span> ev = w.eventFor((i * 5).postln, 2, 5, exprand(0.5, 1.0));<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.put(\pan, 1.0.rand2).play;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.sustain.wait;</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}</p>
+<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p10"><span class="Apple-tab-span"> </span>)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p4"><span class="Apple-tab-span"> </span>// play a single waveset or waveset group by hand</p>
+<p class="p13">(</p>
+<p class="p13">{ <span class="Apple-tab-span"> </span><span class="s6">var</span> startFr, endFr, dur;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>startFr = w.xings[800];<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>endFr = w.xings[820];</p>
+<p class="p3"><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>dur = endFr - startFr / w.buffer.sampleRate;</p>
+<p class="p13"><span class="Apple-tab-span"> </span>dur.postln;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">BufRd</span>.ar(1, w.buffer, <span class="s6">Line</span>.ar(startFr, endFr, dur, doneAction: 2))<span class="Apple-converted-space"> </span></p>
+<p class="p13">}.play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p4"><span class="Apple-tab-span"> </span>loop buffer segments with a Phasor:</p>
+<p class="p13">(</p>
+<p class="p13">x = { <span class="s6">arg</span> start = 0, end = 128, playRate = 1;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">BufRd</span>.ar(1, w.buffer,<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s6">Phasor</span>.ar(0, playRate * <span class="s6">BufRateScale</span>.kr(w.buffer), start, end)</p>
+<p class="p13"><span class="Apple-tab-span"> </span>)</p>
+<p class="p13">}.scope(zoom: 8);</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p13">x.set(<span class="s7">\start</span>, 0, <span class="s7">\end</span>, 1024);<span class="Apple-tab-span"> </span>// just some random length, may buzz</p>
+<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(100), <span class="s7">\end</span>, w.xings.at(101));</p>
+<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(101), <span class="s7">\end</span>, w.xings.at(102));</p>
+<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(100), <span class="s7">\end</span>, w.xings.at(200));</p>
+<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(780), <span class="s7">\end</span>, w.xings.at(800));</p>
+<p class="p13">x.set(<span class="s7">\playRate</span>, 0.25);</p>
+<p class="p13">x.set(<span class="s7">\playRate</span>, 1);</p>
+<p class="p3"><br></p>
+<p class="p13">x.release;</p>
+<p class="p3"><br></p>
+<p class="p7"><br></p>
+<p class="p7"><br></p>
+<p class="p15"><b>Doing Some Task (optional)</b></p>
+<p class="p16"><br></p>
+<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p15"><b>Examples</b></p>
+<p class="p2"><br></p>
+<p class="p1"><b>To play a waveset (or group) for a precise number of repetitions,<span class="Apple-converted-space"> </span></b></p>
+<p class="p1"><b>one can use a SynthDef with a hard cutoff envelope, as below.</b></p>
+<p class="p1"><b>Note that adding an offset outside the phasor works better;<span class="Apple-converted-space"> </span></b></p>
+<p class="p1"><b>Phasor.ar(0, playRate, start, end) is sometimes off by a few samples.</b></p>
+<p class="p1"><b>This is likely a 32bit float precision problem.</b></p>
+<p class="p3"><br></p>
+<p class="p12"><span class="s2">(<span class="Apple-tab-span"> </span></span>// the simplest synthdef as implented in *prepareSynthDefs:<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="s3">SynthDef</span>(<span class="s8">\wvst0</span>, { <span class="s3">arg</span> out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> phasor = <span class="s3">Phasor</span>.ar(0, <span class="s3">BufRateScale</span>.ir(buf) * playRate, 0, length) + start;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> env = <span class="s3">EnvGen</span>.ar(<span class="s3">Env</span>([amp, amp, 0], [sustain, 0]), doneAction: 2);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> snd = <span class="s3">BufRd</span>.ar(1, buf, phasor) * env;</p>
+<p class="p3"><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">OffsetOut</span>.ar(out, <span class="s3">Pan2</span>.ar(snd, pan));</p>
+<p class="p13">}, <span class="s8">\ir</span>.dup(8)).memStore;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="s6">Synth</span>(<span class="s9">"wvst0"</span>, [<span class="s7">\bufnum</span>, b, <span class="s7">\start</span>, 0, <span class="s7">\length</span>, 5000, <span class="s7">\sustain</span>, 0.1]);</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span"> </span>// do the math by hand to understand it:</p>
+<p class="p13">(</p>
+<p class="p13"><span class="s6">var</span> startWs = 100, length = 6, rep = 10, <span class="s7">playRate</span> = 0.5;</p>
+<p class="p13"><span class="s6">var</span> startframe, endframe, sustain;</p>
+<p class="p3"><br></p>
+<p class="p13">startframe = w.xings[startWs];</p>
+<p class="p13">endframe = w.xings[startWs + length];</p>
+<p class="p13"><span class="s7">sustain</span> = (endframe - startframe) * rep / playRate / w.sampleRate;<span class="Apple-converted-space"> </span></p>
+<p class="p3"><br></p>
+<p class="p17"><span class="s6">Synth</span><span class="s2">(</span>"wvst0"<span class="s2">, [</span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\bufnum</span>, w.buffer,<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\start</span>, startframe,<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\length</span>, endframe - startframe,<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\playRate</span>, playRate,</p>
+<p class="p18"><span class="s2"><span class="Apple-tab-span"> </span></span>\sustain<span class="s2">, </span>sustain<span class="s2">,<span class="Apple-converted-space"> </span></span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\amp</span>, 1</p>
+<p class="p13">]);</p>
+<p class="p13">)</p>
+<p class="p13"><span class="Apple-tab-span"> </span>// the same done with eventFor:</p>
+<p class="p13">w.eventFor(100, 6, repeats: 10, playRate: 0.5).put(\amp, 1).play;</p>
+<p class="p3"><br></p>
+<p class="p13">(</p>
+<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>300.do({ <span class="s6">arg</span> i;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(100 + i, 2, 10, 1);</p>
+<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\pan, [-1, 1].choose, \amp, 0.5]);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>});</p>
+<p class="p13">}).play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p20"><span class="s10">x = </span>a11wlk01-44_1.aiff;<span class="Apple-converted-space"> </span></p>
+<p class="p3"><br></p>
+<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// compare fractional and integer xings:</p>
+<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// especially for high frequency signals,<span class="Apple-converted-space"> </span></p>
+<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// fractional does slightly cleaner looping and finer pitch gradations.</p>
+<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// - better test below with ordering wavesets by length -</p>
+<p class="p13">(</p>
+<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>[true, false].do { |usefrac|<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(1250..1500).do { <span class="s6">arg</span> i;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(i, 1, 100, 1, useFrac: usefrac);</p>
+<p class="p3"><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></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([<span class="s11">/*\pan, 0 [-1, 1].choose,*/</span> \amp, 0.5]);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>1.wait;</p>
+<p class="p13"><span class="Apple-tab-span"> </span>};</p>
+<p class="p13">}).play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// some variants waveset timestretch</p>
+<p class="p13">(</p>
+<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// segments of 10 wavesets, step by 1 => 10x longer</p>
+<p class="p13"><span class="Apple-tab-span"> </span>(300, 301 .. 900).do { <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 10, repeats: 1);</p>
+<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>};</p>
+<p class="p13"><span class="Apple-tab-span"> </span>1.wait;<span class="Apple-converted-space"> </span></p>
+<p class="p3"><br></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// 1 waveset at a time, loop 10 times - much more 'pitch beads'-like</p>
+<p class="p13"><span class="Apple-tab-span"> </span>(300, 301 .. 900).do { <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 1, repeats: 10);</p>
+<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>};</p>
+<p class="p3"><span class="Apple-tab-span"> </span></p>
+<p class="p13">}).play;</p>
+<p class="p13">)</p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p3"><br></p>
+<p class="p21"><span class="s2"><span class="Apple-tab-span"> </span></span>// play them sorted by (integer) waveset length:<span class="Apple-converted-space"> </span></p>
+<p class="p13">w.lengths.plot;<span class="Apple-tab-span"> </span>// lengths are very irregular</p>
+<p class="p13">o = w.lengths.order;</p>
+<p class="p3"><br></p>
+<p class="p13">(</p>
+<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">var</span> start, end, startFr, endFr, dur, repeats;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">var</span> order;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>order = w.lengths.order;</p>
+<p class="p3"><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>[\false, \true].do { |useFrac|<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>if (useFrac) { "fractional crossings - better pitch resolution" } {</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>"integer waveset borders - pitches quantized to integer sample lengths"</p>
+<p class="p13"><span class="Apple-tab-span"> </span>}.postln;</p>
+<p class="p3"><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>order.do({ <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 1, repeats: 5);</p>
+<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
+<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
+<p class="p13"><span class="Apple-tab-span"> </span>});</p>
+<p class="p13">}).play;</p>
+<p class="p13">)</p>
+</body>
+</html>
Added: Wavesets/HelpSource/Wavesets.schelp
===================================================================
--- Wavesets/HelpSource/Wavesets.schelp (rev 0)
+++ Wavesets/HelpSource/Wavesets.schelp 2013-12-30 21:43:00 UTC (rev 2683)
@@ -0,0 +1,357 @@
+TITLE:: Wavesets
+summary:: analyse soundfiles into short fragments for granular synthesis
+categories:: GranularSynthesis
+related:: Buffer, Event
+
+DESCRIPTION::
+Wavesets analyses soundfiles into short fragments called wavesets, and contains these waveset data and their info. It can support a variety of waveset based synthesis instruments.
+
+By Trevor Wishart's definition, a waveset is a segment of an audio signal between
+one non-positive to positive zero crossing and the next. [ see T. Wishart (1994): Audible Design. ] Note that this definition only applies to mono signals.
+
+In extension of that concept, the Wavesets class provides fractional zero crossings, amplitude analyses, and other statistical data.
+
+See also the end of Chapter 16, Microsound, in the SuperCollider Book at MIT Press for detailed examples.
+
+code::
+
+Server.default = s = Server.internal; s.boot;
+
+ // make a wavesets from a soundfile
+w = Wavesets.from(String.scDir +/+ "sounds/a11wlk01.wav");
+w.dump; // contains mainly analysis data
+
+w.plot(200, 1); // plot a single waveset
+w.signal.copyRange(w.xings[600], w.xings[601]).plot;
+
+w.plot(600, 1); // a single
+w.plot(600, 5); // a group of five contiguous wavesets
+w.buffer;
+w.buffer.play;
+
+Wavesets.prepareSynthDefs;
+ // startWs
+w.eventFor(startWs: 600, length: 5, repeats: 2).postln.play;
+w.eventFor(startWs: 600, length: 2, playRate: 1, repeats: 5).postln.play;
+w.eventFor(startWs: 600, length: 2, playRate: 0.5, repeats: 5).postln.play;
+w.eventFor(700, 20, 5, 1).play;
+
+(
+fork {
+ 666.do { |i|
+ var ev = w.eventFor(i * 5, 2, 5, exprand(0.5, 1.0));
+ ev.put(\pan, 1.0.rand2).play;
+ ev.sustain.wait;
+ }
+};
+)
+::
+
+CLASSMETHODS::
+
+private:: initClass
+
+METHOD:: prepareSynthDefs
+prepare some basic synthdefs that can be used for Wavesets synthesis (when using the eventFor method).
+
+METHOD:: all
+global dict for all instances of Wavesets
+
+METHOD:: at
+access instances in Wavesets.all by name (key).
+ARGUMENT:: key
+a symbol.
+
+METHOD:: clear
+clear all existing wavesets from the Wavesets.all.
+
+METHOD:: from
+make a Wavesets from a emphasis::MONO:: soundfile at path.
+ARGUMENT:: path
+the path to the soundfile.
+
+ARGUMENT:: name
+the name by which to store the Wavesets instance.
+
+ARGUMENT:: toBuffer
+flag whether to make a buffer that that soundfile. default = true.
+
+ARGUMENT:: server
+the server on which to load the soundfile. default = s.
+
+METHOD:: new
+make a new Wavesets instance. *from is much more common.
+
+METHOD:: minLength
+The minimum number of sample points a single Waveset can have. This is used to avoid lots of extremely short samples in noisy samples. Logical minimum is 2, default is 10.
+
+METHOD:: defaultInst
+get and set the name of the default synthdef to use in Wavesets event-related methods.
+
+
+INSTANCEMETHODS::
+
+subSection:: Instance variables
+
+method:: signal
+the audio signal that was analysed.
+
+method:: name
+the wavesets name in the global dictionary
+
+method:: buffer
+a buffer on the server that was created from the same soundfile
+
+method:: numFrames
+the number of frames of the soundfile, the buffer and the Wavesets
+
+method:: sampleRate
+the sample rate of the signal/buffer. default is s.sampleRate
+
+strong:: These variables are analysis result lists:
+method:: xings
+all integer indices of the zero crossings found
+method:: numXings
+total number of zero crossings found
+method:: lengths
+lengths of all wavesets
+method:: amps
+peak amplitude of every waveset
+method:: maxima
+indices of positive maximum value in every waveset
+method:: minima
+indices of negative minimum value in every waveset
+
+method:: fracXings
+the calculated fractional zerocrossing points. This allows for more precise pitch information and waveset transitions, resulting in smoother sound.
+method:: fracLengths
+fractional lengths - in effect, this is 1/wavesetFreq.
+
+strong:: These are overall statistics of the entire Wavesets:
+method:: minSet
+shorted waveset
+method:: maxSet
+longest waveset
+method:: avgLength
+average length of all wavesets
+method:: sqrAvgLength
+weighted average length - so bigger wavesets have a larger impact
+method:: minAmp
+softest waveset amplitude
+method:: maxAmp
+loudest waveset amplitude
+method:: avgAmp
+average amplitude of the entire waveset
+method:: sqrAvgAmp
+weighted average of (squared) amplitude of the entire waveset
+
+strong:: Instance methods
+
+METHOD:: eventFor
+generate an event for a given combination of start waveset index, number of wavesets, repeats, playback rate, and use of fractional crossings.
+
+ARGUMENT:: startWs, numWs, repeats, playRate, useFrac
+
+METHOD:: minima
+
+METHOD:: frameFor
+
+METHOD:: analyse
+analyse the entire soundfile, then do finishFunc
+
+METHOD:: analyseFromTo
+analyse the soundfile from given startFrame to endFrame
+
+METHOD:: calcAverages
+analysis to do after loading.
+
+METHOD:: toBuffer
+create a buffer for the Waevesets on the server given.
+
+METHOD:: plot
+plot a section of <length> Wavesets from <startWs>
+
+EXAMPLES::
+
+code::
+The simplest usage is to ask the waveset to prepare an event for you.
+
+ w = Wavesets.from("sounds/a11wlk01.wav");
+
+ (
+ fork {
+ 666.do { |i|
+ var ev = w.eventFor((i * 5).postln, 2, 5, exprand(0.5, 1.0));
+ ev.put(\pan, 1.0.rand2).play;
+ ev.sustain.wait;
+ }
+ };
+ )
+
+
+
+
+ // play a single waveset or waveset group by hand
+(
+{ var startFr, endFr, dur;
+ startFr = w.xings[800];
+ endFr = w.xings[820];
+
+ dur = endFr - startFr / w.buffer.sampleRate;
+ dur.postln;
+ BufRd.ar(1, w.buffer, Line.ar(startFr, endFr, dur, doneAction: 2))
+}.play;
+)
+
+ loop buffer segments with a Phasor:
+(
+x = { arg start = 0, end = 128, playRate = 1;
+ BufRd.ar(1, w.buffer,
+ Phasor.ar(0, playRate * BufRateScale.kr(w.buffer), start, end)
+ )
+}.scope(zoom: 8);
+)
+
+x.set(\start, 0, \end, 1024); // just some random length, may buzz
+x.set(\start, w.xings.at(100), \end, w.xings.at(101));
+x.set(\start, w.xings.at(101), \end, w.xings.at(102));
+x.set(\start, w.xings.at(100), \end, w.xings.at(200));
+x.set(\start, w.xings.at(780), \end, w.xings.at(800));
+x.set(\playRate, 0.25);
+x.set(\playRate, 1);
+
+x.release;
+
+::
+
+Doing Some Task (optional)
+
+Examples
+
+code::
+To play a waveset (or group) for a precise number of repetitions,
+one can use a SynthDef with a hard cutoff envelope, as below.
+Note that adding an offset outside the phasor works better;
+Phasor.ar(0, playRate, start, end) is sometimes off by a few samples.
+This is likely a 32bit float precision problem.
+
+( // the simplest synthdef as implented in *prepareSynthDefs:
+SynthDef(\wvst0, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;
+ var phasor = Phasor.ar(0, BufRateScale.ir(buf) * playRate, 0, length) + start;
+ var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
+ var snd = BufRd.ar(1, buf, phasor) * env;
+
+ OffsetOut.ar(out, Pan2.ar(snd, pan));
+}, \ir.dup(8)).memStore;
+)
+
+Synth("wvst0", [\bufnum, b, \start, 0, \length, 5000, \sustain, 0.1]);
+
+ // do the math by hand to understand it:
+(
+var startWs = 100, length = 6, rep = 10, playRate = 0.5;
+var startframe, endframe, sustain;
+
+startframe = w.xings[startWs];
+endframe = w.xings[startWs + length];
+sustain = (endframe - startframe) * rep / playRate / w.sampleRate;
+
+Synth("wvst0", [
+ \bufnum, w.buffer,
+ \start, startframe,
+ \length, endframe - startframe,
+ \playRate, playRate,
+ \sustain, sustain,
+ \amp, 1
+]);
+)
+ // the same done with eventFor:
+w.eventFor(100, 6, repeats: 10, playRate: 0.5).put(\amp, 1).play;
+
+(
+Task({
+ 300.do({ arg i;
+ var ev = w.eventFor(100 + i, 2, 10, 1);
+
+ ev.putPairs([\pan, [-1, 1].choose, \amp, 0.5]);
+ ev.play;
+ (ev.sustain).wait;
+ });
+}).play;
+)
+
+x = a11wlk01-44_1.aiff;
+
+ // compare fractional and integer xings:
+ // especially for high frequency signals,
+ // fractional does slightly cleaner looping and finer pitch gradations.
+ // - better test below with ordering wavesets by length -
+(
+Task({
+ [true, false].do { |usefrac|
+ (1250..1500).do { arg i;
+ var ev = w.eventFor(i, 1, 100, 1, useFrac: usefrac);
+
+ ev.putPairs([/*\pan, 0 [-1, 1].choose,*/ \amp, 0.5]);
+ ev.play;
+ (ev.sustain).wait;
+ };
+ 1.wait;
+ };
+}).play;
+)
+
+ // some variants waveset timestretch
+(
+Task({
+ // segments of 10 wavesets, step by 1 => 10x longer
+ (300, 301 .. 900).do { arg start;
+ var ev = w.eventFor(start, numWs: 10, repeats: 1);
+
+ ev.putPairs([\amp, 0.5]);
+ ev.play;
+ (ev.sustain).wait;
+ };
+ 1.wait;
+
+ // 1 waveset at a time, loop 10 times - much more 'pitch beads'-like
+ (300, 301 .. 900).do { arg start;
+ var ev = w.eventFor(start, numWs: 1, repeats: 10);
+
+ ev.putPairs([\amp, 0.5]);
+ ev.play;
+ (ev.sustain).wait;
+ };
+
+}).play;
+)
+
+
+
+ // play them sorted by (integer) waveset length:
+w.lengths.plot; // lengths are very irregular
+o = w.lengths.order;
+
+(
+Task {
+ var start, end, startFr, endFr, dur, repeats;
+ var order = w.lengths.order;
+
+ [false, true].do { |useFrac|
+ if (useFrac) {
+ "fractional crossings - better pitch resolution."
+ } {
+ "integer crossings - pitches quantized to integer sample lengths."
+ }.postln;
+
+ order.do { arg start;
+ var ev = w.eventFor(start, numWs: 1, repeats: 5);
+ ev.putPairs([\amp, 0.5]);
+ ev.play;
+ (ev.sustain).wait;
+ };
+ 0.5.wait;
+ };
+}.play;
+)
+::
\ No newline at end of file
Deleted: Wavesets/Wavesets.html
===================================================================
--- Wavesets/Wavesets.html 2013-12-30 00:06:32 UTC (rev 2682)
+++ Wavesets/Wavesets.html 2013-12-30 21:43:00 UTC (rev 2683)
@@ -1,358 +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="949.46">
-<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: 9.0px Monaco; min-height: 12.0px}
-p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
-p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
-p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
-p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
-p.p8 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
-p.p9 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #782727}
-p.p10 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco}
-p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
-p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #782727}
-p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
-p.p14 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #0428b3}
-p.p15 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
-p.p16 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica; min-height: 17.0px}
-p.p17 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #4d4d4d}
-p.p18 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #484d3c}
-p.p19 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #303e67}
-p.p20 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Lucida Grande}
-p.p21 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #6b5150}
-span.s1 {font: 18.0px Helvetica}
-span.s2 {color: #000000}
-span.s3 {color: #0428b3}
-span.s4 {color: #782727}
-span.s5 {color: #0a2eb5}
-span.s6 {color: #303e67}
-span.s7 {color: #484d3c}
-span.s8 {color: #556b17}
-span.s9 {color: #4d4d4d}
-span.s10 {font: 9.0px Monaco}
-span.s11 {color: #961e1e}
-span.s12 {color: #001db9}
-span.Apple-tab-span {white-space:pre}
-</style>
-</head>
-<body>
-<p class="p1"><span class="s1"><b>Wavesets<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b></span><b>analyse soundfiles into short fragments for granular synthesis</b></p>
-<p class="p2"><br></p>
-<p class="p1"><b>Inherits from: Object</b></p>
-<p class="p3"><br></p>
-<p class="p1">Wavesets analyses soundfiles into short fragments called wavesets, and keeps these waveset data.</p>
-<p class="p1">It can support a variety of waveset based synthesis instruments.</p>
-<p class="p2"><br></p>
-<p class="p1">By Trevor Wishart's definition, a waveset is a segment of an audio signal between<span class="Apple-converted-space"> </span></p>
-<p class="p1">one non-positive to positive zero crossing and the next. [ see T. Wishart (1994): Audible Design. ]</p>
-<p class="p1">Note that this definition only applies to mono signals.</p>
-<p class="p2"><span class="Apple-tab-span"> </span></p>
-<p class="p4"><b>Creation / Class Methods</b></p>
-<p class="p5"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*from (path, name, toBuffer)</b></p>
-<p class="p7"><b><span class="Apple-tab-span"> </span></b></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>Read a soundfile, analyse the signal, read the file to a buffer</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>path </b>- the path to the soundfile</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>name </b>- a name by which to keep the new wavesets in a global dictionary</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>toBuffer </b>- a boolean whether to load the file to a buffer immediately.</p>
-<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p9"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// a first little example</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Server</span>.default = s = <span class="s3">Server</span>.internal; s.boot;</p>
-<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// make a wavesets from a soundfile</p>
-<p class="p11"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = </span><span class="s3">Wavesets</span><span class="s2">.from(</span>"sounds/a11wlk01.wav"<span class="s2">);<span class="Apple-tab-span"> </span></span></p>
-<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.dump;<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// contains mainly analysis data<span class="Apple-converted-space"> </span></p>
-<p class="p3"><span class="s4"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(200, 1);<span class="Apple-tab-span"> </span></span>// plot a single waveset</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.signal.copyRange(w.xings[600], w.xings[601]).plot;</p>
-<p class="p3"><br></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(600, 1);<span class="Apple-tab-span"> </span><span class="s4">// a single</span></p>
-<p class="p12"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.plot(600, 5);<span class="Apple-tab-span"> </span></span>// a group of five contiguous wavesets</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.buffer;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.buffer.play;</p>
-<p class="p5"><span class="Apple-tab-span"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Wavesets</span>.prepareSynthDefs;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// startWs</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 5, repeats: 2).postln.play;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 2, playRate: 1, repeats: 5).postln.play;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(startWs: 600, length: 2, playRate: 0.5, repeats: 5).postln.play;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w.eventFor(700, 20, 5, 1).play;</p>
-<p class="p5"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span>(</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>fork {<span class="Apple-converted-space"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>666.do { <span class="s3">|i|</span><span class="Apple-converted-space"> </span></p>
-<p class="p10"><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="s3">var</span> ev = w.eventFor(i * 5, 2, 5, exprand(0.5, 1.0));<span class="Apple-converted-space"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.put(\pan, 1.0.rand2).play;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.sustain.wait;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span>)</p>
-<p class="p5"><br></p>
-<p class="p5"><span class="Apple-tab-span"> </span></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*new (name, sig, sampleRate)</b></p>
-<p class="p7"><b><span class="Apple-tab-span"> </span></b></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>Make a Wavesets from a signal directly - not typical usage, but may be needed sometimes.</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>name </b>- a name by which to keep the new wavesets in a global dictionary</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>sig </b>- the signal to be analysed Explanation of sig. Default value is nil. Other information.</p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>sampleRate </b>- Explanation of sampleRate. Default value is nil. Other information.</p>
-<p class="p5"><br></p>
-<p class="p5"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>all</b><span class="Apple-tab-span"> </span>A dictionary where all the wavesets are kept by name.<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>Existing wavesets in .all are not re-analysed.</p>
-<p class="p14"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>Wavesets<span class="s2">.all;</span></p>
-<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*at (key)</b><span class="Apple-tab-span"> </span>Access a Wavesets by its name.<span class="Apple-converted-space"> </span></p>
-<p class="p8"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><b>key </b>- The name to look up</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>g = <span class="s5">Wavesets</span>.at('a11wlk01.wav');</p>
-<p class="p5"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*clear<span class="Apple-tab-span"> </span></b>Clear the global dictionary</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">Wavesets</span>.clear;</p>
-<p class="p5"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*minLength</b><span class="Apple-tab-span"> </span>set the shortest length (in frames) that will still be treated as a waveset. Shorter<span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>wavesets are merged with their neighbors.<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p7"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>*prepareSynthDefs </b><span class="Apple-converted-space"> </span></p>
-<p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>prepare some Synthdefs to be used with wavesets.<span class="Apple-converted-space"> <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></p>
-<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p5"><br></p>
-<p class="p15"><b>Accessing Instance and Class Variables</b></p>
-<p class="p7"><span class="Apple-tab-span"> </span></p>
-<p class="p6"><span class="Apple-tab-span"> </span><b>signal <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the audio signal that was analysed.<span class="Apple-converted-space"> </span></p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>name <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the wavesets name in the global dictionary</p>
-<p class="p1"><span class="Apple-tab-span"> </span><b>buffer</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>a buffer on the server that was created from the same soundfile</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>numFrames <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the number of frames</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>sampleRate <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the sample rate of the signal, default is Server.default.sampleRate</p>
-<p class="p3"><span class="Apple-converted-space"> </span></p>
-<p class="p7"><br></p>
-<p class="p6"><b>The following variables are analysis result lists</b></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>xings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>all integer indices of the zero crossings found</p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>numXings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>total number of zero crossings found</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>lengths<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>lengths of all wavesets</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>amps<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>peak amplitude of every waveset</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>maxima<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>indices of positive maximum value in every waveset</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>minima<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>indices of negative minimum value in every waveset</p>
-<p class="p2"><b><span class="Apple-tab-span"> </span></b></p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>fracXings<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>the calculated fractional zerocrossing points.</p>
-<p class="p1"><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>this allows for more precise pitch information</p>
-<p class="p1"><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>and waveset transitions, resulting in smoother sound.</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>fracLengths<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>fractional lengths - in effect, waveset 'pitch'.</p>
-<p class="p2"><b><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></b></p>
-<p class="p1"><b>These are overall statistics of the entire wavesets<span class="Apple-tab-span"> </span></b></p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>minSet<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>shorted waveset</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>maxSet<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>longest waveset</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>avgLength<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>average length of all wavesets</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>sqrAvgLength<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>weighted average length - so bigger wavesets have a larger impact</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>minAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>softest waveset amplitude</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>maxAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>loudest waveset amplitude</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>avgAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>average amplitude of the entire waveset</p>
-<p class="p1"><b><span class="Apple-tab-span"> </span>sqrAvgAmp<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></b>weighted average of (squared) amplitude of the entire waveset</p>
-<p class="p2"><br></p>
-<p class="p7"><br></p>
-<p class="p6"><b>Some utility instance methods:</b></p>
-<p class="p7"><br></p>
-<p class="p6"><span class="Apple-tab-span"> </span><b>toBuffer(server)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>load the analysed soundfile to the buffer.</p>
-<p class="p7"><span class="Apple-tab-span"> </span></p>
-<p class="p1"><span class="Apple-tab-span"> </span><b>frameFor(startWs, numWs, useFrac)<span class="Apple-tab-span"> </span></b><span class="Apple-tab-span"> </span></p>
-<p class="p1"><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>calculate startFrame, length in frames, and duration<span class="Apple-converted-space"> </span></p>
-<p class="p1"><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>for a waveset or group. useFrac = true means use fractional crossings.<span class="Apple-converted-space"> </span></p>
-<p class="p1"><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>true by default.</p>
-<p class="p2"><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></p>
-<p class="p1"><span class="Apple-tab-span"> </span><b>ampFor(startWs, length)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>maximum amp that occurs in a waveset or group.</p>
-<p class="p2"><span class="Apple-tab-span"> </span></p>
-<p class="p1"><span class="Apple-tab-span"> </span><b>eventFor(startWs, numWs, repeats, playRate, useFrac)</b></p>
-<p class="p1"><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>generate an event for a given combination of start waveset index,</p>
-<p class="p1"><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>number of wavesets, repeats, playback rate, and use of fractional crossings.</p>
-<p class="p2"><br></p>
-<p class="p6"><b><span class="Apple-tab-span"> </span>plot (startWs, length)</b><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>plot a waveset or group for a given waveset index and length.</p>
-<p class="p2"><span class="Apple-tab-span"> </span></p>
-<p class="p2"><span class="Apple-tab-span"> </span></p>
-<p class="p15"><b>Examples</b></p>
-<p class="p3"><br></p>
-<p class="p13">The simplest usage is to ask the waveset to prepare an event for you.</p>
-<p class="p3"><br></p>
-<p class="p11"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>w = </span><span class="s3">Wavesets</span><span class="s2">.from(</span>"sounds/a11wlk01.wav"<span class="s2">);<span class="Apple-tab-span"> </span></span></p>
-<p class="p3"><br></p>
-<p class="p10"><span class="Apple-tab-span"> </span>(</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>fork {<span class="Apple-converted-space"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>666.do { <span class="s3">|i|</span><span class="Apple-converted-space"> </span></p>
-<p class="p10"><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="s3">var</span> ev = w.eventFor((i * 5).postln, 2, 5, exprand(0.5, 1.0));<span class="Apple-converted-space"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.put(\pan, 1.0.rand2).play;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.sustain.wait;</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>}</p>
-<p class="p10"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p10"><span class="Apple-tab-span"> </span>)</p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p4"><span class="Apple-tab-span"> </span>// play a single waveset or waveset group by hand</p>
-<p class="p13">(</p>
-<p class="p13">{ <span class="Apple-tab-span"> </span><span class="s6">var</span> startFr, endFr, dur;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>startFr = w.xings[800];<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>endFr = w.xings[820];</p>
-<p class="p3"><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>dur = endFr - startFr / w.buffer.sampleRate;</p>
-<p class="p13"><span class="Apple-tab-span"> </span>dur.postln;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">BufRd</span>.ar(1, w.buffer, <span class="s6">Line</span>.ar(startFr, endFr, dur, doneAction: 2))<span class="Apple-converted-space"> </span></p>
-<p class="p13">}.play;</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p4"><span class="Apple-tab-span"> </span>loop buffer segments with a Phasor:</p>
-<p class="p13">(</p>
-<p class="p13">x = { <span class="s6">arg</span> start = 0, end = 128, playRate = 1;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">BufRd</span>.ar(1, w.buffer,<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s6">Phasor</span>.ar(0, playRate * <span class="s6">BufRateScale</span>.kr(w.buffer), start, end)</p>
-<p class="p13"><span class="Apple-tab-span"> </span>)</p>
-<p class="p13">}.scope(zoom: 8);</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p13">x.set(<span class="s7">\start</span>, 0, <span class="s7">\end</span>, 1024);<span class="Apple-tab-span"> </span>// just some random length, may buzz</p>
-<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(100), <span class="s7">\end</span>, w.xings.at(101));</p>
-<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(101), <span class="s7">\end</span>, w.xings.at(102));</p>
-<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(100), <span class="s7">\end</span>, w.xings.at(200));</p>
-<p class="p13">x.set(<span class="s7">\start</span>, w.xings.at(780), <span class="s7">\end</span>, w.xings.at(800));</p>
-<p class="p13">x.set(<span class="s7">\playRate</span>, 0.25);</p>
-<p class="p13">x.set(<span class="s7">\playRate</span>, 1);</p>
-<p class="p3"><br></p>
-<p class="p13">x.release;</p>
-<p class="p3"><br></p>
-<p class="p7"><br></p>
-<p class="p7"><br></p>
-<p class="p15"><b>Doing Some Task (optional)</b></p>
-<p class="p16"><br></p>
-<p class="p7"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p15"><b>Examples</b></p>
-<p class="p2"><br></p>
-<p class="p1"><b>To play a waveset (or group) for a precise number of repetitions,<span class="Apple-converted-space"> </span></b></p>
-<p class="p1"><b>one can use a SynthDef with a hard cutoff envelope, as below.</b></p>
-<p class="p1"><b>Note that adding an offset outside the phasor works better;<span class="Apple-converted-space"> </span></b></p>
-<p class="p1"><b>Phasor.ar(0, playRate, start, end) is sometimes off by a few samples.</b></p>
-<p class="p1"><b>This is likely a 32bit float precision problem.</b></p>
-<p class="p3"><br></p>
-<p class="p12"><span class="s2">(<span class="Apple-tab-span"> </span></span>// the simplest synthdef as implented in *prepareSynthDefs:<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="s3">SynthDef</span>(<span class="s8">\wvst0</span>, { <span class="s3">arg</span> out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> phasor = <span class="s3">Phasor</span>.ar(0, <span class="s3">BufRateScale</span>.ir(buf) * playRate, 0, length) + start;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> env = <span class="s3">EnvGen</span>.ar(<span class="s3">Env</span>([amp, amp, 0], [sustain, 0]), doneAction: 2);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">var</span> snd = <span class="s3">BufRd</span>.ar(1, buf, phasor) * env;</p>
-<p class="p3"><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s3">OffsetOut</span>.ar(out, <span class="s3">Pan2</span>.ar(snd, pan));</p>
-<p class="p13">}, <span class="s8">\ir</span>.dup(8)).memStore;</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p13"><span class="s6">Synth</span>(<span class="s9">"wvst0"</span>, [<span class="s7">\bufnum</span>, b, <span class="s7">\start</span>, 0, <span class="s7">\length</span>, 5000, <span class="s7">\sustain</span>, 0.1]);</p>
-<p class="p3"><br></p>
-<p class="p13"><span class="Apple-tab-span"> </span>// do the math by hand to understand it:</p>
-<p class="p13">(</p>
-<p class="p13"><span class="s6">var</span> startWs = 100, length = 6, rep = 10, <span class="s7">playRate</span> = 0.5;</p>
-<p class="p13"><span class="s6">var</span> startframe, endframe, sustain;</p>
-<p class="p3"><br></p>
-<p class="p13">startframe = w.xings[startWs];</p>
-<p class="p13">endframe = w.xings[startWs + length];</p>
-<p class="p13"><span class="s7">sustain</span> = (endframe - startframe) * rep / playRate / w.sampleRate;<span class="Apple-converted-space"> </span></p>
-<p class="p3"><br></p>
-<p class="p17"><span class="s6">Synth</span><span class="s2">(</span>"wvst0"<span class="s2">, [</span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\bufnum</span>, w.buffer,<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\start</span>, startframe,<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\length</span>, endframe - startframe,<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\playRate</span>, playRate,</p>
-<p class="p18"><span class="s2"><span class="Apple-tab-span"> </span></span>\sustain<span class="s2">, </span>sustain<span class="s2">,<span class="Apple-converted-space"> </span></span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s7">\amp</span>, 1</p>
-<p class="p13">]);</p>
-<p class="p13">)</p>
-<p class="p13"><span class="Apple-tab-span"> </span>// the same done with eventFor:</p>
-<p class="p13">w.eventFor(100, 6, repeats: 10, playRate: 0.5).put(\amp, 1).play;</p>
-<p class="p3"><br></p>
-<p class="p13">(</p>
-<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>300.do({ <span class="s6">arg</span> i;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(100 + i, 2, 10, 1);</p>
-<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\pan, [-1, 1].choose, \amp, 0.5]);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>});</p>
-<p class="p13">}).play;</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p20"><span class="s10">x = </span>a11wlk01-44_1.aiff;<span class="Apple-converted-space"> </span></p>
-<p class="p3"><br></p>
-<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// compare fractional and integer xings:</p>
-<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// especially for high frequency signals,<span class="Apple-converted-space"> </span></p>
-<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// fractional does slightly cleaner looping and finer pitch gradations.</p>
-<p class="p21"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// - better test below with ordering wavesets by length -</p>
-<p class="p13">(</p>
-<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>[true, false].do { |usefrac|<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(1250..1500).do { <span class="s6">arg</span> i;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(i, 1, 100, 1, useFrac: usefrac);</p>
-<p class="p3"><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></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([<span class="s11">/*\pan, 0 [-1, 1].choose,*/</span> \amp, 0.5]);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>};</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>1.wait;</p>
-<p class="p13"><span class="Apple-tab-span"> </span>};</p>
-<p class="p13">}).play;</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// some variants waveset timestretch</p>
-<p class="p13">(</p>
-<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// segments of 10 wavesets, step by 1 => 10x longer</p>
-<p class="p13"><span class="Apple-tab-span"> </span>(300, 301 .. 900).do { <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 10, repeats: 1);</p>
-<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>};</p>
-<p class="p13"><span class="Apple-tab-span"> </span>1.wait;<span class="Apple-converted-space"> </span></p>
-<p class="p3"><br></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>// 1 waveset at a time, loop 10 times - much more 'pitch beads'-like</p>
-<p class="p13"><span class="Apple-tab-span"> </span>(300, 301 .. 900).do { <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 1, repeats: 10);</p>
-<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>};</p>
-<p class="p3"><span class="Apple-tab-span"> </span></p>
-<p class="p13">}).play;</p>
-<p class="p13">)</p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p3"><br></p>
-<p class="p21"><span class="s2"><span class="Apple-tab-span"> </span></span>// play them sorted by (integer) waveset length:<span class="Apple-converted-space"> </span></p>
-<p class="p13">w.lengths.plot;<span class="Apple-tab-span"> </span>// lengths are very irregular</p>
-<p class="p13">o = w.lengths.order;</p>
-<p class="p3"><br></p>
-<p class="p13">(</p>
-<p class="p19">Task<span class="s2">({<span class="Apple-converted-space"> </span></span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">var</span> start, end, startFr, endFr, dur, repeats;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="s6">var</span> order;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>order = w.lengths.order;</p>
-<p class="p3"><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>[\false, \true].do { |useFrac|<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>if (useFrac) { "fractional crossings - better pitch resolution" } {</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>"integer waveset borders - pitches quantized to integer sample lengths"</p>
-<p class="p13"><span class="Apple-tab-span"> </span>}.postln;</p>
-<p class="p3"><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>order.do({ <span class="s6">arg</span> start;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>var ev = w.eventFor(start, <span class="s12">numWs</span>: 1, repeats: 5);</p>
-<p class="p3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.putPairs([\amp, 0.5]);</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>ev.play;</p>
-<p class="p13"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>(ev.sustain).wait;<span class="Apple-converted-space"> </span></p>
-<p class="p13"><span class="Apple-tab-span"> </span>});</p>
-<p class="p13">}).play;</p>
-<p class="p13">)</p>
-</body>
-</html>
Deleted: Wavesets/Wavesets.sc
===================================================================
--- Wavesets/Wavesets.sc 2013-12-30 00:06:32 UTC (rev 2682)
+++ Wavesets/Wavesets.sc 2013-12-30 21:43:00 UTC (rev 2683)
@@ -1,245 +0,0 @@
-// Analyses a soundfile's data into wavesets.
-// keep all wavesets objects in global var all.
-// only works for single channels.
-
-/*****
- to do:
- analyse turnaround points better:
- reverse-interpolate where between samples
- the actual turnaround point would be,
- and store them in vars <fracMaxima, <fracMinima.
-*****/
-
-Wavesets {
-
- classvar <>minLength = 10; // reasonable? => 4.4 kHz maxFreq.
- classvar <all, formatDict;
- classvar <>defaultInst = \wvst0;
-
- var <signal, <name, <numFrames, <sampleRate;
- var <xings, <lengths, <fracXings, <fracLengths,
- <amps, <maxima, <minima;
- var <numXings, <minSet, <maxSet, <avgLength, <sqrAvgLength,
- <minAmp, <maxAmp, <avgAmp, <sqrAvgAmp;
- var <>path, <buffer;
-
- *prepareSynthDefs {
- SynthDef(\wvst0, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, sustain = 1, amp=0.2, pan;
- var phasor = Phasor.ar(0, BufRateScale.ir(buf) * playRate, 0, length) + start;
- var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
- var snd = BufRd.ar(1, buf, phasor) * env;
-
- OffsetOut.ar(out, Pan2.ar(snd, pan));
- }, \ir.dup(8)).add;
-
- SynthDef(\wvst1gl, { arg out = 0, buf = 0, start = 0, length = 441, playRate = 1, playRate2 = 1, sustain = 1,
- amp=0.2, pan;
- var playRateEnv = Line.ar(playRate, playRate2, sustain);
- var phasor = Phasor.ar(0, BufRateScale.ir(buf) * playRateEnv, 0, length) + start;
- var env = EnvGen.ar(Env([amp, amp, 0], [sustain, 0]), doneAction: 2);
- var snd = BufRd.ar(1, buf, phasor) * env;
-
- OffsetOut.ar(out, Pan2.ar(snd, pan));
- }, \ir.dup(8)).add;
- }
-
- *new { arg name, sig, sampleRate;
- ^super.new.init(name, sig, sampleRate);
- }
-
- *from { arg path, name, toBuffer = true, server;
- var f, sig, ws;
-
- f = SoundFile.new;
- if (f.openRead(path).not) {
- ("Wavesets.from: File" + path + "not found.").warn;
- ^nil
- };
- if (f.numChannels > 1) {
- ("File" + path + "has" + f.numChannels + "chans."
- "Wavesets only works on mono signals, so please ...").warn;
- // could also take first chan...
- ^nil
- };
- // sampleFormat is not updated correctly in SoundFile.
-
- sig = (formatDict[f.sampleFormat] ? Signal).newClear(f.numFrames);
- name = name ?? { PathName(path).fileName.basename; };
- f.readData(sig);
- f.close;
-
- ws = this.new(name.asSymbol, sig, f.sampleRate);
- ws.path = path;
- if (toBuffer) { ws.toBuffer(server) };
-
- ^ws
- }
-
- toBuffer { |server|
- server = server ? Server.default;
- buffer = buffer ?? { Buffer(server) };
- buffer.allocRead(path, completionMessage: {|buf|["/b_query",buf.bufnum]});
@@ Diff output truncated at 100000 characters. @@
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/