Update index.html
Browse files- index.html +709 -18
index.html
CHANGED
@@ -1,19 +1,710 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
</html>
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<title>NeuroFractal Music Box</title>
|
6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
+
<style>
|
8 |
+
html, body {
|
9 |
+
margin: 0; padding: 0;
|
10 |
+
background: black;
|
11 |
+
overflow: hidden;
|
12 |
+
font-family: monospace;
|
13 |
+
}
|
14 |
+
#hydra-canvas {
|
15 |
+
position: absolute;
|
16 |
+
top: 0; left: 0;
|
17 |
+
width: 100vw;
|
18 |
+
height: 100vh;
|
19 |
+
image-rendering: pixelated;
|
20 |
+
z-index: 0;
|
21 |
+
}
|
22 |
+
#terminal {
|
23 |
+
position: absolute;
|
24 |
+
bottom: 0;
|
25 |
+
width: 100%;
|
26 |
+
height: 200px;
|
27 |
+
background: rgba(0,0,0,0.75);
|
28 |
+
color: white;
|
29 |
+
border: none;
|
30 |
+
padding: 10px;
|
31 |
+
resize: none;
|
32 |
+
font-size: 14px;
|
33 |
+
line-height: 1.4;
|
34 |
+
z-index: 2;
|
35 |
+
}
|
36 |
+
#instructions {
|
37 |
+
position: absolute;
|
38 |
+
bottom: 10px;
|
39 |
+
left: 10px;
|
40 |
+
width: 250px;
|
41 |
+
max-height: 200px;
|
42 |
+
background: rgba(0,0,0,0.75);
|
43 |
+
color: white;
|
44 |
+
padding: 10px;
|
45 |
+
font-size: 12px;
|
46 |
+
line-height: 1.4;
|
47 |
+
z-index: 2;
|
48 |
+
overflow-y: auto;
|
49 |
+
display: none;
|
50 |
+
}
|
51 |
+
#btns {
|
52 |
+
position: absolute;
|
53 |
+
top: 10px;
|
54 |
+
left: 10px;
|
55 |
+
z-index: 3;
|
56 |
+
}
|
57 |
+
button {
|
58 |
+
background: #222;
|
59 |
+
color: white;
|
60 |
+
border: 1px solid #555;
|
61 |
+
padding: 6px 10px;
|
62 |
+
margin-right: 5px;
|
63 |
+
margin-bottom: 5px;
|
64 |
+
font-size: 12px;
|
65 |
+
cursor: pointer;
|
66 |
+
transition: background 0.2s, transform 0.2s;
|
67 |
+
}
|
68 |
+
button.active {
|
69 |
+
background: #155;
|
70 |
+
border-color: #2aa;
|
71 |
+
}
|
72 |
+
button.pulsing {
|
73 |
+
animation: pulse 1s infinite alternate;
|
74 |
+
}
|
75 |
+
@keyframes pulse {
|
76 |
+
0% { transform: scale(1); }
|
77 |
+
100% { transform: scale(1.1); }
|
78 |
+
}
|
79 |
+
</style>
|
80 |
+
</head>
|
81 |
+
<body>
|
82 |
+
<canvas id="hydra-canvas"></canvas>
|
83 |
+
|
84 |
+
<div id="btns">
|
85 |
+
<button id="btn-terminal" onclick="terminal.style.display = terminal.style.display === 'none' ? 'block' : 'none'">🧠 Открыть терминал</button>
|
86 |
+
<button id="btn-code" onclick="eval(terminal.value)">▶️ Запуск кода</button>
|
87 |
+
<button id="btn-dream" onclick="insertDream()">💤 Нейросон</button>
|
88 |
+
<button id="btn-osc1" onclick="insertOscPreset1()">🌊 OSC Пресет 1</button>
|
89 |
+
<button id="btn-osc2" onclick="insertOscPreset2()">🔥 OSC Пресет 2</button>
|
90 |
+
<button id="btn-osc3" onclick="insertOscPreset3()">⚡️ OSC Пресет 3</button>
|
91 |
+
<button id="btn-audio" onclick="toggleAudio()">🔊 Вкл/Выкл звук</button>
|
92 |
+
<button id="btn-voice" onclick="toggleVoiceDetection()">🎤 Вкл/Выкл голос</button>
|
93 |
+
<button id="btn-formant" onclick="toggleFormantSynthesis()">🗣️ Вкл/Выкл речь</button>
|
94 |
+
<button id="btn-speech" onclick="toggleSpeechSynthesis()">🗣️ Вкл/Выкл синтез речи</button>
|
95 |
+
<button id="btn-randomize" onclick="randomizeParameters()">🎲 Рандомизировать</button>
|
96 |
+
<button id="btn-instructions" onclick="instructions.style.display = instructions.style.display === 'none' ? 'block' : 'none'">📜 Инструкции</button>
|
97 |
+
</div>
|
98 |
+
|
99 |
+
<textarea id="terminal" spellcheck="false" style="display:none"></textarea>
|
100 |
+
<div id="instructions" style="display:none">
|
101 |
+
<strong>Инструкции:</strong><br>
|
102 |
+
1. Используйте <strong>наушники</strong> для бинауральных ритмов.<br>
|
103 |
+
2. Разрешите доступ к <strong>микрофону</strong> и <strong>камере</strong>.<br>
|
104 |
+
3. <strong>Говорите/пойте</strong> (800-3000 Гц) для активации голоса и речи.<br>
|
105 |
+
4. <strong>Двигайтесь перед камерой</strong> для визуальной реакции.<br>
|
106 |
+
5. Кнопки:<br>
|
107 |
+
- 🧠: Показать/скрыть терминал для кода.<br>
|
108 |
+
- ▶️: Запустить код из терминала.<br>
|
109 |
+
- 💤: Основная визуализация (глобус, ЭЭГ, радар).<br>
|
110 |
+
- 🌊/🔥/⚡️: OSC-пресеты (разные ритмы).<br>
|
111 |
+
- 🔊: Вкл/выкл звук (бинауральные ритмы, природа).<br>
|
112 |
+
- 🎤: Вкл/выкл голосовое управление.<br>
|
113 |
+
- 🗣️ (речь): Вкл/выкл формантный синтез.<br>
|
114 |
+
- 🗣️ (синтез): Вкл/выкл случайные слова.<br>
|
115 |
+
- 🎲: Рандомизация параметров.<br>
|
116 |
+
- 📜: Показать/скрыть инструкции.<br>
|
117 |
+
6. <strong>Радар</strong> (вверху справа) показывает окружение.<br>
|
118 |
+
7. Кнопки <strong>пульсируют</strong>, если есть голос/камера.<br>
|
119 |
+
8. Существо говорит случайные слова, пауза при активности.<br>
|
120 |
+
Проблемы? Проверьте консоль (F12) и разрешения.
|
121 |
+
</div>
|
122 |
+
|
123 |
+
<script src="https://unpkg.com/hydra-synth"></script>
|
124 |
+
<script>
|
125 |
+
const canvas = document.getElementById("hydra-canvas");
|
126 |
+
canvas.width = window.innerWidth * window.devicePixelRatio;
|
127 |
+
canvas.height = window.innerHeight * window.devicePixelRatio;
|
128 |
+
const hydra = new Hydra({
|
129 |
+
detectAudio: true,
|
130 |
+
canvas: canvas,
|
131 |
+
width: canvas.width,
|
132 |
+
height: canvas.height,
|
133 |
+
pixelRatio: window.devicePixelRatio
|
134 |
+
});
|
135 |
+
|
136 |
+
// Web Audio API: Binaural beats, formant synthesis, nature sounds, voice detection
|
137 |
+
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
138 |
+
let oscillators = [];
|
139 |
+
let gainNodes = [];
|
140 |
+
let analyser = null;
|
141 |
+
let voiceActive = false;
|
142 |
+
let formantSynthesisActive = false;
|
143 |
+
let speechSynthesisActive = false;
|
144 |
+
let audioPlaying = false;
|
145 |
+
let formantIntensity = 0;
|
146 |
+
let camIntensity = 0;
|
147 |
+
let isPausedForThought = false;
|
148 |
+
|
149 |
+
// Randomizer state
|
150 |
+
let randomParams = {
|
151 |
+
deltaFreq: 200,
|
152 |
+
thetaFreq: 220,
|
153 |
+
alphaFreq: 240,
|
154 |
+
betaFreq: 260,
|
155 |
+
formant1Freq: 700,
|
156 |
+
formant2Freq: 1200,
|
157 |
+
oscFreqGlobe: 5,
|
158 |
+
oscFreqLasers: 8,
|
159 |
+
oscFreqEEG1: 4,
|
160 |
+
oscFreqEEG2: 1,
|
161 |
+
kaleidGlobe: 2,
|
162 |
+
kaleidLasers: 2,
|
163 |
+
kaleidPreset1: 2,
|
164 |
+
kaleidPreset2: 2,
|
165 |
+
kaleidPreset3: 2,
|
166 |
+
colorR: 0.2,
|
167 |
+
colorG: 0.5,
|
168 |
+
colorB: 1
|
169 |
+
};
|
170 |
+
|
171 |
+
function createBinauralAndSounds() {
|
172 |
+
// Binaural Beats
|
173 |
+
const deltaLeft = audioCtx.createOscillator();
|
174 |
+
deltaLeft.type = 'sine';
|
175 |
+
deltaLeft.frequency.setValueAtTime(randomParams.deltaFreq, audioCtx.currentTime);
|
176 |
+
const deltaLeftGain = audioCtx.createGain();
|
177 |
+
deltaLeftGain.gain.setValueAtTime(0.04, audioCtx.currentTime);
|
178 |
+
const deltaLeftPan = audioCtx.createStereoPanner();
|
179 |
+
deltaLeftPan.pan.setValueAtTime(-1, audioCtx.currentTime);
|
180 |
+
deltaLeft.connect(deltaLeftGain).connect(deltaLeftPan).connect(audioCtx.destination);
|
181 |
+
|
182 |
+
const deltaRight = audioCtx.createOscillator();
|
183 |
+
deltaRight.type = 'sine';
|
184 |
+
deltaRight.frequency.setValueAtTime(randomParams.deltaFreq + 2, audioCtx.currentTime);
|
185 |
+
const deltaRightGain = audioCtx.createGain();
|
186 |
+
deltaRightGain.gain.setValueAtTime(0.04, audioCtx.currentTime);
|
187 |
+
const deltaRightPan = audioCtx.createStereoPanner();
|
188 |
+
deltaRightPan.pan.setValueAtTime(1, audioCtx.currentTime);
|
189 |
+
deltaRight.connect(deltaRightGain).connect(deltaRightPan).connect(audioCtx.destination);
|
190 |
+
|
191 |
+
const thetaLeft = audioCtx.createOscillator();
|
192 |
+
thetaLeft.type = 'sine';
|
193 |
+
thetaLeft.frequency.setValueAtTime(randomParams.thetaFreq, audioCtx.currentTime);
|
194 |
+
const thetaLeftGain = audioCtx.createGain();
|
195 |
+
thetaLeftGain.gain.setValueAtTime(0.03, audioCtx.currentTime);
|
196 |
+
const thetaLeftPan = audioCtx.createStereoPanner();
|
197 |
+
thetaLeftPan.pan.setValueAtTime(-1, audioCtx.currentTime);
|
198 |
+
thetaLeft.connect(thetaLeftGain).connect(thetaLeftPan).connect(audioCtx.destination);
|
199 |
+
|
200 |
+
const thetaRight = audioCtx.createOscillator();
|
201 |
+
thetaRight.type = 'sine';
|
202 |
+
thetaRight.frequency.setValueAtTime(randomParams.thetaFreq + 6, audioCtx.currentTime);
|
203 |
+
const thetaRightGain = audioCtx.createGain();
|
204 |
+
thetaRightGain.gain.setValueAtTime(0.03, audioCtx.currentTime);
|
205 |
+
const thetaRightPan = audioCtx.createStereoPanner();
|
206 |
+
thetaRightPan.pan.setValueAtTime(1, audioCtx.currentTime);
|
207 |
+
thetaRight.connect(thetaRightGain).connect(thetaRightPan).connect(audioCtx.destination);
|
208 |
+
|
209 |
+
const alphaLeft = audioCtx.createOscillator();
|
210 |
+
alphaLeft.type = 'sine';
|
211 |
+
alphaLeft.frequency.setValueAtTime(randomParams.alphaFreq, audioCtx.currentTime);
|
212 |
+
const alphaLeftGain = audioCtx.createGain();
|
213 |
+
alphaLeftGain.gain.setValueAtTime(0.02, audioCtx.currentTime);
|
214 |
+
const alphaLeftPan = audioCtx.createStereoPanner();
|
215 |
+
alphaLeftPan.pan.setValueAtTime(-1, audioCtx.currentTime);
|
216 |
+
alphaLeft.connect(alphaLeftGain).connect(alphaLeftPan).connect(audioCtx.destination);
|
217 |
+
|
218 |
+
const alphaRight = audioCtx.createOscillator();
|
219 |
+
alphaRight.type = 'sine';
|
220 |
+
alphaRight.frequency.setValueAtTime(randomParams.alphaFreq + 10, audioCtx.currentTime);
|
221 |
+
const alphaRightGain = audioCtx.createGain();
|
222 |
+
alphaRightGain.gain.setValueAtTime(0.02, audioCtx.currentTime);
|
223 |
+
const alphaRightPan = audioCtx.createStereoPanner();
|
224 |
+
alphaRightPan.pan.setValueAtTime(1, audioCtx.currentTime);
|
225 |
+
alphaRight.connect(alphaRightGain).connect(alphaRightPan).connect(audioCtx.destination);
|
226 |
+
|
227 |
+
const betaLeft = audioCtx.createOscillator();
|
228 |
+
betaLeft.type = 'sine';
|
229 |
+
betaLeft.frequency.setValueAtTime(randomParams.betaFreq, audioCtx.currentTime);
|
230 |
+
const betaLeftGain = audioCtx.createGain();
|
231 |
+
betaLeftGain.gain.setValueAtTime(0.015, audioCtx.currentTime);
|
232 |
+
const betaLeftPan = audioCtx.createStereoPanner();
|
233 |
+
betaLeftPan.pan.setValueAtTime(-1, audioCtx.currentTime);
|
234 |
+
betaLeft.connect(betaLeftGain).connect(betaLeftPan).connect(audioCtx.destination);
|
235 |
+
|
236 |
+
const betaRight = audioCtx.createOscillator();
|
237 |
+
betaRight.type = 'sine';
|
238 |
+
betaRight.frequency.setValueAtTime(randomParams.betaFreq + 20, audioCtx.currentTime);
|
239 |
+
const betaRightGain = audioCtx.createGain();
|
240 |
+
betaRightGain.gain.setValueAtTime(0.015, audioCtx.currentTime);
|
241 |
+
const betaRightPan = audioCtx.createStereoPanner();
|
242 |
+
betaRightPan.pan.setValueAtTime(1, audioCtx.currentTime);
|
243 |
+
betaRight.connect(betaRightGain).connect(betaRightPan).connect(audioCtx.destination);
|
244 |
+
|
245 |
+
// Formant Synthesis: Vowel-like sounds (/a/)
|
246 |
+
const formant1 = audioCtx.createOscillator();
|
247 |
+
formant1.type = 'sine';
|
248 |
+
formant1.frequency.setValueAtTime(randomParams.formant1Freq, audioCtx.currentTime);
|
249 |
+
const formant1Gain = audioCtx.createGain();
|
250 |
+
formant1Gain.gain.setValueAtTime(0, audioCtx.currentTime);
|
251 |
+
const formant1Filter = audioCtx.createBiquadFilter();
|
252 |
+
formant1Filter.type = 'bandpass';
|
253 |
+
formant1Filter.frequency.setValueAtTime(randomParams.formant1Freq, audioCtx.currentTime);
|
254 |
+
formant1Filter.Q.setValueAtTime(10, audioCtx.currentTime);
|
255 |
+
formant1.connect(formant1Gain).connect(formant1Filter).connect(audioCtx.destination);
|
256 |
+
|
257 |
+
const formant2 = audioCtx.createOscillator();
|
258 |
+
formant2.type = 'sine';
|
259 |
+
formant2.frequency.setValueAtTime(randomParams.formant2Freq, audioCtx.currentTime);
|
260 |
+
const formant2Gain = audioCtx.createGain();
|
261 |
+
formant2Gain.gain.setValueAtTime(0, audioCtx.currentTime);
|
262 |
+
const formant2Filter = audioCtx.createBiquadFilter();
|
263 |
+
formant2Filter.type = 'bandpass';
|
264 |
+
formant2Filter.frequency.setValueAtTime(randomParams.formant2Freq, audioCtx.currentTime);
|
265 |
+
formant2Filter.Q.setValueAtTime(10, audioCtx.currentTime);
|
266 |
+
formant2.connect(formant2Gain).connect(formant2Filter).connect(audioCtx.destination);
|
267 |
+
|
268 |
+
// Subtle Nature Sounds
|
269 |
+
const waterNoise = audioCtx.createBufferSource();
|
270 |
+
const bufferSize = audioCtx.sampleRate * 2;
|
271 |
+
const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
|
272 |
+
const data = buffer.getChannelData(0);
|
273 |
+
for (let i = 0; i < bufferSize; i++) {
|
274 |
+
data[i] = Math.random() * 2 - 1;
|
275 |
+
}
|
276 |
+
waterNoise.buffer = buffer;
|
277 |
+
waterNoise.loop = true;
|
278 |
+
const waterFilter = audioCtx.createBiquadFilter();
|
279 |
+
waterFilter.type = 'lowpass';
|
280 |
+
waterFilter.frequency.setValueAtTime(400, audioCtx.currentTime);
|
281 |
+
const waterGain = audioCtx.createGain();
|
282 |
+
waterGain.gain.setValueAtTime(0.01, audioCtx.currentTime);
|
283 |
+
waterNoise.connect(waterFilter).connect(waterGain).connect(audioCtx.destination);
|
284 |
+
|
285 |
+
const birdOsc = audioCtx.createOscillator();
|
286 |
+
birdOsc.type = 'sine';
|
287 |
+
birdOsc.frequency.setValueAtTime(1000, audioCtx.currentTime);
|
288 |
+
const birdGain = audioCtx.createGain();
|
289 |
+
birdGain.gain.setValueAtTime(0, audioCtx.currentTime);
|
290 |
+
birdOsc.connect(birdGain).connect(audioCtx.destination);
|
291 |
+
setInterval(() => {
|
292 |
+
const freq = 800 + Math.random() * 400;
|
293 |
+
birdOsc.frequency.setValueAtTime(freq, audioCtx.currentTime);
|
294 |
+
birdGain.gain.setValueAtTime(0.01, audioCtx.currentTime);
|
295 |
+
birdGain.gain.setValueAtTime(0, audioCtx.currentTime + 0.1);
|
296 |
+
}, 3000);
|
297 |
+
|
298 |
+
const forestNoise = audioCtx.createBufferSource();
|
299 |
+
const forestBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
|
300 |
+
const forestData = forestBuffer.getChannelData(0);
|
301 |
+
for (let i = 0; i < bufferSize; i++) {
|
302 |
+
forestData[i] = Math.random() * 0.3 - 0.15;
|
303 |
+
}
|
304 |
+
forestNoise.buffer = forestBuffer;
|
305 |
+
forestNoise.loop = true;
|
306 |
+
const forestFilter = audioCtx.createBiquadFilter();
|
307 |
+
forestFilter.type = 'lowpass';
|
308 |
+
forestFilter.frequency.setValueAtTime(150, audioCtx.currentTime);
|
309 |
+
const forestGain = audioCtx.createGain();
|
310 |
+
forestGain.gain.setValueAtTime(0.01, audioCtx.currentTime);
|
311 |
+
forestNoise.connect(forestFilter).connect(forestGain).connect(audioCtx.destination);
|
312 |
+
|
313 |
+
oscillators = [deltaLeft, deltaRight, thetaLeft, thetaRight, alphaLeft, alphaRight, betaLeft, betaRight, formant1, formant2, waterNoise, birdOsc, forestNoise];
|
314 |
+
gainNodes = [deltaLeftGain, deltaRightGain, thetaLeftGain, thetaRightGain, alphaLeftGain, alphaRightGain, betaLeftGain, betaRightGain, formant1Gain, formant2Gain, waterGain, birdGain, forestGain];
|
315 |
+
}
|
316 |
+
|
317 |
+
// Formant-based voice detection (mid-range focus)
|
318 |
+
function setupVoiceDetection(stream) {
|
319 |
+
analyser = audioCtx.createAnalyser();
|
320 |
+
analyser.fftSize = 256;
|
321 |
+
const source = audioCtx.createMediaStreamSource(stream);
|
322 |
+
source.connect(analyser);
|
323 |
+
const dataArray = new Float32Array(analyser.frequencyBinCount);
|
324 |
+
const sampleRate = audioCtx.sampleRate;
|
325 |
+
const binWidth = sampleRate / analyser.fftSize;
|
326 |
+
|
327 |
+
function detectFormants() {
|
328 |
+
analyser.getFloatFrequencyData(dataArray);
|
329 |
+
let midRangeIntensity = 0;
|
330 |
+
for (let i = 0; i < dataArray.length; i++) {
|
331 |
+
const freq = i * binWidth;
|
332 |
+
if (freq >= 800 && freq <= 3000) {
|
333 |
+
midRangeIntensity = Math.max(midRangeIntensity, dataArray[i] > -100 ? dataArray[i] + 100 : 0);
|
334 |
+
}
|
335 |
+
}
|
336 |
+
formantIntensity = Math.min(midRangeIntensity / 80, 1);
|
337 |
+
if (voiceActive && audioPlaying) {
|
338 |
+
gainNodes[0].gain.setValueAtTime(0.04 + formantIntensity * 0.04, audioCtx.currentTime);
|
339 |
+
gainNodes[2].gain.setValueAtTime(0.03 + formantIntensity * 0.03, audioCtx.currentTime);
|
340 |
+
gainNodes[4].gain.setValueAtTime(0.02 + formantIntensity * 0.02, audioCtx.currentTime);
|
341 |
+
gainNodes[6].gain.setValueAtTime(0.015 + formantIntensity * 0.015, audioCtx.currentTime);
|
342 |
+
gainNodes[8].gain.setValueAtTime(formantSynthesisActive ? formantIntensity * 0.05 : 0, audioCtx.currentTime);
|
343 |
+
gainNodes[9].gain.setValueAtTime(formantSynthesisActive ? formantIntensity * 0.05 : 0, audioCtx.currentTime);
|
344 |
+
gainNodes[10].gain.setValueAtTime(0.01 + formantIntensity * 0.01, audioCtx.currentTime);
|
345 |
+
gainNodes[11].gain.setValueAtTime(0.01 + formantIntensity * 0.01, audioCtx.currentTime);
|
346 |
+
gainNodes[12].gain.setValueAtTime(0.01 + formantIntensity * 0.01, audioCtx.currentTime);
|
347 |
+
}
|
348 |
+
updateButtonStates();
|
349 |
+
requestAnimationFrame(detectFormants);
|
350 |
+
}
|
351 |
+
detectFormants();
|
352 |
+
}
|
353 |
+
|
354 |
+
// Camera intensity detection
|
355 |
+
function setupCamera() {
|
356 |
+
try {
|
357 |
+
s0.initCam();
|
358 |
+
setInterval(() => {
|
359 |
+
const ctx = canvas.getContext('2d');
|
360 |
+
const frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
361 |
+
let brightness = 0;
|
362 |
+
for (let i = 0; i < frame.data.length; i += 4) {
|
363 |
+
brightness += (frame.data[i] + frame.data[i + 1] + frame.data[i + 2]) / 3;
|
364 |
+
}
|
365 |
+
camIntensity = Math.min(brightness / (frame.data.length / 4) / 255, 1);
|
366 |
+
updateButtonStates();
|
367 |
+
}, 100);
|
368 |
+
} catch (e) {
|
369 |
+
console.error("Camera initialization failed:", e);
|
370 |
+
camIntensity = 0;
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
// T9-like nonsense word generator tied to OSC EEG rhythms
|
375 |
+
function generateNonsenseWord() {
|
376 |
+
const vowels = ['a', 'e', 'i', 'o', 'u'];
|
377 |
+
const consonants = ['b', 'd', 'g', 'k', 'm', 'n', 'p', 's', 't', 'w', 'z'];
|
378 |
+
let word = '';
|
379 |
+
const length = Math.floor(2 + Math.random() * 3);
|
380 |
+
for (let i = 0; i < length; i++) {
|
381 |
+
word += consonants[Math.floor(Math.random() * consonants.length)];
|
382 |
+
word += vowels[Math.floor(Math.random() * vowels.length)];
|
383 |
+
}
|
384 |
+
const oscInfluence = randomParams.betaFreq / 270;
|
385 |
+
if (Math.random() < oscInfluence) word += '-' + vowels[Math.floor(Math.random() * vowels.length)];
|
386 |
+
return word;
|
387 |
+
}
|
388 |
+
|
389 |
+
// Web Speech API with pause and thought
|
390 |
+
let speechInterval;
|
391 |
+
function speakNonsense() {
|
392 |
+
if (!speechSynthesisActive || isPausedForThought) return;
|
393 |
+
if (formantIntensity > 0.5 || camIntensity > 0.5) {
|
394 |
+
isPausedForThought = true;
|
395 |
+
speechSynthesis.cancel();
|
396 |
+
const word = generateNonsenseWord();
|
397 |
+
const utterance = new SpeechSynthesisUtterance(`I sense ${word}`);
|
398 |
+
utterance.pitch = 0.8 + formantIntensity * 0.4;
|
399 |
+
utterance.volume = 0.5 + formantIntensity * 0.3;
|
400 |
+
utterance.rate = 0.8 + (randomParams.betaFreq - 250) / 20 * 0.4;
|
401 |
+
utterance.onend = () => {
|
402 |
+
setTimeout(() => {
|
403 |
+
isPausedForThought = false;
|
404 |
+
}, 3000);
|
405 |
+
};
|
406 |
+
speechSynthesis.speak(utterance);
|
407 |
+
} else {
|
408 |
+
const utterance = new SpeechSynthesisUtterance(generateNonsenseWord());
|
409 |
+
utterance.pitch = 0.8 + formantIntensity * 0.4;
|
410 |
+
utterance.volume = 0.5 + formantIntensity * 0.3;
|
411 |
+
utterance.rate = 0.8 + (randomParams.betaFreq - 250) / 20 * 0.4;
|
412 |
+
speechSynthesis.speak(utterance);
|
413 |
+
}
|
414 |
+
}
|
415 |
+
|
416 |
+
function toggleSpeechSynthesis() {
|
417 |
+
speechSynthesisActive = !speechSynthesisActive;
|
418 |
+
if (speechSynthesisActive) {
|
419 |
+
speakNonsense();
|
420 |
+
speechInterval = setInterval(speakNonsense, 2000);
|
421 |
+
} else {
|
422 |
+
clearInterval(speechInterval);
|
423 |
+
speechSynthesis.cancel();
|
424 |
+
isPausedForThought = false;
|
425 |
+
}
|
426 |
+
updateButtonStates();
|
427 |
+
}
|
428 |
+
|
429 |
+
// Update button states
|
430 |
+
function updateButtonStates() {
|
431 |
+
document.getElementById('btn-audio').className = audioPlaying ? 'active pulsing' : '';
|
432 |
+
document.getElementById('btn-voice').className = voiceActive ? 'active pulsing' : '';
|
433 |
+
document.getElementById('btn-formant').className = formantSynthesisActive ? 'active pulsing' : '';
|
434 |
+
document.getElementById('btn-speech').className = speechSynthesisActive ? 'active pulsing' : '';
|
435 |
+
document.getElementById('btn-randomize').className = formantIntensity > 0.3 || camIntensity > 0.3 ? 'active pulsing' : '';
|
436 |
+
document.getElementById('btn-dream').className = formantIntensity > 0.3 || camIntensity > 0.3 ? 'active pulsing' : '';
|
437 |
+
document.getElementById('btn-osc1').className = formantIntensity > 0.3 || camIntensity > 0.3 ? 'active pulsing' : '';
|
438 |
+
document.getElementById('btn-osc2').className = formantIntensity > 0.3 || camIntensity > 0.3 ? 'active pulsing' : '';
|
439 |
+
document.getElementById('btn-osc3').className = formantIntensity > 0.3 || camIntensity > 0.3 ? 'active pulsing' : '';
|
440 |
+
document.getElementById('btn-instructions').className = document.getElementById('instructions').style.display === 'block' ? 'active' : '';
|
441 |
+
}
|
442 |
+
|
443 |
+
function randomizeParameters() {
|
444 |
+
randomParams = {
|
445 |
+
deltaFreq: 190 + Math.random() * 20,
|
446 |
+
thetaFreq: 210 + Math.random() * 20,
|
447 |
+
alphaFreq: 230 + Math.random() * 20,
|
448 |
+
betaFreq: 250 + Math.random() * 20,
|
449 |
+
formant1Freq: 600 + Math.random() * 200,
|
450 |
+
formant2Freq: 1100 + Math.random() * 200,
|
451 |
+
oscFreqGlobe: 4 + Math.random() * 3,
|
452 |
+
oscFreqLasers: 7 + Math.random() * 3,
|
453 |
+
oscFreqEEG1: 3 + Math.random() * 2,
|
454 |
+
oscFreqEEG2: 0.5 + Math.random() * 1,
|
455 |
+
kaleidGlobe: Math.floor(2 + Math.random() * 2),
|
456 |
+
kaleidLasers: Math.floor(2 + Math.random() * 2),
|
457 |
+
kaleidPreset1: Math.floor(2 + Math.random() * 2),
|
458 |
+
kaleidPreset2: Math.floor(2 + Math.random() * 2),
|
459 |
+
kaleidPreset3: Math.floor(2 + Math.random() * 2),
|
460 |
+
colorR: Math.random() * 0.5,
|
461 |
+
colorG: Math.random() * 0.5 + 0.3,
|
462 |
+
colorB: Math.random() * 0.5 + 0.5
|
463 |
+
};
|
464 |
+
if (audioPlaying) {
|
465 |
+
oscillators[0].frequency.setValueAtTime(randomParams.deltaFreq, audioCtx.currentTime);
|
466 |
+
oscillators[1].frequency.setValueAtTime(randomParams.deltaFreq + 2, audioCtx.currentTime);
|
467 |
+
oscillators[2].frequency.setValueAtTime(randomParams.thetaFreq, audioCtx.currentTime);
|
468 |
+
oscillators[3].frequency.setValueAtTime(randomParams.thetaFreq + 6, audioCtx.currentTime);
|
469 |
+
oscillators[4].frequency.setValueAtTime(randomParams.alphaFreq, audioCtx.currentTime);
|
470 |
+
oscillators[5].frequency.setValueAtTime(randomParams.alphaFreq + 10, audioCtx.currentTime);
|
471 |
+
oscillators[6].frequency.setValueAtTime(randomParams.betaFreq, audioCtx.currentTime);
|
472 |
+
oscillators[7].frequency.setValueAtTime(randomParams.betaFreq + 20, audioCtx.currentTime);
|
473 |
+
oscillators[8].frequency.setValueAtTime(randomParams.formant1Freq, audioCtx.currentTime);
|
474 |
+
oscillators[9].frequency.setValueAtTime(randomParams.formant2Freq, audioCtx.currentTime);
|
475 |
+
gainNodes[8].frequency.setValueAtTime(randomParams.formant1Freq, audioCtx.currentTime);
|
476 |
+
gainNodes[9].frequency.setValueAtTime(randomParams.formant2Freq, audioCtx.currentTime);
|
477 |
+
}
|
478 |
+
insertDream();
|
479 |
+
updateButtonStates();
|
480 |
+
}
|
481 |
+
|
482 |
+
function toggleAudio() {
|
483 |
+
if (audioPlaying) {
|
484 |
+
oscillators.forEach(osc => osc.stop());
|
485 |
+
oscillators = [];
|
486 |
+
gainNodes = [];
|
487 |
+
audioPlaying = false;
|
488 |
+
} else {
|
489 |
+
createBinauralAndSounds();
|
490 |
+
oscillators.forEach(osc => osc.start());
|
491 |
+
audioPlaying = true;
|
492 |
+
}
|
493 |
+
updateButtonStates();
|
494 |
+
}
|
495 |
+
|
496 |
+
function toggleVoiceDetection() {
|
497 |
+
voiceActive = !voiceActive;
|
498 |
+
if (!voiceActive) {
|
499 |
+
if (audioPlaying) {
|
500 |
+
gainNodes[0].gain.setValueAtTime(0.04, audioCtx.currentTime);
|
501 |
+
gainNodes[2].gain.setValueAtTime(0.03, audioCtx.currentTime);
|
502 |
+
gainNodes[4].gain.setValueAtTime(0.02, audioCtx.currentTime);
|
503 |
+
gainNodes[6].gain.setValueAtTime(0.015, audioCtx.currentTime);
|
504 |
+
gainNodes[8].gain.setValueAtTime(0, audioCtx.currentTime);
|
505 |
+
gainNodes[9].gain.setValueAtTime(0, audioCtx.currentTime);
|
506 |
+
gainNodes[10].gain.setValueAtTime(0.01, audioCtx.currentTime);
|
507 |
+
gainNodes[11].gain.setValueAtTime(0.01, audioCtx.currentTime);
|
508 |
+
gainNodes[12].gain.setValueAtTime(0.01, audioCtx.currentTime);
|
509 |
+
}
|
510 |
+
formantIntensity = 0;
|
511 |
+
}
|
512 |
+
updateButtonStates();
|
513 |
+
}
|
514 |
+
|
515 |
+
function toggleFormantSynthesis() {
|
516 |
+
formantSynthesisActive = !formantSynthesisActive;
|
517 |
+
if (!formantSynthesisActive && audioPlaying) {
|
518 |
+
gainNodes[8].gain.setValueAtTime(0, audioCtx.currentTime);
|
519 |
+
gainNodes[9].gain.setValueAtTime(0, audioCtx.currentTime);
|
520 |
+
}
|
521 |
+
updateButtonStates();
|
522 |
+
}
|
523 |
+
|
524 |
+
// Запрашиваем аудио и камеру
|
525 |
+
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
|
526 |
+
.then(stream => {
|
527 |
+
setupVoiceDetection(stream);
|
528 |
+
setupCamera();
|
529 |
+
insertDream();
|
530 |
+
toggleAudio();
|
531 |
+
toggleVoiceDetection();
|
532 |
+
})
|
533 |
+
.catch(err => {
|
534 |
+
console.error("Media access failed:", err);
|
535 |
+
navigator.mediaDevices.getUserMedia({ audio: true })
|
536 |
+
.then(stream => {
|
537 |
+
setupVoiceDetection(stream);
|
538 |
+
insertDream();
|
539 |
+
toggleAudio();
|
540 |
+
toggleVoiceDetection();
|
541 |
+
})
|
542 |
+
.catch(err => {
|
543 |
+
console.error("Audio access failed:", err);
|
544 |
+
insertDream();
|
545 |
+
toggleAudio();
|
546 |
+
});
|
547 |
+
});
|
548 |
+
|
549 |
+
// Основной нейро-фрактальный сон
|
550 |
+
function insertDream() {
|
551 |
+
terminal.value = `
|
552 |
+
// Вращающийся фрактальный глобус
|
553 |
+
osc(${randomParams.oscFreqGlobe}, 0.1, 1)
|
554 |
+
.color(${randomParams.colorR}, ${randomParams.colorG}, ${randomParams.colorB}, 0.9)
|
555 |
+
.rotate(0, () => time * 0.02)
|
556 |
+
.scale(() => 1 + a.fft[0] * 0.2 + ${formantIntensity} * 0.15 + ${camIntensity} * 0.1)
|
557 |
+
.modulate(src(s0), 0.05)
|
558 |
+
.kaleid(${randomParams.kaleidGlobe})
|
559 |
+
.out(o0)
|
560 |
+
|
561 |
+
// Лазерное сканирование
|
562 |
+
osc(${randomParams.oscFreqLasers}, 0.1, 1)
|
563 |
+
.color(1, 0, 0)
|
564 |
+
.modulate(noise(1, 0.05), 0.03)
|
565 |
+
.kaleid(${randomParams.kaleidLasers})
|
566 |
+
.scale(() => 1 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.05)
|
567 |
+
.modulate(src(s0), 0.03)
|
568 |
+
.out(o1)
|
569 |
+
|
570 |
+
// Первый ЭЭГ: OSC, реагирует на звук и голос
|
571 |
+
osc(${randomParams.oscFreqEEG1}, 0.1)
|
572 |
+
.scale(() => 1 + a.fft[0] * 0.3 + ${formantIntensity} * 0.2 + ${camIntensity} * 0.1)
|
573 |
+
.rotate(0, () => time * 0.01 + ${formantIntensity} * 0.01)
|
574 |
+
.color(0.5, 0.5, 1, 0.7)
|
575 |
+
.out(o2)
|
576 |
+
|
577 |
+
// Второй ЭЭГ: модерирует первый
|
578 |
+
src(o2)
|
579 |
+
.modulate(osc(${randomParams.oscFreqEEG2}, 0.05).add(() => a.fft[1] * 0.1 + ${formantIntensity} * 0.05 + ${camIntensity} * 0.05), 0.03)
|
580 |
+
.scale(1.1)
|
581 |
+
.color(0.7, 0.2, 1, 0.8)
|
582 |
+
.out(o3)
|
583 |
+
|
584 |
+
// Нейронный декодер
|
585 |
+
osc(6, 0.1)
|
586 |
+
.diff(osc(7, 0.1))
|
587 |
+
.posterize(2)
|
588 |
+
.colorama(0.05)
|
589 |
+
.scale(() => 1 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.05)
|
590 |
+
.modulate(src(s0), 0.03)
|
591 |
+
.out(o4)
|
592 |
+
|
593 |
+
// Биометрические показатели: пульс
|
594 |
+
osc(3, 0, 0.5)
|
595 |
+
.color(1, 0, 0)
|
596 |
+
.scale(0.3, 0.04)
|
597 |
+
.scrollY(-0.4)
|
598 |
+
.out(o5)
|
599 |
+
|
600 |
+
// Биометрические показатели: нейроактивность
|
601 |
+
osc(4, 0.1, 0.5)
|
602 |
+
.color(0, 0.5, 1)
|
603 |
+
.scale(0.3, 0.04)
|
604 |
+
.scrollY(-0.45)
|
605 |
+
.out(o6)
|
606 |
+
|
607 |
+
// Торсионный индикатор
|
608 |
+
osc(2, 0.05)
|
609 |
+
.scale(() => 0.5 + osc(0.4, 0.05).x * 0.3, 1)
|
610 |
+
.color(0.8, 0.2, 1)
|
611 |
+
.scrollY(0.4)
|
612 |
+
.out(o7)
|
613 |
+
|
614 |
+
// Координаты цели
|
615 |
+
osc(3, 0.1)
|
616 |
+
.scale(0.15)
|
617 |
+
.scrollX(0.4)
|
618 |
+
.scrollY(-0.4)
|
619 |
+
.color(0, 1, 0)
|
620 |
+
.out(o8)
|
621 |
+
|
622 |
+
// Окно для синтетического сознания
|
623 |
+
shape(4, 0.3, 0.01)
|
624 |
+
.color(1, 1, 1, 0.5)
|
625 |
+
.modulate(osc(0.5).add(() => ${formantIntensity} * 0.05 + ${camIntensity} * 0.05), 0.01)
|
626 |
+
.out(o9)
|
627 |
+
|
628 |
+
// Карта окружения (радар)
|
629 |
+
osc(5, 0.2)
|
630 |
+
.color(0, 1, 0)
|
631 |
+
.scale(() => 0.2 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.1)
|
632 |
+
.scrollX(0.35)
|
633 |
+
.scrollY(0.35)
|
634 |
+
.modulate(src(s0), 0.05)
|
635 |
+
.modulate(osc(10).rotate(0, 0.1), 0.05)
|
636 |
+
.out(o10)
|
637 |
+
|
638 |
+
// Эффекты пространства и финальная композиция
|
639 |
+
src(o0)
|
640 |
+
.add(src(o1), 0.3)
|
641 |
+
.add(src(o3), 0.3)
|
642 |
+
.add(src(o4), 0.3)
|
643 |
+
.add(src(o10), 0.4)
|
644 |
+
.modulate(noise(1, 0.05), 0.02)
|
645 |
+
.add(shape(4, 0.2, 0.01).rotate(0, 0.01 + ${formantIntensity} * 0.01 + ${camIntensity} * 0.01), 0.2)
|
646 |
+
.add(src(o5), 0.6)
|
647 |
+
.add(src(o6), 0.6)
|
648 |
+
.add(src(o7), 0.7)
|
649 |
+
.add(src(o8), 0.7)
|
650 |
+
.add(src(o9), 0.5)
|
651 |
+
.out()
|
652 |
+
`;
|
653 |
+
eval(terminal.value);
|
654 |
+
terminal.style.display = 'block';
|
655 |
+
}
|
656 |
+
|
657 |
+
// OSC Пресет 1: Медленные волны
|
658 |
+
function insertOscPreset1() {
|
659 |
+
terminal.value = `
|
660 |
+
osc(${randomParams.oscFreqGlobe}, 0.1, 1)
|
661 |
+
.color(${randomParams.colorR}, ${randomParams.colorG}, ${randomParams.colorB})
|
662 |
+
.modulate(noise(1, 0.05), 0.05)
|
663 |
+
.scale(() => 1 + a.fft[0] * 0.2 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.1)
|
664 |
+
.modulate(src(s0), 0.05)
|
665 |
+
.kaleid(${randomParams.kaleidPreset1})
|
666 |
+
.out()
|
667 |
+
`;
|
668 |
+
eval(terminal.value);
|
669 |
+
terminal.style.display = 'block';
|
670 |
+
}
|
671 |
+
|
672 |
+
// OSC Пресет 2: Пульсирующий ритм
|
673 |
+
function insertOscPreset2() {
|
674 |
+
terminal.value = `
|
675 |
+
osc(${randomParams.oscFreqLasers}, 0.15, 1)
|
676 |
+
.color(1, 0.2, 0.5)
|
677 |
+
.modulate(osc(2, 0.05), 0.05)
|
678 |
+
.scale(() => 1 + a.fft[1] * 0.2 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.1)
|
679 |
+
.modulate(src(s0), 0.05)
|
680 |
+
.kaleid(${randomParams.kaleidPreset2})
|
681 |
+
.out()
|
682 |
+
`;
|
683 |
+
eval(terminal.value);
|
684 |
+
terminal.style.display = 'block';
|
685 |
+
}
|
686 |
+
|
687 |
+
// OSC Пресет 3: Энергичный всплеск
|
688 |
+
function insertOscPreset3() {
|
689 |
+
terminal.value = `
|
690 |
+
osc(${randomParams.oscFreqLasers + 2}, 0.2, 1)
|
691 |
+
.color(0.5, 1, 0.2)
|
692 |
+
.modulate(noise(1, 0.1), 0.1)
|
693 |
+
.scale(() => 1 + a.fft[2] * 0.3 + ${formantIntensity} * 0.1 + ${camIntensity} * 0.1)
|
694 |
+
.modulate(src(s0), 0.05)
|
695 |
+
.kaleid(${randomParams.kaleidPreset3})
|
696 |
+
.out()
|
697 |
+
`;
|
698 |
+
eval(terminal.value);
|
699 |
+
terminal.style.display = 'block';
|
700 |
+
}
|
701 |
+
|
702 |
+
// Periodic randomization
|
703 |
+
setInterval(randomizeParameters, 10000);
|
704 |
+
insertDream();
|
705 |
+
toggleAudio();
|
706 |
+
toggleVoiceDetection();
|
707 |
+
toggleFormantSynthesis();
|
708 |
+
</script>
|
709 |
+
</body>
|
710 |
</html>
|