Dmtlant commited on
Commit
7d44b25
·
verified ·
1 Parent(s): f7a05cc

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +208 -93
index.html CHANGED
@@ -1,115 +1,230 @@
1
  <!DOCTYPE html>
2
  <html>
3
  <head>
4
- <title>TTS GUI</title>
5
- <style>
6
- body {
7
- font-family: Arial, sans-serif;
8
- display: flex;
9
- flex-direction: column;
10
- align-items: center;
11
- justify-content: center;
12
- height: 100vh;
13
- margin: 0;
14
- background-color: #f0f0f0;
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- .container {
18
- background-color: white;
19
- padding: 20px;
20
- border-radius: 8px;
21
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
22
- width: 400px;
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- textarea {
26
- width: 100%;
27
- height: 100px;
28
- font-size: 16px;
29
- padding: 10px;
30
- box-sizing: border-box;
31
- border: 1px solid #ccc;
32
- border-radius: 4px;
33
- resize: vertical;
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
-
36
- button {
37
- width: 100%;
38
- font-size: 16px;
39
- padding: 10px;
40
- background-color: #4CAF50;
41
- color: white;
42
- border: none;
43
- border-radius: 4px;
44
- cursor: pointer;
45
- margin-top: 10px;
 
46
  }
 
 
 
 
 
 
 
 
 
47
 
48
- button:hover {
49
- background-color: #45a049;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
 
51
 
52
- #log-container {
53
- margin-top: 20px;
54
- width: 100%;
55
- max-height: 200px;
56
- overflow-y: auto;
57
- background-color: #f0f0f0;
58
- padding: 10px;
59
- border-radius: 4px;
60
- font-size: 14px;
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
- </style>
63
- </head>
64
- <body>
65
- <div class="container">
66
- <textarea id="text-input" placeholder="Enter text to convert to speech"></textarea>
67
- <button onclick="generateSpeech()">Generate Speech</button>
68
- <div id="log-container">
69
- <pre id="log"></pre>
70
- </div>
71
- </div>
72
-
73
- <script>
74
- async function generateSpeech() {
75
- const textInput = document.getElementById('text-input').value;
76
- const response = await query({ "inputs": textInput });
77
- const audioBlob = response;
78
- const audioUrl = URL.createObjectURL(audioBlob);
79
 
80
- // Create an Audio object and set its src property to the Blob URL
81
- const audio = new Audio(audioUrl);
82
- audio.play();
83
-
84
- // Log the audioBlob to the console
85
- console.log(audioBlob);
86
  }
 
87
 
88
- async function query(data) {
89
- logMessage('Sending request to the server...');
 
 
 
 
90
 
91
- const response = await fetch(
92
- "https://api-inference.huggingface.co/models/suno/bark-small",
93
- {
94
- headers: {
95
- Authorization: "Bearer hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
96
- "Content-Type": "application/json",
97
- },
98
- method: "POST",
99
- body: JSON.stringify(data),
100
- }
101
- );
102
 
103
- logMessage('Response received from the server.');
 
104
 
105
- const result = await response.blob();
106
- return result;
 
 
 
 
 
107
  }
 
 
108
 
109
- function logMessage(message) {
110
- const logContainer = document.getElementById('log');
111
- logContainer.textContent += `${message}\n`;
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
113
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  </body>
115
  </html>
 
1
  <!DOCTYPE html>
2
  <html>
3
  <head>
4
+ <title>Широкополосный FM и ELF Demodulator</title>
5
+ <style>
6
+ body { font-family: Arial, sans-serif; }
7
+ #controls { margin-bottom: 20px; }
8
+ </style>
9
+ </head>
10
+ <body>
11
+ <div id="controls">
12
+ <label for="frequencySlider">Частота (Hz): </label>
13
+ <input type="range" id="frequencySlider" min="3" max="20000" step="1" value="1000">
14
+ <span id="frequencyValue">1000</span> Hz
15
+ <button id="toggleAudio">Включить звук</button>
16
+ <button id="toggleELF">Включить ELF режим</button>
17
+ </div>
18
+ <canvas id="elfCanvas" width="800" height="150" style="border:1px solid #000000;"></canvas>
19
+ <script>
20
+ let audioContext;
21
+ let analyser;
22
+ let microphone;
23
+ let canvas;
24
+ let canvasCtx;
25
+ let scriptProcessor;
26
+ let prevPhase = 0;
27
+ let demodulatedSignal = [];
28
+ let gainNode;
29
+ let isAudioEnabled = false;
30
+ let isELFMode = false;
31
+ let centerFrequency = 1000; // Hz
32
+ let elfBuffer = [];
33
+ let elfCanvas;
34
+ let elfCtx;
35
+ let movingAverageBuffer = [];
36
+ const movingAverageSize = 50; // Размер окна для скользящего среднего
37
 
38
+ function startAudioAnalysis() {
39
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
40
+ analyser = audioContext.createAnalyser();
41
+ analyser.fftSize = 2048;
42
+
43
+ scriptProcessor = audioContext.createScriptProcessor(1024, 1, 1);
44
+ gainNode = audioContext.createGain();
45
+ gainNode.gain.setValueAtTime(0, audioContext.currentTime);
46
+
47
+ navigator.mediaDevices.getUserMedia({ audio: true, video: false })
48
+ .then(function(stream) {
49
+ microphone = audioContext.createMediaStreamSource(stream);
50
+ microphone.connect(analyser);
51
+ analyser.connect(scriptProcessor);
52
+ scriptProcessor.connect(gainNode);
53
+ gainNode.connect(audioContext.destination);
54
+
55
+ canvas = document.createElement('canvas');
56
+ canvas.width = 800;
57
+ canvas.height = 300;
58
+ document.body.appendChild(canvas);
59
+ canvasCtx = canvas.getContext('2d');
60
+
61
+ elfCanvas = document.getElementById('elfCanvas');
62
+ elfCtx = elfCanvas.getContext('2d');
63
+
64
+ drawSpectrum();
65
+ })
66
+ .catch(function(err) {
67
+ console.error('Ошибка доступа к микрофону:', err);
68
+ });
69
+
70
+ scriptProcessor.onaudioprocess = processAudio;
71
+ }
72
 
73
+ function drawSpectrum() {
74
+ requestAnimationFrame(drawSpectrum);
75
+
76
+ const bufferLength = analyser.frequencyBinCount;
77
+ const dataArray = new Uint8Array(bufferLength);
78
+ analyser.getByteFrequencyData(dataArray);
79
+
80
+ canvasCtx.fillStyle = 'rgb(0, 0, 0)';
81
+ canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
82
+
83
+ const barWidth = (canvas.width / bufferLength) * 2.5;
84
+ let x = 0;
85
+
86
+ for(let i = 0; i < bufferLength; i++) {
87
+ const barHeight = dataArray[i] / 2;
88
+
89
+ canvasCtx.fillStyle = `rgb(${barHeight + 100}, 50, 50)`;
90
+ canvasCtx.fillRect(x, canvas.height - barHeight, barWidth, barHeight);
91
+
92
+ x += barWidth + 1;
93
  }
94
+
95
+ // Рисуем демодулированный сигнал
96
+ canvasCtx.strokeStyle = 'rgb(0, 255, 0)';
97
+ canvasCtx.beginPath();
98
+ for(let i = 0; i < demodulatedSignal.length; i++) {
99
+ const x = (i / demodulatedSignal.length) * canvas.width;
100
+ const y = (0.5 - demodulatedSignal[i] / 2) * canvas.height;
101
+ if(i === 0) {
102
+ canvasCtx.moveTo(x, y);
103
+ } else {
104
+ canvasCtx.lineTo(x, y);
105
+ }
106
  }
107
+ canvasCtx.stroke();
108
+
109
+ // Рисуем маркер центральной частоты
110
+ const centerX = (centerFrequency / 20000) * canvas.width;
111
+ canvasCtx.strokeStyle = 'rgb(255, 255, 0)';
112
+ canvasCtx.beginPath();
113
+ canvasCtx.moveTo(centerX, 0);
114
+ canvasCtx.lineTo(centerX, canvas.height);
115
+ canvasCtx.stroke();
116
 
117
+ // Рисуем ELF сигнал
118
+ if (isELFMode) {
119
+ elfCtx.fillStyle = 'rgb(0, 0, 0)';
120
+ elfCtx.fillRect(0, 0, elfCanvas.width, elfCanvas.height);
121
+ elfCtx.strokeStyle = 'rgb(0, 255, 0)';
122
+ elfCtx.beginPath();
123
+ for(let i = 0; i < elfBuffer.length; i++) {
124
+ const x = (i / elfBuffer.length) * elfCanvas.width;
125
+ const y = (0.5 - elfBuffer[i] / 2) * elfCanvas.height;
126
+ if(i === 0) {
127
+ elfCtx.moveTo(x, y);
128
+ } else {
129
+ elfCtx.lineTo(x, y);
130
+ }
131
+ }
132
+ elfCtx.stroke();
133
  }
134
+ }
135
 
136
+ function processAudio(audioProcessingEvent) {
137
+ const inputBuffer = audioProcessingEvent.inputBuffer;
138
+ const outputBuffer = audioProcessingEvent.outputBuffer;
139
+ const inputData = inputBuffer.getChannelData(0);
140
+ const outputData = outputBuffer.getChannelData(0);
141
+
142
+ demodulatedSignal = [];
143
+
144
+ for(let i = 0; i < inputData.length; i++) {
145
+ const phase = Math.atan2(inputData[i], prevPhase);
146
+ const instantFreq = (phase - prevPhase + Math.PI) % (2 * Math.PI) - Math.PI;
147
+ let demodulated;
148
+ if (isELFMode) {
149
+ demodulated = lowPassFilter(instantFreq);
150
+ demodulated = movingAverage(demodulated);
151
+ } else {
152
+ demodulated = instantFreq * (centerFrequency / 1000);
153
+ }
154
+ demodulatedSignal.push(demodulated);
155
+ outputData[i] = demodulated;
156
+ prevPhase = inputData[i];
157
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
+ if (isELFMode) {
160
+ elfBuffer = elfBuffer.concat(demodulatedSignal);
161
+ if (elfBuffer.length > 1000) {
162
+ elfBuffer = elfBuffer.slice(-1000);
163
+ }
 
164
  }
165
+ }
166
 
167
+ function lowPassFilter(input) {
168
+ // Простой фильтр нижних частот
169
+ const alpha = 0.1;
170
+ this.filtered = (this.filtered || 0) * (1 - alpha) + input * alpha;
171
+ return this.filtered;
172
+ }
173
 
174
+ function movingAverage(input) {
175
+ movingAverageBuffer.push(input);
176
+ if (movingAverageBuffer.length > movingAverageSize) {
177
+ movingAverageBuffer.shift();
178
+ }
179
+ const sum = movingAverageBuffer.reduce((a, b) => a + b, 0);
180
+ return sum / movingA
 
 
 
 
181
 
182
+ return sum / movingAverageBuffer.length;
183
+ }
184
 
185
+ function toggleAudio() {
186
+ if (isAudioEnabled) {
187
+ gainNode.gain.setValueAtTime(0, audioContext.currentTime);
188
+ document.getElementById('toggleAudio').textContent = 'Включить звук';
189
+ } else {
190
+ gainNode.gain.setValueAtTime(1, audioContext.currentTime);
191
+ document.getElementById('toggleAudio').textContent = 'Выключить звук';
192
  }
193
+ isAudioEnabled = !isAudioEnabled;
194
+ }
195
 
196
+ function toggleELF() {
197
+ isELFMode = !isELFMode;
198
+ if (isELFMode) {
199
+ document.getElementById('toggleELF').textContent = 'Выключить ELF режим';
200
+ document.getElementById('frequencySlider').min = 3;
201
+ document.getElementById('frequencySlider').max = 30;
202
+ centerFrequency = 15;
203
+ document.getElementById('frequencySlider').value = centerFrequency;
204
+ updateFrequency();
205
+ } else {
206
+ document.getElementById('toggleELF').textContent = 'Включить ELF режим';
207
+ document.getElementById('frequencySlider').min = 3;
208
+ document.getElementById('frequencySlider').max = 20000;
209
+ centerFrequency = 1000;
210
+ document.getElementById('frequencySlider').value = centerFrequency;
211
+ updateFrequency();
212
  }
213
+ elfBuffer = [];
214
+ movingAverageBuffer = [];
215
+ }
216
+
217
+ function updateFrequency() {
218
+ centerFrequency = parseFloat(document.getElementById('frequencySlider').value);
219
+ document.getElementById('frequencyValue').textContent = centerFrequency.toFixed(0);
220
+ }
221
+
222
+ window.onload = function() {
223
+ startAudioAnalysis();
224
+ document.getElementById('toggleAudio').addEventListener('click', toggleAudio);
225
+ document.getElementById('toggleELF').addEventListener('click', toggleELF);
226
+ document.getElementById('frequencySlider').addEventListener('input', updateFrequency);
227
+ };
228
+ </script>
229
  </body>
230
  </html>