<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>test</title>
<script src="https://unpkg.com/tone@14.7.77/build/Tone.js"></script>
</head>
<body>
<button onclick="play()">再生</button>
</body>
</html>
let g_sampler;
let g_seed;
let g_random;
class Random {
constructor(seed = 19681106) {
this.x = 31415926535;
this.y = 8979323846;
this.z = 2643383279;
this.w = seed;
}
// XorShift
next() {
let t;
t = this.x ^ (this.x << 11);
this.x = this.y; this.y = this.z; this.z = this.w;
return this.w = (this.w ^ (this.w >>> 19)) ^ (t ^ (t >>> 8));
}
// min以上max以下の乱数を生成する
nextInt(min, max) {
const r = Math.abs(this.next());
return min + (r % (max + 1 - min));
}
// nパーセントの確率でtrueを返す
isNtrue(n){
let t = this.nextInt(1,100);
if(t <= n){
return true;
}else{
return false;
}
}
}
//ページを読み込んだ際にしておくべき処理。
const init = () => {
const sampler = new Tone.Sampler({
urls: {
"C4": "C4.mp3",
"D#4": "Ds4.mp3",
"F#4": "Fs4.mp3",
"A4": "A4.mp3",
},
baseUrl: "https://tonejs.github.io/audio/salamander/",
}).toDestination();
Tone.loaded().then(() => {
g_sampler = sampler;
})
}
//パターンを生成する
const createPattern = (chord1, chord2) => {
//最小の長さを32分音符とする。
//1パターン2小節とし、1小節に32部音符が32個入るから×2して64
const maxLength = 64;
let availableLength = maxLength;
let pattern = [];
//まず、全音符、2分音符、4分音符で作成
while(availableLength > 0){
let s_crd;
if(availableLength > availableLength / 2){
s_crd = chord1;
}else{
s_crd = chord2;
}
let t = g_random.nextInt(0,100);
if(t<60 && availableLength >= 8){
pattern.push({note: selectNote(s_crd),pitch: 3, time: "4n", length: 8});
availableLength -= 8;
}else if(t<80 && availableLength >= 16){
pattern.push({note: selectNote(s_crd),pitch: 3, time: "2n", length: 16});
availableLength -= 16;
}else if(t<100 && availableLength >= 32){
pattern.push({note: selectNote(s_crd),pitch: 3, time: "1n", length: 32});
availableLength -= 32;
}
}
pattern.forEach((note)=>{
if(g_random.isNtrue(50)){
}
});
return pattern;
}
//コードの構成音から一つをランダムに選択する
const selectNote = (chord) => {
let t = g_random.nextInt(0,chord.length-1);
return chord[t];
}
const play = () => {
let nowTime = Tone.now();
let offset = nowTime;
// 乱数生成用インスタンス
let dt = new Date();
g_seed = dt.getTime();
console.log(g_seed);
let pattern = [];
g_random = new Random( g_seed );
let chord1 = ["Bb","Db","F"];
let chord2 = ["Bb","Eb","G"];
let t_pattern1 = createPattern(chord1, chord2);
chord1 = ["Ab","Eb","F"];
chord2 = ["Bb","Db","F"];
let t_pattern2 = createPattern(chord1, chord2);
g_random = new Random( g_seed + 5 );
chord1 = ["Bb","Db","F"];
chord2 = ["Bb","Eb","G"];
let t_pattern3 = createPattern(chord1, chord2);
chord1 = ["Ab","Eb","F"];
chord2 = ["Bb","Db","F"];
let t_pattern4 = createPattern(chord1, chord2);
pattern = [...t_pattern1, ...t_pattern2,...t_pattern1, ...t_pattern2,...t_pattern3, ...t_pattern4,...t_pattern1, ...t_pattern2];
console.log(pattern);
for(let i=0; i<pattern.length; ++i){
let n = pattern[i];
let startTime = offset;
g_sampler.triggerAttackRelease(n["note"] + n["pitch"], n["time"], startTime);
offset = startTime + Tone.Time(n["time"]).toSeconds();
}
}
window.onload = init();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.