karmikovic commited on
Commit
344df9b
·
verified ·
1 Parent(s): 206dbb5

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +635 -19
index.html CHANGED
@@ -1,19 +1,635 @@
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
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Vibe Voice - Real-Time Audio Visualizer</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --primary: #6c5ce7;
11
+ --primary-dark: #5649c0;
12
+ --secondary: #a29bfe;
13
+ --accent: #fd79a8;
14
+ --dark: #2d3436;
15
+ --light: #f5f6fa;
16
+ --success: #00b894;
17
+ --warning: #fdcb6e;
18
+ --danger: #d63031;
19
+ }
20
+
21
+ * {
22
+ margin: 0;
23
+ padding: 0;
24
+ box-sizing: border-box;
25
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
26
+ }
27
+
28
+ body {
29
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
30
+ min-height: 100vh;
31
+ display: flex;
32
+ flex-direction: column;
33
+ align-items: center;
34
+ color: var(--dark);
35
+ line-height: 1.6;
36
+ }
37
+
38
+ header {
39
+ width: 100%;
40
+ padding: 1.5rem 2rem;
41
+ background: rgba(255, 255, 255, 0.9);
42
+ backdrop-filter: blur(10px);
43
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
44
+ display: flex;
45
+ justify-content: space-between;
46
+ align-items: center;
47
+ position: sticky;
48
+ top: 0;
49
+ z-index: 100;
50
+ }
51
+
52
+ .logo {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 0.5rem;
56
+ text-decoration: none;
57
+ color: var(--primary);
58
+ font-weight: 700;
59
+ font-size: 1.5rem;
60
+ }
61
+
62
+ .logo i {
63
+ font-size: 1.8rem;
64
+ }
65
+
66
+ .anycoder-link {
67
+ color: var(--primary);
68
+ text-decoration: none;
69
+ font-weight: 500;
70
+ transition: all 0.3s ease;
71
+ }
72
+
73
+ .anycoder-link:hover {
74
+ color: var(--primary-dark);
75
+ transform: translateY(-2px);
76
+ }
77
+
78
+ .container {
79
+ width: 100%;
80
+ max-width: 1200px;
81
+ padding: 2rem;
82
+ margin: 2rem 0;
83
+ }
84
+
85
+ h1 {
86
+ text-align: center;
87
+ margin-bottom: 1.5rem;
88
+ color: var(--primary);
89
+ font-size: 2.5rem;
90
+ background: linear-gradient(90deg, var(--primary), var(--accent));
91
+ -webkit-background-clip: text;
92
+ background-clip: text;
93
+ color: transparent;
94
+ background-color: transparent;
95
+ }
96
+
97
+ .subheading {
98
+ text-align: center;
99
+ margin-bottom: 3rem;
100
+ color: var(--dark);
101
+ font-size: 1.1rem;
102
+ max-width: 700px;
103
+ margin-left: auto;
104
+ margin-right: auto;
105
+ }
106
+
107
+ .controls {
108
+ display: flex;
109
+ justify-content: center;
110
+ gap: 1rem;
111
+ margin-bottom: 2rem;
112
+ flex-wrap: wrap;
113
+ }
114
+
115
+ button {
116
+ padding: 0.8rem 1.5rem;
117
+ border: none;
118
+ border-radius: 50px;
119
+ font-weight: 600;
120
+ cursor: pointer;
121
+ transition: all 0.3s ease;
122
+ display: flex;
123
+ align-items: center;
124
+ gap: 0.5rem;
125
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
126
+ }
127
+
128
+ .btn-primary {
129
+ background: var(--primary);
130
+ color: white;
131
+ }
132
+
133
+ .btn-primary:hover {
134
+ background: var(--primary-dark);
135
+ transform: translateY(-2px);
136
+ }
137
+
138
+ .btn-secondary {
139
+ background: var(--secondary);
140
+ color: var(--dark);
141
+ }
142
+
143
+ .btn-secondary:hover {
144
+ background: #8a83e6;
145
+ transform: translateY(-2px);
146
+ }
147
+
148
+ .btn-danger {
149
+ background: var(--danger);
150
+ color: white;
151
+ }
152
+
153
+ .btn-danger:hover {
154
+ background: #b72727;
155
+ transform: translateY(-2px);
156
+ }
157
+
158
+ .visualizer-container {
159
+ background: rgba(255, 255, 255, 0.9);
160
+ border-radius: 20px;
161
+ padding: 2rem;
162
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
163
+ margin-bottom: 2rem;
164
+ backdrop-filter: blur(10px);
165
+ }
166
+
167
+ .visualizer {
168
+ width: 100%;
169
+ height: 300px;
170
+ display: flex;
171
+ align-items: flex-end;
172
+ justify-content: center;
173
+ gap: 2px;
174
+ padding: 1rem;
175
+ background: rgba(255, 255, 255, 0.5);
176
+ border-radius: 10px;
177
+ overflow: hidden;
178
+ }
179
+
180
+ .bar {
181
+ width: 4px;
182
+ background: linear-gradient(to top, var(--primary), var(--accent));
183
+ border-radius: 2px;
184
+ transition: height 0.1s ease;
185
+ }
186
+
187
+ .status {
188
+ text-align: center;
189
+ margin: 1rem 0;
190
+ font-weight: 600;
191
+ color: var(--dark);
192
+ }
193
+
194
+ .status.active {
195
+ color: var(--success);
196
+ }
197
+
198
+ .stats {
199
+ display: flex;
200
+ justify-content: space-around;
201
+ margin: 2rem 0;
202
+ flex-wrap: wrap;
203
+ gap: 1rem;
204
+ }
205
+
206
+ .stat-card {
207
+ background: white;
208
+ padding: 1.5rem;
209
+ border-radius: 15px;
210
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
211
+ text-align: center;
212
+ flex: 1;
213
+ min-width: 200px;
214
+ }
215
+
216
+ .stat-value {
217
+ font-size: 2rem;
218
+ font-weight: 700;
219
+ color: var(--primary);
220
+ margin-bottom: 0.5rem;
221
+ }
222
+
223
+ .stat-label {
224
+ color: var(--dark);
225
+ font-size: 0.9rem;
226
+ text-transform: uppercase;
227
+ letter-spacing: 1px;
228
+ }
229
+
230
+ .features {
231
+ display: grid;
232
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
233
+ gap: 1.5rem;
234
+ margin: 2rem 0;
235
+ }
236
+
237
+ .feature-card {
238
+ background: white;
239
+ padding: 1.5rem;
240
+ border-radius: 15px;
241
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
242
+ transition: all 0.3s ease;
243
+ }
244
+
245
+ .feature-card:hover {
246
+ transform: translateY(-5px);
247
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
248
+ }
249
+
250
+ .feature-icon {
251
+ font-size: 2.5rem;
252
+ color: var(--primary);
253
+ margin-bottom: 1rem;
254
+ }
255
+
256
+ .feature-title {
257
+ font-size: 1.2rem;
258
+ font-weight: 700;
259
+ margin-bottom: 0.5rem;
260
+ color: var(--dark);
261
+ }
262
+
263
+ .feature-description {
264
+ color: #636e72;
265
+ font-size: 0.95rem;
266
+ }
267
+
268
+ footer {
269
+ width: 100%;
270
+ padding: 1.5rem;
271
+ background: rgba(255, 255, 255, 0.9);
272
+ text-align: center;
273
+ color: var(--dark);
274
+ margin-top: auto;
275
+ }
276
+
277
+ .social-links {
278
+ display: flex;
279
+ justify-content: center;
280
+ gap: 1rem;
281
+ margin: 1rem 0;
282
+ }
283
+
284
+ .social-links a {
285
+ color: var(--dark);
286
+ font-size: 1.5rem;
287
+ transition: all 0.3s ease;
288
+ }
289
+
290
+ .social-links a:hover {
291
+ color: var(--primary);
292
+ transform: translateY(-3px);
293
+ }
294
+
295
+ @media (max-width: 768px) {
296
+ .container {
297
+ padding: 1rem;
298
+ }
299
+
300
+ h1 {
301
+ font-size: 2rem;
302
+ }
303
+
304
+ .controls {
305
+ flex-direction: column;
306
+ align-items: center;
307
+ }
308
+
309
+ .visualizer {
310
+ height: 200px;
311
+ }
312
+
313
+ .stats {
314
+ flex-direction: column;
315
+ }
316
+ }
317
+
318
+ @media (max-width: 480px) {
319
+ header {
320
+ flex-direction: column;
321
+ gap: 1rem;
322
+ padding: 1rem;
323
+ }
324
+
325
+ .visualizer {
326
+ height: 150px;
327
+ }
328
+
329
+ .bar {
330
+ width: 2px;
331
+ }
332
+ }
333
+
334
+ /* Loading animation */
335
+ .loading {
336
+ display: inline-block;
337
+ width: 20px;
338
+ height: 20px;
339
+ border: 3px solid rgba(255,255,255,.3);
340
+ border-radius: 50%;
341
+ border-top-color: white;
342
+ animation: spin 1s ease-in-out infinite;
343
+ }
344
+
345
+ @keyframes spin {
346
+ to { transform: rotate(360deg); }
347
+ }
348
+
349
+ /* Pulse animation for active state */
350
+ @keyframes pulse {
351
+ 0% { transform: scale(1); }
352
+ 50% { transform: scale(1.05); }
353
+ 100% { transform: scale(1); }
354
+ }
355
+
356
+ .status.active {
357
+ animation: pulse 1.5s ease-in-out infinite;
358
+ }
359
+ </style>
360
+ </head>
361
+ <body>
362
+ <header>
363
+ <a href="#" class="logo">
364
+ <i class="fas fa-microphone-alt"></i>
365
+ <span>Vibe Voice</span>
366
+ </a>
367
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">
368
+ Built with anycoder
369
+ </a>
370
+ </header>
371
+
372
+ <div class="container">
373
+ <h1>Real-Time Audio Visualizer</h1>
374
+ <p class="subheading">
375
+ Experience your voice like never before with our advanced real-time audio visualization.
376
+ See the frequency spectrum of your voice and analyze its characteristics.
377
+ </p>
378
+
379
+ <div class="controls">
380
+ <button id="startBtn" class="btn-primary">
381
+ <i class="fas fa-play"></i> Start Visualization
382
+ </button>
383
+ <button id="stopBtn" class="btn-danger" disabled>
384
+ <i class="fas fa-stop"></i> Stop Visualization
385
+ </button>
386
+ <button id="clearBtn" class="btn-secondary">
387
+ <i class="fas fa-eraser"></i> Clear Visualization
388
+ </button>
389
+ </div>
390
+
391
+ <div class="status" id="status">
392
+ Ready to visualize your voice
393
+ </div>
394
+
395
+ <div class="visualizer-container">
396
+ <div class="visualizer" id="visualizer">
397
+ <!-- Bars will be added by JavaScript -->
398
+ </div>
399
+ </div>
400
+
401
+ <div class="stats">
402
+ <div class="stat-card">
403
+ <div class="stat-value" id="frequency">0</div>
404
+ <div class="stat-label">Dominant Frequency (Hz)</div>
405
+ </div>
406
+ <div class="stat-card">
407
+ <div class="stat-value" id="volume">0</div>
408
+ <div class="stat-label">Volume Level</div>
409
+ </div>
410
+ <div class="stat-card">
411
+ <div class="stat-value" id="pitch">0</div>
412
+ <div class="stat-label">Pitch Detection</div>
413
+ </div>
414
+ </div>
415
+
416
+ <div class="features">
417
+ <div class="feature-card">
418
+ <div class="feature-icon">
419
+ <i class="fas fa-wave-square"></i>
420
+ </div>
421
+ <h3 class="feature-title">Real-Time Analysis</h3>
422
+ <p class="feature-description">
423
+ Get instant feedback on your voice with our real-time audio processing engine.
424
+ See frequency patterns as you speak or sing.
425
+ </p>
426
+ </div>
427
+ <div class="feature-card">
428
+ <div class="feature-icon">
429
+ <i class="fas fa-chart-line"></i>
430
+ </div>
431
+ <h3 class="feature-title">Frequency Visualization</h3>
432
+ <p class="feature-description">
433
+ Visualize the frequency spectrum of your voice with our interactive bar graph.
434
+ Understand the composition of your voice.
435
+ </p>
436
+ </div>
437
+ <div class="feature-card">
438
+ <div class="feature-icon">
439
+ <i class="fas fa-cog"></i>
440
+ </div>
441
+ <h3 class="feature-title">Advanced Processing</h3>
442
+ <p class="feature-description">
443
+ Our system uses Web Audio API for precise audio analysis.
444
+ Detect pitch, volume, and frequency characteristics.
445
+ </p>
446
+ </div>
447
+ </div>
448
+ </div>
449
+
450
+ <footer>
451
+ <div class="social-links">
452
+ <a href="#" title="Twitter"><i class="fab fa-twitter"></i></a>
453
+ <a href="#" title="Facebook"><i class="fab fa-facebook"></i></a>
454
+ <a href="#" title="GitHub"><i class="fab fa-github"></i></a>
455
+ <a href="#" title="Instagram"><i class="fab fa-instagram"></i></a>
456
+ </div>
457
+ <p>&copy; 2023 Vibe Voice. All rights reserved.</p>
458
+ </footer>
459
+
460
+ <script>
461
+ document.addEventListener('DOMContentLoaded', function() {
462
+ // DOM elements
463
+ const startBtn = document.getElementById('startBtn');
464
+ const stopBtn = document.getElementById('stopBtn');
465
+ const clearBtn = document.getElementById('clearBtn');
466
+ const status = document.getElementById('status');
467
+ const visualizer = document.getElementById('visualizer');
468
+ const frequencyDisplay = document.getElementById('frequency');
469
+ const volumeDisplay = document.getElementById('volume');
470
+ const pitchDisplay = document.getElementById('pitch');
471
+
472
+ // Audio context and analyzer
473
+ let audioContext;
474
+ let analyser;
475
+ let dataArray;
476
+ let source;
477
+ let stream;
478
+ let animationId;
479
+ let isVisualizing = false;
480
+
481
+ // Number of bars for visualization
482
+ const barCount = 128;
483
+
484
+ // Create visualizer bars
485
+ function createVisualizer() {
486
+ visualizer.innerHTML = '';
487
+ for (let i = 0; i < barCount; i++) {
488
+ const bar = document.createElement('div');
489
+ bar.className = 'bar';
490
+ bar.style.height = '2px';
491
+ visualizer.appendChild(bar);
492
+ }
493
+ }
494
+
495
+ // Initialize audio context
496
+ function initAudio() {
497
+ try {
498
+ audioContext = new (window.AudioContext || window.webkitAudioContext)();
499
+ analyser = audioContext.createAnalyser();
500
+ analyser.fftSize = 256;
501
+ const bufferLength = analyser.frequencyBinCount;
502
+ dataArray = new Uint8Array(bufferLength);
503
+
504
+ createVisualizer();
505
+ status.textContent = "Ready to start visualization";
506
+ } catch (err) {
507
+ console.error("Audio context error:", err);
508
+ status.textContent = "Audio context not supported in your browser";
509
+ startBtn.disabled = true;
510
+ }
511
+ }
512
+
513
+ // Start visualization
514
+ async function startVisualization() {
515
+ if (isVisualizing) return;
516
+
517
+ try {
518
+ status.textContent = "Accessing microphone...";
519
+ stream = await navigator.mediaDevices.getUserMedia({ audio: true });
520
+ source = audioContext.createMediaStreamSource(stream);
521
+ source.connect(analyser);
522
+
523
+ isVisualizing = true;
524
+ startBtn.disabled = true;
525
+ stopBtn.disabled = false;
526
+ status.textContent = "Visualizing your voice";
527
+ status.classList.add('active');
528
+
529
+ draw();
530
+ } catch (err) {
531
+ console.error("Microphone access error:", err);
532
+ status.textContent = "Could not access microphone";
533
+ status.classList.remove('active');
534
+ startBtn.disabled = false;
535
+ }
536
+ }
537
+
538
+ // Stop visualization
539
+ function stopVisualization() {
540
+ if (!isVisualizing) return;
541
+
542
+ if (stream) {
543
+ stream.getTracks().forEach(track => track.stop());
544
+ }
545
+
546
+ if (source) {
547
+ source.disconnect();
548
+ }
549
+
550
+ if (animationId) {
551
+ cancelAnimationFrame(animationId);
552
+ }
553
+
554
+ isVisualizing = false;
555
+ startBtn.disabled = false;
556
+ stopBtn.disabled = true;
557
+ status.textContent = "Visualization stopped";
558
+ status.classList.remove('active');
559
+
560
+ // Reset displays
561
+ frequencyDisplay.textContent = '0';
562
+ volumeDisplay.textContent = '0';
563
+ pitchDisplay.textContent = '0';
564
+ }
565
+
566
+ // Clear visualization
567
+ function clearVisualization() {
568
+ const bars = document.querySelectorAll('.bar');
569
+ bars.forEach(bar => {
570
+ bar.style.height = '2px';
571
+ });
572
+
573
+ // Reset displays
574
+ frequencyDisplay.textContent = '0';
575
+ volumeDisplay.textContent = '0';
576
+ pitchDisplay.textContent = '0';
577
+ }
578
+
579
+ // Draw visualization
580
+ function draw() {
581
+ analyser.getByteFrequencyData(dataArray);
582
+
583
+ const bars = document.querySelectorAll('.bar');
584
+ let totalVolume = 0;
585
+ let maxFrequency = 0;
586
+ let maxIndex = 0;
587
+
588
+ for (let i = 0; i < barCount; i++) {
589
+ const barHeight = dataArray[i] / 2;
590
+ bars[i].style.height = barHeight + 'px';
591
+
592
+ // Calculate total volume
593
+ totalVolume += dataArray[i];
594
+
595
+ // Find dominant frequency
596
+ if (dataArray[i] > maxFrequency) {
597
+ maxFrequency = dataArray[i];
598
+ maxIndex = i;
599
+ }
600
+ }
601
+
602
+ // Calculate average volume (0-100)
603
+ const averageVolume = Math.round((totalVolume / barCount) * 100 / 255);
604
+ volumeDisplay.textContent = averageVolume;
605
+
606
+ // Calculate dominant frequency (approximate)
607
+ const nyquist = audioContext.sampleRate / 2;
608
+ const dominantFreq = Math.round((maxIndex * nyquist) / analyser.fftSize);
609
+ frequencyDisplay.textContent = dominantFreq;
610
+
611
+ // Simple pitch detection (note: this is a simplified approximation)
612
+ const pitch = dominantFreq > 0 ? Math.round(12 * (Math.log(dominantFreq / 440) / Math.log(2)) + 69) : 0;
613
+ pitchDisplay.textContent = pitch > 0 ? pitch : '0';
614
+
615
+ animationId = requestAnimationFrame(draw);
616
+ }
617
+
618
+ // Event listeners
619
+ startBtn.addEventListener('click', startVisualization);
620
+ stopBtn.addEventListener('click', stopVisualization);
621
+ clearBtn.addEventListener('click', clearVisualization);
622
+
623
+ // Initialize on page load
624
+ initAudio();
625
+
626
+ // Clean up on page unload
627
+ window.addEventListener('beforeunload', function() {
628
+ if (isVisualizing) {
629
+ stopVisualization();
630
+ }
631
+ });
632
+ });
633
+ </script>
634
+ </body>
635
+ </html>