Public
Edited
Jan 24, 2023
Insert cell
Insert cell
Insert cell
viewof mute = html`<input type='checkbox' />`
Insert cell
width=3*height
Insert cell
viewof volume = html`<input type='range' min=-24 max=0 value=-20 />`
Insert cell
viewof offset = Inputs.range([-10, 10], {label: "Amount", step: 1})
Insert cell
Insert cell
function note(i){
const min = fundamentalFrequency * 4;
const note = min * Math.pow(Math.pow(2, 1/12), i);
return note
}
Insert cell
viewof zoom = Inputs.range([1, 10], {label: "Amount"})
Insert cell
height=52
Insert cell
function row(i) {
return Math.floor(i/6);
}
Insert cell
cardDims = [24, 24 *.7]
Insert cell
margin = [2, 2];

Insert cell
function cardIndex(position) {
}
Insert cell
function column(i) {
return i % 6;
}
Insert cell
viewof range = Inputs.range([0, 100], {label: "Amount", step: 1})
Insert cell
function cardPos(i) {
return {
x: (column(i)) * (cardDims[0]+margin[0]),
y: row(i) * (cardDims[1]+margin[1]+offset)
}
}
Insert cell
function getNoteCard(x, i) {
const smolGuy = (cardDims[0]-12)/12;
const indicatorOffset = {
x: smolGuy * i+6,
y: 0
}
return htl.svg.fragment`
<rect
width=${cardDims[0]}
height=${cardDims[1]}
fill=${colors[i*12]}
rx=2
x=${cardPos(i).x}
y=${cardPos(i).y}
stroke=${
selectedCard === i ? "pink" : "none"
}
></rect>
<rect
width=${smolGuy+2}
height=${smolGuy+1}
fill="black"
x=${cardPos(i).x + indicatorOffset.x-1}
y=${cardPos(i).y}
></rect>
<rect
width=${smolGuy}
height=${smolGuy}
fill="white"
x=${cardPos(i).x + indicatorOffset.x}
y=${cardPos(i).y}
></rect>


`;
}
Insert cell
# Todo

- Play notes when u click on a card
- integrate card interactions
- 1st click: highlight card
- 2nd click
- if other card, stack highlighted card on top
- if elsewhere, return highlighted card to default position
Insert cell
colors =["#a50026","#a70226","#a90426","#ab0626","#ad0826","#af0926","#b10b26","#b30d26","#b50f26","#b61127","#b81327","#ba1527","#bc1727","#be1927","#c01b27","#c21d28","#c41f28","#c52128","#c72328","#c92529","#cb2729","#cc2929","#ce2b2a","#d02d2a","#d12f2b","#d3312b","#d4332c","#d6352c","#d7382d","#d93a2e","#da3c2e","#dc3e2f","#dd4030","#de4331","#e04532","#e14733","#e24a33","#e34c34","#e44e35","#e55136","#e75337","#e85538","#e95839","#ea5a3a","#eb5d3c","#ec5f3d","#ed613e","#ed643f","#ee6640","#ef6941","#f06b42","#f16e43","#f17044","#f27346","#f37547","#f37848","#f47a49","#f57d4a","#f57f4b","#f6824d","#f6844e","#f7864f","#f78950","#f88b51","#f88e53","#f89054","#f99355","#f99556","#f99858","#fa9a59","#fa9c5a","#fa9f5b","#fba15d","#fba35e","#fba660","#fba861","#fcaa62","#fcad64","#fcaf65","#fcb167","#fcb368","#fcb56a","#fdb86b","#fdba6d","#fdbc6e","#fdbe70","#fdc071","#fdc273","#fdc474","#fdc676","#fdc878","#fdca79","#fecc7b","#fecd7d","#fecf7e","#fed180","#fed382","#fed584","#fed685","#fed887","#feda89","#fedb8b","#fedd8d","#fede8f","#fee090","#fee192","#fee394","#fee496","#fee698","#fee79a","#fee89b","#feea9d","#feeb9f","#feeca0","#feeda2","#feeea3","#fdefa5","#fdf0a6","#fdf1a7","#fdf2a9","#fcf3aa","#fcf4ab","#fcf5ab","#fbf5ac","#fbf6ad","#faf6ad","#faf7ad","#f9f7ae","#f8f7ae","#f7f8ad","#f7f8ad","#f6f8ad","#f5f8ac","#f4f8ab","#f3f8ab","#f1f8aa","#f0f7a9","#eff7a8","#eef7a6","#edf6a5","#ebf6a4","#eaf6a2","#e8f5a1","#e7f59f","#e6f49d","#e4f39c","#e2f39a","#e1f298","#dff297","#def195","#dcf093","#daef92","#d9ef90","#d7ee8e","#d5ed8d","#d3ec8b","#d2ec89","#d0eb88","#ceea86","#cce985","#cae983","#c8e882","#c6e780","#c4e67f","#c2e57e","#c0e47c","#bee47b","#bce37a","#bae279","#b8e178","#b6e076","#b4df75","#b2de74","#b0dd73","#aedc72","#acdb71","#a9da70","#a7d970","#a5d86f","#a3d86e","#a0d76d","#9ed66c","#9cd56c","#99d36b","#97d26b","#95d16a","#92d069","#90cf69","#8ece68","#8bcd68","#89cc67","#86cb67","#84ca66","#81c966","#7fc866","#7cc665","#79c565","#77c464","#74c364","#71c263","#6fc063","#6cbf62","#69be62","#67bd62","#64bc61","#61ba60","#5eb960","#5cb85f","#59b65f","#56b55e","#53b45e","#51b25d","#4eb15c","#4baf5c","#48ae5b","#46ad5a","#43ab5a","#40aa59","#3da858","#3ba757","#38a557","#36a456","#33a255","#31a154","#2e9f54","#2c9d53","#2a9c52","#289a51","#259950","#23974f","#21954f","#1f944e","#1e924d","#1c904c","#1a8f4b","#188d4a","#178b49","#158948","#148747","#128646","#118446","#108245","#0e8044","#0d7e43","#0c7d42","#0b7b41","#0a7940","#08773f","#07753e","#06733d","#05713c","#04703b","#036e3a","#026c39","#016a38","#006837"]
Insert cell
Insert cell
synths = {
//create a synth and connect it to the master output (your speakers)
var synth = new Tone.PolySynth({
maxPolyphony: 12,
voice: Tone.FMSynth
}).chain(Volume, Tone.Master);
synth.set({
oscillator: {
type: "sine"
},
envelope: {
decay: 1,
release: 1
}
});

var synth2 = new Tone.PolySynth({
maxPolyphony: 12,
voice: Tone.FMSynth
}).chain(Volume, Tone.Master);
synth2.set({
oscillator: {
type: "sine"
},
envelope: {
decay: .1,
release: .1
}
});

try {
yield {synth, synth2};
yield invalidation;
} finally {
//synth.dispose();
}
}
Insert cell
Insert cell
fundamentalFrequency = 40.45;
Insert cell
{

synths.synth.triggerAttackRelease(note(selectedCard), .5)
}
Insert cell
Volume = new Tone.Volume(volume)
Insert cell
{ Volume.mute = mute }
Insert cell
Tone = require('tone')
Insert cell
# Appendix

We used the known values of some notes from here as a test case
https://pages.mtu.edu/~suits/notefreq432.html

ended up reading from here to get the math that gave something that sounded right
https://en.wikipedia.org/wiki/Equal_temperament

A prior attempt added 1/12 of the difference between the min frequency & 2*min frequency
Insert cell
[...Array(12).keys()].map(note).map((x,i) => ({val: x, diff: x - known_values[i]}))
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more