First proper working
This commit is contained in:
commit
356444f2de
|
@ -0,0 +1 @@
|
|||
.venv
|
|
@ -0,0 +1,27 @@
|
|||
from flask import Flask, render_template
|
||||
from flask_socketio import SocketIO, emit
|
||||
|
||||
app = Flask(__name__)
|
||||
socketio = SocketIO(app)
|
||||
|
||||
# Normal app routes
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/spe')
|
||||
def spe():
|
||||
return render_template('spe.html')
|
||||
|
||||
# Socket IO stuff
|
||||
@socketio.on('action')
|
||||
def hey():
|
||||
print('action')
|
||||
socketio.emit('all_action')
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(
|
||||
app,
|
||||
host='0.0.0.0',
|
||||
allow_unsafe_werkzeug=True
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
bidict==0.22.1
|
||||
blinker==1.7.0
|
||||
click==8.1.7
|
||||
Flask==3.0.1
|
||||
Flask-SocketIO==5.3.6
|
||||
h11==0.14.0
|
||||
itsdangerous==2.1.2
|
||||
Jinja2==3.1.3
|
||||
MarkupSafe==2.1.4
|
||||
python-engineio==4.8.2
|
||||
python-socketio==5.11.0
|
||||
simple-websocket==1.0.0
|
||||
Werkzeug==3.0.1
|
||||
wsproto==1.2.0
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="19.999996mm" height="22.569992mm" viewBox="0 0 19.999996 22.569992" version="1.1" id="svg5" inkscape:version="1.2 (dc2aedaf03, 2022-05-15)" sodipodi:docname="icons.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview id="namedview7" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" showgrid="false" inkscape:zoom="3.6613294" inkscape:cx="332.80262" inkscape:cy="370.76697" inkscape:window-width="1920" inkscape:window-height="1011" inkscape:window-x="0" inkscape:window-y="0" inkscape:window-maximized="1" inkscape:current-layer="layer1"/>
|
||||
<defs id="defs2"/>
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-50.079351,-70.338316)">
|
||||
<path id="rect1069" style="opacity:1;fill:#121212;fill-opacity:1;stroke-width:1.59792;stroke-linejoin:round;stop-color:#000000" d="m 51.57935,70.475601 17,9.525 c 0.724961,0.406191 1.5,0.669 1.5,1.5 v 0.245422 c 0,0.831 -0.775039,1.093809 -1.5,1.5 l -17,9.525 c -0.724961,0.406192 -1.5,-0.139833 -1.5,-0.970833 V 71.446434 c 0,-0.831 0.775039,-1.377025 1.5,-0.970833 z" sodipodi:nodetypes="sssssssss"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,85 @@
|
|||
import { amsynth } from "./modules/instruments/amsynth.js"
|
||||
import { duosynth } from "./modules/instruments/duosynth.js"
|
||||
import { monosynth } from "./modules/instruments/monosynth.js"
|
||||
import { plucksynth } from "./modules/instruments/plucksynth.js"
|
||||
|
||||
let FILTER_FREQ = 400
|
||||
let REV_RANGE = 12
|
||||
let REV = Math.random() * REV_RANGE
|
||||
|
||||
let NOTES = ["A3", "A2", "C4", "C3", "F3", "F2"]
|
||||
let NOTE = NOTES[ Math.floor(Math.random() * NOTES.length)]
|
||||
|
||||
let SPACING = ["7h", "8h", "9h", "10h"]
|
||||
let SPACE = SPACING[Math.floor(Math.random() * SPACING.length)]
|
||||
|
||||
Tone.Transport.bpm.value = 60;
|
||||
|
||||
let INSTRUMENTS = [amsynth, monosynth, plucksynth]
|
||||
let INSTRUMENT = INSTRUMENTS[Math.floor(Math.random() * INSTRUMENTS.length)]
|
||||
|
||||
const channel = new Tone.Channel();
|
||||
const freeverb = new Tone.Freeverb({ roomSize: 0.98, wet : 0.4 })
|
||||
const filter = new Tone.Filter({type:"lowpass", frequency:800})
|
||||
|
||||
channel.chain(freeverb, filter, Tone.Master)
|
||||
|
||||
for (let inst of INSTRUMENTS) {
|
||||
inst.connect(channel)
|
||||
}
|
||||
|
||||
const play = () => {
|
||||
let r = Math.random()
|
||||
if (r > 0.7) {
|
||||
const a = new Tone.Loop((time) => {
|
||||
INSTRUMENT.triggerAttackRelease(NOTE, "16n")
|
||||
}, SPACE).start(0)
|
||||
} else if (r > 0.3) {
|
||||
const a = new Tone.Loop((time) => {
|
||||
amsynth.triggerAttack(NOTE, "16n")
|
||||
}, SPACE).start(0)
|
||||
|
||||
} else {
|
||||
freeverb.wet.value = 0.0
|
||||
const bassPart = new Tone.Sequence(((time, note) => {
|
||||
plucksynth.triggerAttack(note);
|
||||
}), ["C7", "C8", "C7", "C5", "C#8"], "8n").start(0);
|
||||
|
||||
bassPart.probability = 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
let ac_x = document.getElementById("ac_x")
|
||||
let ac_y = document.getElementById("ac_y")
|
||||
let ac_z = document.getElementById("ac_z")
|
||||
|
||||
if (window.DeviceOrientationEvent) {
|
||||
window.addEventListener(
|
||||
"deviceorientation",
|
||||
(event) => {
|
||||
const rotateDegrees = event.alpha; // alpha: rotation around z-axis
|
||||
const leftToRight = event.gamma; // gamma: left to right
|
||||
const frontToBack = event.beta; // beta: front back motion
|
||||
|
||||
// ac_x.innerHTML = rotateDegrees
|
||||
ac_y.innerHTML = leftToRight
|
||||
// ac_z.innerHTML = frontToBack
|
||||
|
||||
filter.frequency.value = (180 + leftToRight) * 6
|
||||
|
||||
ac_x.innerHTML = filter.frequency.value
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
(function() {
|
||||
document.getElementById('start').addEventListener('click', function() {
|
||||
Tone.context.resume().then(() => {
|
||||
Tone.start()
|
||||
Tone.Transport.start()
|
||||
|
||||
play()
|
||||
})
|
||||
})
|
||||
})()
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,90 @@
|
|||
const socket = io();
|
||||
|
||||
import { NOTE, SPACE } from "./settings.js"
|
||||
|
||||
import { pick } from "./modules/utils.js"
|
||||
|
||||
import { amsynth } from "./modules/instruments/amsynth.js"
|
||||
import { duosynth } from "./modules/instruments/duosynth.js"
|
||||
import { monosynth } from "./modules/instruments/monosynth.js"
|
||||
import { membranesynth } from "./modules/instruments/membranesynth.js"
|
||||
import { plucksynth } from "./modules/instruments/plucksynth.js"
|
||||
|
||||
const instrument = pick([amsynth, duosynth, monosynth, membranesynth, plucksynth])
|
||||
|
||||
import { reverb } from "./modules/effects/reverb.js"
|
||||
|
||||
Tone.Transport.bpm.value = 60;
|
||||
|
||||
// A channel to chain instruments and effects
|
||||
const channel = new Tone.Channel();
|
||||
|
||||
// This is a hack to have something running, which makes the reverb work
|
||||
const pingpong = new Tone.PingPongDelay({delayTime : 2, feedback : 0, wet : 0})
|
||||
|
||||
// Chain the channel and effects to the master out
|
||||
channel.connect(pingpong)
|
||||
pingpong.connect(reverb)
|
||||
reverb.connect(Tone.Master)
|
||||
|
||||
// Chain instrument to the channel
|
||||
instrument.connect(channel)
|
||||
|
||||
const voice = new Tone.Player("/static/recordings/tts.mp3").connect(channel)
|
||||
voice.playbackRate = 0.75
|
||||
voice.loop = true
|
||||
voice.autostart = false
|
||||
|
||||
let playloop = undefined
|
||||
|
||||
const pathway = pick([0, 1, 2])
|
||||
const play = () => {
|
||||
// Determine which of our patterns to play
|
||||
switch(pathway) {
|
||||
case 0:
|
||||
playloop = new Tone.Loop((time) => {
|
||||
instrument.triggerAttackRelease(NOTE, "16n")
|
||||
}, SPACE).start(0)
|
||||
break
|
||||
|
||||
case 1:
|
||||
playloop = new Tone.Loop((time) => {
|
||||
instrument.triggerAttackRelease(NOTE, "8n")
|
||||
}, SPACE).start(0)
|
||||
break
|
||||
|
||||
case 2:
|
||||
playloop = new Tone.Player("/static/recordings/birds.mp3").connect(channel)
|
||||
playloop.loop = true
|
||||
playloop.autostart = true
|
||||
break
|
||||
|
||||
default:
|
||||
// Defaulting
|
||||
}
|
||||
}
|
||||
|
||||
(function() {
|
||||
socket.on('all_action', () => {
|
||||
console.log('ACTION')
|
||||
document.body.style.background = "orange"
|
||||
voice.start()
|
||||
})
|
||||
|
||||
const flowers = ["🌼", "🌸", "💮", "🌺", "🪷", "🏵️"]
|
||||
|
||||
const playbutton = document.getElementById('play')
|
||||
|
||||
playbutton.addEventListener('click', () => {
|
||||
if (playbutton.className == 'paused') {
|
||||
playbutton.className = 'playing';
|
||||
playbutton.innerHTML = pick(flowers);
|
||||
Tone.context.resume().then(() => {
|
||||
Tone.start()
|
||||
Tone.Transport.start("+0.1")
|
||||
}).then(
|
||||
play()
|
||||
)
|
||||
}
|
||||
})
|
||||
})()
|
|
@ -0,0 +1,4 @@
|
|||
export const reverb = new Tone.Reverb({
|
||||
decay : 30,
|
||||
wet : 0.5
|
||||
})
|
|
@ -0,0 +1,2 @@
|
|||
export const amsynth = new Tone.AMSynth({
|
||||
})
|
|
@ -0,0 +1,3 @@
|
|||
export const duosynth = new Tone.DuoSynth({
|
||||
volume : -9
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
export const membranesynth = new Tone.MembraneSynth({
|
||||
volume : -9,
|
||||
pitchDecay : 0.05,
|
||||
octaves : 10,
|
||||
oscillator : {
|
||||
type : "sine"
|
||||
},
|
||||
envelope : {
|
||||
attack : 0.001,
|
||||
decay : 0.4,
|
||||
sustain : 0.01,
|
||||
release : 1.4,
|
||||
attackCurve : "exponential"
|
||||
}
|
||||
})
|
|
@ -0,0 +1,13 @@
|
|||
export const monosynth = new Tone.MonoSynth({
|
||||
volume: -9,
|
||||
envelope: {
|
||||
attack: 0.01,
|
||||
},
|
||||
filterEnvelope: {
|
||||
attack: 0.001,
|
||||
decay: 0.01,
|
||||
sustain: 0.9,
|
||||
baseFrequency: 1000,
|
||||
octaves: 1.6
|
||||
}
|
||||
})
|
|
@ -0,0 +1,5 @@
|
|||
export const plucksynth = new Tone.PluckSynth({
|
||||
volume : -3,
|
||||
attackNoise : 1,
|
||||
resonance : 0.9
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
export const name = "burger"
|
|
@ -0,0 +1,3 @@
|
|||
export const pick = (list) => {
|
||||
return list[Math.floor(Math.random() * list.length)]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export const play = () => {
|
||||
synth.triggerAttackRelease("C4", "16n");
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { pick } from "./modules/utils.js"
|
||||
|
||||
export const NOTES = ["A3", "A2", "C4", "C3", "F3", "F2"]
|
||||
export const NOTE = pick(NOTES)
|
||||
|
||||
export const SPACING = ["7h", "8h", "9h", "10h"]
|
||||
export const SPACE = SPACING[Math.floor(Math.random() * SPACING.length)]
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,84 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<title>🌟 Valde 30 🌟</title>
|
||||
<style>
|
||||
html, body {
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
body div {
|
||||
font-size : 2.88em;
|
||||
color : #aa2211;
|
||||
}
|
||||
|
||||
#play {
|
||||
height: 180px;
|
||||
width: 180px;
|
||||
border-radius: 100%;
|
||||
text-align: center;
|
||||
line-height: 180px;
|
||||
font-size: 100px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.4s, color 0.4s;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.6);
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#play.paused {
|
||||
background-color: #efefef;
|
||||
color: #121212;
|
||||
background-image: url('/static/images/play.svg');
|
||||
background-position: 58% 54%;
|
||||
|
||||
}
|
||||
|
||||
#play.playing {
|
||||
background-color: #121212;
|
||||
color: #efefef;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h2>🌟 Valde 30 🌟</h2>
|
||||
</div>
|
||||
<div>
|
||||
<div id="play" class="paused"></div>
|
||||
</div>
|
||||
<script src="static/js/lib/socket.io.js"></script>
|
||||
<script src="static/js/lib/Tone.js"></script>
|
||||
<script type="module" src="static/js/main.js"></script>
|
||||
<script>
|
||||
// Random colours
|
||||
let hexString = "0123456789abcdef";
|
||||
let randomColor = () => {
|
||||
let hexCode = "#";
|
||||
for( i=0; i<6; i++){
|
||||
hexCode += hexString[Math.floor(Math.random() * hexString.length)];
|
||||
}
|
||||
return hexCode;
|
||||
}
|
||||
|
||||
let generateGrad = () => {
|
||||
let colorOne = randomColor();
|
||||
let colorTwo = randomColor();
|
||||
let angle = Math.floor(Math.random() * 360);
|
||||
document.body.style.background = `linear-gradient(${angle}deg, ${colorOne}, ${colorTwo})`;
|
||||
// outputCode.value = `background: linear-gradient(${angle}deg, ${colorOne}, ${colorTwo});`;
|
||||
}
|
||||
|
||||
generateGrad()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
<title>Admin</title>
|
||||
<style>
|
||||
body {
|
||||
background : #222;
|
||||
color : #aaa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="action">Action</button>
|
||||
<script src="static/js/lib/socket.io.js"></script>
|
||||
<script>
|
||||
const socket = io();
|
||||
document.getElementById('action').addEventListener('click', () => {
|
||||
socket.emit('action')
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue