-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/cian0/cian0.github.io
- Loading branch information
Showing
2 changed files
with
233 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
{ | ||
"tempo": 80, | ||
"timeSignature": [4, 4], | ||
"tracks": [ | ||
{ | ||
"name": "Eerie Lead", | ||
"instrument": { | ||
"type": "AMSynth", | ||
"options": { | ||
"harmonicity": 3.5, | ||
"oscillator": { "type": "sine" }, | ||
"envelope": { "attack": 0.1, "decay": 0.2, "sustain": 0.8, "release": 1.5 }, | ||
"modulation": { "type": "square" }, | ||
"modulationEnvelope": { "attack": 0.5, "decay": 0, "sustain": 1, "release": 0.5 } | ||
} | ||
}, | ||
"effects": [ | ||
{ "type": "FeedbackDelay", "options": { "delayTime": "16n", "feedback": 0.2 } }, | ||
{ "type": "Freeverb", "options": { "roomSize": 0.8, "dampening": 3000 } } | ||
], | ||
"volume": -15, | ||
"notes": [ | ||
{ "pitch": "D#4", "duration": "2n", "time": 0 }, | ||
{ "pitch": "E4", "duration": "4n", "time": "0:2" }, | ||
{ "pitch": "F4", "duration": "2n", "time": "1:0" }, | ||
{ "pitch": "D4", "duration": "4n", "time": "1:2" }, | ||
{ "pitch": "C#4", "duration": "2n", "time": "2:0" }, | ||
{ "pitch": "C4", "duration": "4n", "time": "2:2" }, | ||
{ "pitch": "B3", "duration": "2n", "time": "3:0" } | ||
] | ||
}, | ||
{ | ||
"name": "Unsettling Bass", | ||
"instrument": { | ||
"type": "FMSynth", | ||
"options": { | ||
"modulationIndex": 10, | ||
"oscillator": { "type": "triangle" }, | ||
"envelope": { "attack": 0.01, "decay": 0.2, "sustain": 0.9, "release": 0.4 }, | ||
"modulation": { "type": "sawtooth" }, | ||
"modulationEnvelope": { "attack": 0.5, "decay": 0, "sustain": 1, "release": 0.5 } | ||
} | ||
}, | ||
"effects": [ | ||
{ "type": "Distortion", "options": { "distortion": 0.3 } }, | ||
{ "type": "BitCrusher", "options": { "bits": 6 } } | ||
], | ||
"volume": -20, | ||
"notes": [ | ||
{ "pitch": "A1", "duration": "1m", "time": 0 }, | ||
{ "pitch": "G#1", "duration": "1m", "time": "1:0" }, | ||
{ "pitch": "G1", "duration": "1m", "time": "2:0" }, | ||
{ "pitch": "F#1", "duration": "1m", "time": "3:0" } | ||
] | ||
}, | ||
{ | ||
"name": "Creepy Atmosphere", | ||
"instrument": { | ||
"type": "NoiseSynth", | ||
"options": { | ||
"noise": { "type": "brown" }, | ||
"envelope": { "attack": 0.5, "decay": 0.2, "sustain": 0.8, "release": 2 } | ||
} | ||
}, | ||
"effects": [ | ||
{ "type": "AutoFilter", "options": { "frequency": "16n", "baseFrequency": 200, "octaves": 4 } }, | ||
{ "type": "PingPongDelay", "options": { "delayTime": "8n", "feedback": 0.3 } } | ||
], | ||
"volume": -30, | ||
"notes": [ | ||
{ "pitch": "C2", "duration": "4m", "time": 0 } | ||
] | ||
}, | ||
{ | ||
"name": "Sudden Stabs", | ||
"instrument": { | ||
"type": "MetalSynth", | ||
"options": { | ||
"frequency": 200, | ||
"envelope": { "attack": 0.001, "decay": 0.1, "release": 0.2 }, | ||
"harmonicity": 5.1, | ||
"modulationIndex": 32, | ||
"resonance": 4000, | ||
"octaves": 1.5 | ||
} | ||
}, | ||
"volume": -15, | ||
"notes": [ | ||
{ "pitch": "C5", "duration": "32n", "time": "0:3.5" }, | ||
{ "pitch": "C5", "duration": "32n", "time": "1:3" }, | ||
{ "pitch": "C5", "duration": "32n", "time": "2:2.5" }, | ||
{ "pitch": "C5", "duration": "32n", "time": "3:1" }, | ||
{ "pitch": "C5", "duration": "32n", "time": "3:3.75" } | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Advanced Tone.js JSON Score Player</title> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.min.js"></script> | ||
<style> | ||
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } | ||
h1 { text-align: center; } | ||
button { font-size: 1.2em; padding: 10px 20px; margin: 10px; } | ||
#controls { text-align: center; margin-bottom: 20px; } | ||
#visualizer { width: 100%; height: 200px; background-color: #f0f0f0; } | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Advanced Tone.js JSON Score Player</h1> | ||
<div id="controls"> | ||
<button id="playBtn">Play</button> | ||
<button id="stopBtn">Stop</button> | ||
<button id="rewindBtn">Rewind</button> | ||
</div> | ||
<canvas id="visualizer"></canvas> | ||
|
||
<script> | ||
let score; | ||
let tracks; | ||
|
||
// Load the JSON file | ||
fetch('score.json') | ||
.then(response => response.json()) | ||
.then(data => { | ||
score = data; | ||
initializePlayer(); | ||
}) | ||
.catch(error => console.error('Error loading the score:', error)); | ||
|
||
function initializePlayer() { | ||
// Create instruments, effects chains, and sequences for each track | ||
tracks = score.tracks.map(track => { | ||
const instrument = new Tone[track.instrument.type](track.instrument.options).toDestination(); | ||
instrument.volume.value = track.volume; | ||
|
||
// Create effects chain | ||
if (track.effects && track.effects.length > 0) { | ||
const effectsChain = track.effects.map(effect => new Tone[effect.type](effect.options)); | ||
instrument.chain(...effectsChain, Tone.Destination); | ||
} | ||
|
||
// Create sequence | ||
const seq = new Tone.Sequence((time, note) => { | ||
instrument.triggerAttackRelease(note.pitch, note.duration, time); | ||
}, track.notes.map(note => ({ | ||
pitch: note.pitch, | ||
duration: note.duration, | ||
time: Tone.Time(note.time).toSeconds() | ||
})), "4n"); | ||
|
||
return { instrument, seq }; | ||
}); | ||
|
||
// Set up transport | ||
Tone.Transport.timeSignature = score.timeSignature; | ||
Tone.Transport.bpm.value = score.tempo; | ||
|
||
// Set up visualizer | ||
const visualizer = document.getElementById('visualizer'); | ||
const canvasContext = visualizer.getContext('2d'); | ||
const analyser = new Tone.Analyser('waveform', 256); | ||
|
||
// Connect the master output to the analyser | ||
Tone.Destination.connect(analyser); | ||
|
||
function drawVisualizer() { | ||
requestAnimationFrame(drawVisualizer); | ||
|
||
const width = visualizer.width; | ||
const height = visualizer.height; | ||
const values = analyser.getValue(); | ||
const bufferLength = analyser.size; | ||
|
||
canvasContext.clearRect(0, 0, width, height); | ||
canvasContext.beginPath(); | ||
|
||
const sliceWidth = width / bufferLength; | ||
let x = 0; | ||
|
||
for (let i = 0; i < bufferLength; i++) { | ||
const v = values[i] / 2 + 0.5; | ||
const y = v * height; | ||
|
||
if (i === 0) { | ||
canvasContext.moveTo(x, y); | ||
} else { | ||
canvasContext.lineTo(x, y); | ||
} | ||
|
||
x += sliceWidth; | ||
} | ||
|
||
canvasContext.lineTo(width, height / 2); | ||
canvasContext.strokeStyle = 'rgb(0, 0, 0)'; | ||
canvasContext.stroke(); | ||
} | ||
|
||
// Set up play, stop, and rewind buttons | ||
document.getElementById('playBtn').addEventListener('click', async () => { | ||
await Tone.start(); | ||
Tone.Transport.start(); | ||
tracks.forEach(track => track.seq.start(0)); | ||
drawVisualizer(); | ||
}); | ||
|
||
document.getElementById('stopBtn').addEventListener('click', () => { | ||
Tone.Transport.stop(); | ||
tracks.forEach(track => track.seq.stop()); | ||
}); | ||
|
||
document.getElementById('rewindBtn').addEventListener('click', () => { | ||
Tone.Transport.position = 0; | ||
}); | ||
|
||
// Set up the canvas size | ||
function resizeCanvas() { | ||
visualizer.width = visualizer.clientWidth * window.devicePixelRatio; | ||
visualizer.height = visualizer.clientHeight * window.devicePixelRatio; | ||
canvasContext.scale(window.devicePixelRatio, window.devicePixelRatio); | ||
} | ||
|
||
// Call resizeCanvas initially and on window resize | ||
resizeCanvas(); | ||
window.addEventListener('resize', resizeCanvas); | ||
} | ||
</script> | ||
</body> | ||
</html> |