summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2016-09-19 18:55:47 -0400
committerJules Laplace <jules@okfoc.us>2016-09-19 18:55:47 -0400
commitd142c4b5ba6be49fda5413713096eaa3b911b306 (patch)
tree5970841d76d4e9cdab4a8ad018d1b995ad6d7adb
parent6971d016561a9563a07494d0fc9fdb32250d5b0e (diff)
v1 of library
-rw-r--r--index.html77
-rw-r--r--intonation.js49
2 files changed, 104 insertions, 22 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..358b4a3
--- /dev/null
+++ b/index.html
@@ -0,0 +1,77 @@
+<style>
+.note {
+ color: #339;
+ text-decoration: underline;
+ cursor: pointer;
+}
+* {
+ cursor: default;
+}
+</style>
+<pre>
+<script src="intonation.js"></script>
+<script>
+var delim = "</span> <span>"
+function write(s){ document.write("<span>" + (s || "") + "</span>\n") }
+
+s = new Intonation({
+ intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',
+})
+write("original scale:")
+write( s.range(0, 10).map(function(i){ return i.toFixed(0) }).join(delim) )
+write("")
+
+s = new Intonation({
+ root: 450,
+ intervals: '1/1 9/8 5/4 4/3 3/2 5/3 15/8 2/1',
+})
+write("root @ 450:")
+write( s.range(0, 10).map(function(i){ return i.toFixed(0) }).join(delim) )
+write("")
+
+s = new Intonation({
+ tet: 5,
+})
+write("5-tet")
+write( s.range(0, 6).map(function(i){ return i.toFixed(0) }).join(delim) )
+write("")
+
+s = new Intonation({
+ tet: 12,
+})
+write("12-tet")
+write( s.range(0, 13).map(function(i){ return i.toFixed(0) }).join(delim) )
+write("")
+
+s = new Intonation({
+ tet: 17,
+})
+write("17-tet")
+write( s.range(0, 18).map(function(i){ return i.toFixed(0) }).join(delim) )
+write("")
+
+</script>
+<script src="http://asdf.us/harp/js/vendor/Tone.min.js"></script>
+<script>
+polysynth = new Tone.PolySynth(8, Tone.synth)
+polysynth.set({
+ oscillator: { type: "sine" },
+ envelope:{
+ attack: 0.01,
+ decay: 2.5,
+ sustain: 0.0,
+ release: 0.1,
+ }
+})
+var comp = new Tone.Compressor(-30, 3).toMaster()
+polysynth.connect(comp)
+Array.prototype.slice.apply( document.querySelectorAll("span") ).forEach(function(span){
+ if (! span.innerHTML.match(/[^0-9]/)) {
+ var f = parseInt(span.innerHTML)
+ span.classList.add("note")
+ span.addEventListener("click", function(){
+ polysynth.triggerAttackRelease(f, 1.5)
+ })
+ }
+})
+</script> \ No newline at end of file
diff --git a/intonation.js b/intonation.js
index 4485d81..509addd 100644
--- a/intonation.js
+++ b/intonation.js
@@ -1,18 +1,20 @@
var Intonation = (function(){
var Intonation = function(opt){
- opt = Object.assign({
+ opt = this.opt = Object.assign({
root: 440,
octave: 0,
interval: 2,
tet: 0,
+ intervals: null,
}, opt || {})
this.generate()
}
- Intonation.prototype.generate = function(){
- if (this.opt.tet) {
+ Intonation.prototype.generate = function(opt){
+ opt = Object.assign(this.opt, opt || {})
+ if (opt.tet) {
this.generate_tet()
}
- else {
+ else if (opt.intervals) {
this.generate_intervals()
}
}
@@ -22,23 +24,11 @@ var Intonation = (function(){
if (typeof interval_list == "string") {
interval_list = interval_list.split(" ")
}
- var intervals = .map(function(v){
- if (v.indexOf("/") !== -1) return parseInterval(v) // intervals
- if (v.indexOf("f") !== -1) return parseFloat(v) // pure frequencies
- return parseFloat(v)
- }).filter(function(v){
+ this.intervals = interval_list
+ this.opt.interval = parseInterval.call(this, interval_list.pop() )
+ this.scale = interval_list.map( parseIntervalString.bind(this) ).filter(function(v){
return !! v
})
- if (! intervals.length) return
- this.opt.interval = intervals.pop()
- scale = intervals.map(function(v){
- if (v < 20) {
- return v * root
- }
- else {
- return v
- }
- })
}
Intonation.prototype.generate_tet = function(){
var scale = this.scale = []
@@ -47,11 +37,12 @@ var Intonation = (function(){
var interval = this.opt.interval
var ratio = Math.pow( interval, 1/tet )
var n = root
- scale = [n]
+ scale.push(n)
for (var i = 0; i < tet; i++) {
n *= ratio
scale.push(n)
}
+ this.intervals = null
}
Intonation.prototype.index = function(i, octave){
octave = octave || this.opt.octave
@@ -60,6 +51,13 @@ var Intonation = (function(){
f *= Math.pow(this.opt.interval, pow)
return f
}
+ Intonation.prototype.range = function(min, max){
+ var a = []
+ for (var i = min; i < max; i++) {
+ a.push( this.index(i) )
+ }
+ return a
+ }
Intonation.prototype.set_root = function(f){
this.opt.root = f
this.generate()
@@ -68,11 +66,13 @@ var Intonation = (function(){
if (f == 0) return 0
var scale_f = f
var pow = 0
+ var interval = this.opt.interval
+ var scale = this.scale
while (scale_f < root) {
scale_f *= interval
pow -= 1
}
- while (scale_f > root*interval) {
+ while (scale_f > root * interval) {
scale_f /= interval
pow += 1
}
@@ -87,7 +87,7 @@ var Intonation = (function(){
Intonation.prototype.quantize_index = function(i){
return mod(index-1, this.scale.length)|0
}
- Intonation.prototype.parse_interval = function parseInterval (interval) {
+ var parseInterval = Intonation.prototype.parse_interval = function (s) {
if (typeof s == "number") return s
if (! s.indexOf("/") == -1) return parseInt(s)
var pp = s.split("/")
@@ -98,6 +98,11 @@ var Intonation = (function(){
if (num == den) return 1
return num / den
}
+ var parseIntervalString = Intonation.prototype.parse_interval_string = function(s){
+ if (s.indexOf("/") !== -1) return parseInterval(s) * this.opt.root // intervals
+ if (s.indexOf("f") !== -1) return parseFloat(s) // pure frequencies
+ return parseFloat(s)
+ }
function norm(n,a,b){ return (n-a) / (b-a) }
function mod(n,m){ return n-(m * Math.floor(n/m)) }