Dmtlant commited on
Commit
de46ccf
·
verified ·
1 Parent(s): f1bfa1a

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +709 -18
index.html CHANGED
@@ -1,19 +1,710 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>