Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
577 lines (554 loc) · 29.1 KB
/
Copy pathindex.html
File metadata and controls
577 lines (554 loc) · 29.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audiojs · open audio stack for JavaScript</title>
<meta name="description" content="Open audio stack for JavaScript. Decode, process, synthesize and play — same code on Browser, Node, Deno and Bun. 300+ modular packages · 9M+ npm downloads/month. W3C Web Audio · WPT 100%.">
<meta name="theme-color" content="#0d1014">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://audiojs.dev/">
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" type="image/png" sizes="512x512" href="/icon-512.png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://audiojs.dev/">
<meta property="og:title" content="audiojs · open audio stack for JavaScript">
<meta property="og:description" content="Decode, process, synthesize and play — same code on Browser, Node, Deno and Bun. 300+ modular packages · 9M+ npm downloads/month. W3C Web Audio · WPT 100%.">
<meta property="og:site_name" content="audiojs">
<meta property="og:image" content="https://audiojs.dev/icon-512.png">
<meta property="og:image:width" content="512">
<meta property="og:image:height" content="512">
<!-- Twitter -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://audiojs.dev/icon-512.png">
<meta name="twitter:site" content="@audio_js">
<meta name="twitter:title" content="audiojs · open audio stack for JavaScript">
<meta name="twitter:description" content="Decode, process, synthesize and play — same code on Browser, Node, Deno and Bun. 300+ modular packages · 9M+ npm downloads/month. W3C Web Audio · WPT 100%.">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://audiojs.dev/#org",
"name": "audiojs",
"url": "https://audiojs.dev/",
"logo": "https://audiojs.dev/icon-512.png",
"sameAs": ["https://github.com/audiojs", "https://www.npmjs.com/org/audiojs", "https://x.com/audio_js"]
},
{
"@type": "SoftwareSourceCode",
"name": "audiojs",
"description": "Open audio stack for JavaScript. Cross-runtime modules for decode, encode, synthesis, analysis and DSP.",
"url": "https://audiojs.dev/",
"codeRepository": "https://github.com/audiojs",
"programmingLanguage": "JavaScript",
"license": "https://opensource.org/licenses/MIT",
"author": { "@id": "https://audiojs.dev/#org" }
}
]
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;700;800&family=Orbitron:wght@400;700&family=Wavefont:ROND,wght@0..100,100..900&display=swap" rel="stylesheet">
<script src="https://unpkg.com/sprae" data-start></script>
<style>
:root {
/* colors */
--c-ink: #0d1014;
--c-paper: #edebe4;
--c-bg: #f1efe9;
--c-accent: #00a4b8;
/* fonts */
--f-body: 'Manrope', system-ui, sans-serif;
--f-logo: 'Orbitron', sans-serif;
--f-wave: 'Wavefont', monospace;
/* font sizes */
--fs-xs: clamp(10px, 1.5vw, 15px);
--fs-sm: clamp(12px, 1.7vw, 17px);
--fs-md: clamp(14px, 2vw, 20px);
--fs-lg: clamp(20px, 3vw, 30px);
--fs-xl: clamp(54px, 8.1vw, 81px);
--fs-2xl: clamp(72px, 10.8vw, 108px);
/* layout — rh scales with viewport; sw follows proportionally */
--rh: clamp(72px, 10.8vw, 108px);
--sw: calc(var(--rh) * 4);
--dot-cell: calc(var(--rh)/4);
/* aliases for legacy refs */
--ink: var(--c-ink);
--paper: var(--c-paper);
--teal: var(--c-accent);
--grot: var(--f-body);
--logo: var(--f-logo);
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 0;
font-family: var(--grot);
background-color: #f1efe9;
min-height: 100vh;
color: var(--ink);
}
h1 { margin: 0; font-weight: inherit; }
/* ─── COVER ─── */
.cover {
width: 100%;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
}
/* top dark half · canvas */
.top {
background: var(--ink);
color: var(--paper);
position: relative;
padding: 0;
min-height: calc(4 * var(--rh));
}
/* .top::before {
content: '';
position: absolute; inset: 0;
background-image: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px);
background-size: var(--dot-cell) var(--dot-cell);
background-position: center;
pointer-events: none;
} */
/* bottom half · transparent — shows root bg */
.bot {
position: relative;
padding: 0;
min-height: calc(var(--rh) * 5);
}
.bot::after { display: none; }
/* content wrapper inside each half */
.inner {
max-width: 1080px;
margin: 0 auto;
padding: 12px 56px 6.75rem;
height: 100%;
position: relative;
}
.bot .inner {
padding: 0 56px 32px;
height: auto;
}
.pro {
text-align: center;
padding-top: 0;
font-style: normal;
font-weight: 500;
font-size: var(--fs-xs);
color: var(--paper);
}
.wordmark {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 18px;
margin-top: 48px;
}
.wordmark .name {
font-family: var(--logo);
font-weight: 600;
font-size: var(--fs-2xl);
line-height: 0.72;
letter-spacing: -0.027em;
color: var(--paper);
}
.wordmark .js {
border: 0.036em solid var(--paper);
padding: 8px;
font-weight: 600;
font-size: clamp(42px, 6.4vw, 64px);
line-height: 0.81;
letter-spacing: -0.02em;
color: transparent;
-webkit-text-stroke: .054em var(--paper);
}
.subtitle {
font-weight: 500;
font-size: var(--fs-lg);
line-height: 1;
color: var(--paper);
margin-top: 2rem;
text-align: center;
}
.freq {
font-weight: 700;
font-size: var(--fs-xl);
line-height: 1;
letter-spacing: -0.035em;
color: var(--teal);
margin-top: 4px;
text-align: center;
}
/* wavefont stripe block */
.stripe-block {
width: var(--sw);
max-width: 100%;
opacity: 0;
transition: opacity 0.2s;
margin: calc(var(--rh) * -1) auto 0;
display: grid;
grid-template-rows: repeat(3, 1fr);
position: relative;
z-index: 2;
pointer-events: none;
user-select: none;
touch-action: none;
cursor: ew-resize;
}
.stripe-row {
pointer-events: auto;
overflow: hidden;
font-family: var(--f-wave);
font-size: var(--rh);
line-height: 1;
white-space: nowrap;
}
.stripe-row span {
display: inline-block;
width: calc(var(--sw) / var(--sn));
will-change: font-variation-settings;
transform: translateZ(0);
-webkit-font-smoothing: antialiased;
}
.r-0 { background-color: #f1efe9; }
.r-0, .r-1, .r-2 { color: var(--ink); }
.stripe-row:nth-child(even) { text-align: right; }
.feats {
margin-top: 20px;
text-align: center;
position: relative;
z-index: 3;
}
.feats div {
font-weight: 700;
font-size: var(--fs-lg);
letter-spacing: -0.012em;
color: var(--ink);
line-height: 1.55;
}
.stats {
margin-top: 26px;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 14px 56px;
position: relative;
z-index: 3;
text-align: center;
}
.stats a {
display: flex;
flex-direction: column;
gap: 2px;
color: var(--ink);
text-decoration: none;
transition: opacity 0.15s;
}
.stats a:hover { opacity: 0.7; }
.stats .n {
font-weight: 800;
font-size: var(--fs-lg);
letter-spacing: -0.012em;
line-height: 1;
}
.stats .l {
font-weight: 500;
font-size: var(--fs-xs);
}
.bullets {
margin-top: 20px;
text-align: center;
font-weight: 500;
font-size: var(--fs-xs);
color: var(--ink);
position: relative;
z-index: 3;
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0 1em;
}
.bullets div {
display: flex;
align-items: center;
gap: 0.4em;
}
.bullets div::before {
content: '◼';
font-size: 0.75em;
flex-shrink: 0;
}
.seal {
margin: 22px auto 0;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
position: relative;
z-index: 3;
color: var(--ink);
text-decoration: none;
transition: opacity 0.15s;
}
.seal:hover { opacity: 0.7; }
.seal svg { width: 54px; height: 54px; display: block; }
.caption {
text-align: center;
margin-top: 10px;
font-weight: 500;
font-size: var(--fs-xs);
color: var(--ink);
position: relative;
z-index: 3;
}
.intro {
max-width: 640px;
margin: 0 auto;
padding: 44px 24px 0;
text-align: center;
color: var(--ink);
}
.intro p { margin: 0; font-weight: 500; font-size: var(--fs-md); line-height: 1.45; }
.intro .start { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 8px 18px; margin-top: 16px; font-size: var(--fs-sm); font-weight: 700; }
.intro code { padding: 6px 12px; border-radius: 6px; background: var(--ink); color: var(--paper); font: 500 var(--fs-sm) ui-monospace, SFMono-Regular, Menlo, monospace; user-select: all; }
.intro a { color: inherit; text-decoration-color: var(--teal); text-underline-offset: 4px; }
.tools {
padding: 44px 24px 0;
text-align: center;
color: var(--ink);
}
.tools .t-label {
margin: 0;
font-weight: 800;
font-size: var(--fs-md);
letter-spacing: -0.012em;
}
.tools ul {
list-style: none;
margin: 18px auto 0;
padding: 0;
max-width: 760px;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
@media (max-width: 640px) { .tools ul { grid-template-columns: minmax(0, 1fr); max-width: 560px; } }
.tools li a {
display: block;
height: 100%;
padding: 14px 18px;
border: 1px solid #d6d3cb;
border-radius: 8px;
background: var(--paper);
color: inherit;
text-decoration: none;
transition: border-color 0.15s;
}
.tools li a:hover { border-color: var(--teal); }
.tools .t-name {
font-weight: 700;
font-size: var(--fs-sm);
letter-spacing: -0.01em;
}
.tools .t-desc {
margin-top: 3px;
font-weight: 500;
font-size: var(--fs-xs);
}
.sponsors {
padding: 44px 24px 56px;
text-align: center;
color: var(--ink);
}
.sponsors .s-label {
font-weight: 800;
font-size: var(--fs-md);
letter-spacing: -0.012em;
}
.sponsors .s-logos {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 18px 40px;
margin-top: 18px;
}
.sponsors .s-logos:empty { display: none; }
.sponsors .s-logos img { height: 28px; max-width: 140px; object-fit: contain; }
.sponsors .s-note {
margin-top: 14px;
font-weight: 500;
font-size: var(--fs-xs);
}
.sponsors .s-note a { color: inherit; white-space: nowrap; }
@media (max-width: 479px) {
.inner { padding-left: 24px; padding-right: 24px; }
.bot .inner { padding-left: 24px; padding-right: 24px; }
}
</style>
<link rel="stylesheet" href="/bar.css?v=4e6dabc4">
</head>
<body>
<header class="site-bar">
<a class="site-brand" href="/" aria-label="audiojs home" aria-current="page"><svg aria-hidden="true" viewBox="0 5 90.4 17" fill="currentColor"><path d="M4.2 22Q3.3 22 2.7 21.6Q2 21.2 1.6 20.5Q1.1 19.8 1.1 19V14.2H11.2V12.4Q11.2 12.3 11.1 12.2Q11.1 12.1 10.9 12.1H1.1V9.2H11.1Q11.9 9.2 12.6 9.7Q13.3 10.1 13.7 10.8Q14.1 11.4 14.1 12.3V22ZM4.3 19.1H11.2V16.8H4V18.9Q4 19 4.1 19Q4.2 19.1 4.3 19.1ZM19 22Q18.2 22 17.5 21.6Q16.8 21.2 16.4 20.5Q16 19.8 16 19V9.2H18.9V18.9Q18.9 19 19 19Q19 19.1 19.1 19.1H25.8Q25.9 19.1 26 19Q26.1 19 26.1 18.9V9.2H29V19Q29 19.8 28.5 20.5Q28.1 21.2 27.4 21.6Q26.8 22 25.9 22H19ZM33.2 22Q32.4 22 31.7 21.6Q31 21.2 30.6 20.5Q30.2 19.8 30.2 19V12.3Q30.2 11.4 30.6 10.8Q31 10.1 31.7 9.7Q32.4 9.2 33.2 9.2H40.3V5.1H43.2V22H33.2ZM33.4 19.1H40Q40.1 19.1 40.2 19Q40.3 19 40.3 18.9V12.4Q40.3 12.3 40.2 12.2Q40.1 12.1 40 12.1H33.4Q33.2 12.1 33.2 12.2Q33.1 12.3 33.1 12.4V18.9Q33.1 19 33.2 19Q33.2 19.1 33.4 19.1ZM45.1 22V9.2H47.9V22ZM45.1 8V5.1H47.9V8ZM52.5 22Q51.7 22 51 21.6Q50.3 21.2 49.9 20.5Q49.5 19.8 49.5 19V12.3Q49.5 11.4 49.9 10.8Q50.3 10.1 51 9.7Q51.7 9.2 52.5 9.2H59.4Q60.2 9.2 60.9 9.7Q61.6 10.1 62 10.8Q62.4 11.4 62.4 12.3V19Q62.4 19.8 62 20.5Q61.6 21.2 60.9 21.6Q60.2 22 59.4 22H52.5ZM52.6 19.1H59.3Q59.4 19.1 59.5 19Q59.5 19 59.5 18.9V12.4Q59.5 12.3 59.5 12.2Q59.4 12.1 59.3 12.1H52.6Q52.5 12.1 52.4 12.2Q52.4 12.3 52.4 12.4V18.9Q52.4 19 52.4 19Q52.5 19.1 52.6 19.1Z"/><path d="M75.1 18.4Q74.1 18.4 73.4 17.8Q72.7 17.3 72.4 16.4L73.8 16Q73.9 16.5 74.3 16.8Q74.6 17.1 75.1 17.1Q75.4 17.1 75.7 16.9Q76.1 16.8 76.2 16.4Q76.3 16.2 76.4 15.9Q76.4 15.6 76.4 15.2V8.8H77.7V15.2Q77.7 15.6 77.7 15.9Q77.7 16.2 77.7 16.5Q77.6 16.8 77.4 17.1Q77.1 17.8 76.5 18.1Q75.9 18.4 75.1 18.4ZM82.8 18.4Q81.8 18.4 81 18Q80.2 17.7 79.7 17Q79.2 16.4 79 15.5L80.4 15.3Q80.6 16.1 81.3 16.6Q82 17.1 82.9 17.1Q83.5 17.1 84 16.9Q84.4 16.7 84.7 16.4Q85 16.1 85 15.6Q85 15.3 84.9 15.1Q84.8 14.9 84.7 14.8Q84.5 14.7 84.3 14.6Q84.1 14.4 83.8 14.4L81.4 13.7Q81.1 13.6 80.7 13.4Q80.4 13.2 80.1 13Q79.7 12.7 79.6 12.3Q79.4 11.9 79.4 11.3Q79.4 10.4 79.8 9.8Q80.3 9.2 81 8.9Q81.8 8.6 82.7 8.6Q83.7 8.6 84.4 9Q85.2 9.3 85.7 9.9Q86.2 10.5 86.4 11.4L84.9 11.6Q84.8 11.1 84.5 10.7Q84.2 10.3 83.7 10.1Q83.2 9.9 82.7 9.9Q82.2 9.9 81.8 10.1Q81.3 10.2 81.1 10.5Q80.8 10.8 80.8 11.2Q80.8 11.6 81 11.9Q81.3 12.1 81.6 12.3Q81.9 12.4 82.3 12.5L84 13Q84.3 13.1 84.7 13.2Q85.1 13.4 85.5 13.6Q85.9 13.9 86.2 14.4Q86.4 14.8 86.4 15.5Q86.4 16.2 86.1 16.7Q85.9 17.3 85.4 17.6Q84.9 18 84.2 18.2Q83.6 18.4 82.8 18.4Z" fill="none" stroke="currentColor" stroke-width=".8"/><rect x="68.9" y="5.5" width="21" height="16" fill="none" stroke="currentColor"/></svg></a>
<nav aria-label="audiojs"><a href="/util/">Utilities</a><a href="/lab/">Lab</a><a href="/audio/">audio</a><a href="/audio/playground.html">Playground</a><a class="site-gh" href="https://github.com/audiojs" aria-label="audiojs on GitHub"><svg aria-hidden="true" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C12.1381 15.0539 13.5182 14.0332 14.4958 12.6716C15.4735 11.3101 15.9996 9.6762 16 8C16 3.58 12.42 0 8 0Z"/></svg></a></nav>
</header>
<header>
<article class="cover" aria-label="audiojs · modular web audio toolkit">
<div class="top">
<div class="inner">
<div class="pro">For Professional Use</div>
<h1 class="wordmark">
<span class="name">audio</span>
<span class="js">JS</span>
</h1>
<div class="subtitle">Open Audio Stack</div>
<div class="freq">20-20k</div>
</div>
</div>
<div class="bot">
<div class="stripe-block" id="stripeBlock"
:scope="{
N:40,
rows:[Math.PI*1.5,Math.PI*0.5,Math.PI*1.5].map(off=>Array.from({length:40},(_,i)=>({ph:+(off+i/39*Math.PI).toFixed(4)})))
}"
:style="`--sn:${N}`"
aria-hidden="true">
<div class="stripe-row r-0">
<template :each="bar in rows[0]"><span :style="`--phase:${bar.ph}`">Z</span></template>
</div>
<div class="stripe-row r-1">
<template :each="bar in rows[1]"><span :style="`--phase:${bar.ph}`">Z</span></template>
</div>
<div class="stripe-row r-2">
<template :each="bar in rows[2]"><span :style="`--phase:${bar.ph}`">Z</span></template>
</div>
</div>
<div class="inner">
<div class="feats">
<div>Cross-Runtime</div>
<div>Modular Design</div>
<div>Standards Compliant</div>
</div>
<div class="stats">
<a href="https://www.npmjs.com/org/audio" target="_blank" rel="noopener" title="audiojs on npm"><span class="n">9M+</span><span class="l">npm downloads / month</span></a>
<a href="https://www.npmjs.com/org/audio" target="_blank" rel="noopener" title="the @audio packages on npm"><span class="n">300+</span><span class="l">open-source packages</span></a>
<a href="https://github.com/audiojs/web-audio-api" target="_blank" rel="noopener" title="maintained since 2016"><span class="n">2016</span><span class="l">maintained ever since</span></a>
</div>
<div class="bullets">
<div>ES Modules</div><div>Web Audio API</div><div>Sample-accurate</div>
</div>
<a class="seal" href="https://github.com/audiojs/web-audio-api/actions/workflows/wpt.yml" target="_blank" rel="noopener" title="web-audio-api passes every checked-in W3C Web Platform Test: the CI run" aria-label="web-audio-api W3C Web Platform Tests: view the CI run">
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="24" cy="24" r="24" fill="black"/>
<circle cx="24" cy="24" r="20.5" fill="black" stroke="white"/>
<path d="M3.72998 24.4174C9.11908 24.4174 9.98873 24.2988 12.735 18.2706C16.279 10.4913 18.92 9.67227 22.8177 24.4174C26.715 39.1609 29.8613 37.131 32.6572 28.3694C36.73 15.6062 37.803 24.4174 42.5662 24.4174C44.2699 24.4174 44.2699 24.4174 44.2699 24.4174" stroke="white"/>
<line x1="3.35498" y1="24.3584" x2="44.6444" y2="24.3584" stroke="white"/>
</svg>
</a>
<div class="caption">W3C WPT 100%</div>
</div>
</div>
</article>
</header>
<main>
<section class="intro" aria-label="What audiojs is">
<p>JavaScript packages for audio: decode, encode, measure, process, synthesize and play, the same code in the browser, Node, Deno and Bun.</p>
<div class="start"><code>npm i audio</code><a href="https://audio.js.org/">Docs and playground</a><a href="#util">Use the tools below</a></div>
</section>
<section class="tools" id="util" aria-label="Utilities">
<h2 class="t-label"><a href="/util/" style="color:inherit;text-decoration:none">Utilities</a></h2>
<ul><!-- utilities: written by scripts/util-pages.mjs from the pages list -->
<li><a href="/util/extract-audio/"><div class="t-name">Extract audio from video</div><div class="t-desc">Video → MP3, WAV, FLAC, M4A, ALAC, OGG, Opus, AAC</div></a></li>
<li><a href="/util/video-audio/"><div class="t-name">Remove or replace video audio</div><div class="t-desc">Strip the audio track, or swap in AAC, Opus, ALAC or FLAC — the video is never re-encoded</div></a></li>
<li><a href="/util/convert-audio/"><div class="t-name">Audio converter</div><div class="t-desc">MP3, WAV, FLAC, M4A, ALAC, WavPack, OGG, Opus, AAC, AIFF, CAF, WebM, QOA; reads APE, TTA, Musepack, DSD, tracker modules too</div></a></li>
<li><a href="/util/loudness/"><div class="t-name">Loudness meter and normalizer</div><div class="t-desc">LUFS, true peak, loudness range; normalize for Spotify, YouTube, podcasts</div></a></li>
<li><a href="/util/denoise/"><div class="t-name">Noise remover</div><div class="t-desc">Background noise, hum, clicks, wind, plosives, reverb</div></a></li>
<li><a href="/util/desilence/"><div class="t-name">Remove silence from audio</div><div class="t-desc">Podcast smart speed, silence removal, trim start/end — voice activity detection</div></a></li>
<li><a href="/util/dewow/"><div class="t-name">Wow and flutter fixer</div><div class="t-desc">Correct slow pitch drift and fast wobble in tape, cassette and vinyl transfers</div></a></li>
<li><a href="/util/transcribe/"><div class="t-name">Transcribe audio to text and subtitles</div><div class="t-desc">Whisper speech-to-text; TXT, SRT, VTT; sentence or word timestamps</div></a></li>
<li><a href="/util/key-bpm/"><div class="t-name">Key and BPM finder</div><div class="t-desc">Musical key, Camelot code, tempo, chords</div></a></li>
<li><a href="/util/vocal-remover/"><div class="t-name">Vocal remover</div><div class="t-desc">Karaoke track or isolated vocal, by a trained model (SCNet, Mel-Band RoFormer) or mid/side</div></a></li>
<li><a href="/util/stem-splitter/"><div class="t-name">Stem splitter</div><div class="t-desc">Vocals, drums, bass and other from any song, by the SCNet model; play, mute, solo, rebalance, save</div></a></li>
<li><a href="/util/pitch-tempo/"><div class="t-name">Pitch and tempo changer</div><div class="t-desc">Transpose semitones, change speed without changing pitch</div></a></li>
<li><a href="/util/midi-to-mp3/"><div class="t-name">MIDI to MP3</div><div class="t-desc">Render a MIDI file with a synth-GM instrument set, no soundfont</div></a></li>
<li><a href="/util/audio-to-midi/"><div class="t-name">Audio to MIDI converter</div><div class="t-desc">Songs, chords, piano, guitar or voice to MIDI, MusicXML and ABC, with Spotify’s Basic Pitch</div></a></li>
<li><a href="/util/tuner/"><div class="t-name">Tuner</div><div class="t-desc">Chromatic tuner for guitar, bass, violin, voice</div></a></li>
<li><a href="/util/tone-generator/"><div class="t-name">Tone generator</div><div class="t-desc">Sine, square, sawtooth and triangle tones, binaural beats, harmonics, noise, sweeps; save as WAV</div></a></li>
<li><a href="/util/prosody/"><div class="t-name">Speech prosody editor</div><div class="t-desc">Move syllables to notes, straighten or smooth intonation, change phrase timing</div></a></li>
<li><a href="/util/recorder/"><div class="t-name">Audio recorder</div><div class="t-desc">Record from the microphone, save as MP3, WAV, FLAC, Opus</div></a></li>
<li><a href="/util/lossless-check/"><div class="t-name">Lossless audio checker</div><div class="t-desc">Detect a fake lossless FLAC or WAV: spectral cutoff, edge sharpness, spectral holes</div></a></li>
<li><a href="/util/spectrogram/"><div class="t-name">Spectrogram</div><div class="t-desc">Frequency-over-time image of any recording</div></a></li>
<li><a href="/util/measure/"><div class="t-name">Room and speaker measurement</div><div class="t-desc">Frequency response, reverb time (RT60), latency, via a sine sweep</div></a></li>
<li><a href="/util/latency/"><div class="t-name">Audio latency test</div><div class="t-desc">Round-trip delay from speaker to microphone, and the Bluetooth delay you hear</div></a></li>
<!-- /utilities -->
</ul>
</section>
<section class="tools" id="lab" aria-label="Lab">
<h2 class="t-label"><a href="/lab/" style="color:inherit;text-decoration:none">Lab</a></h2>
<ul>
<li><a href="/lab/words-under-the-waveform/"><div class="t-name">How do you set words under a waveform?</div><div class="t-desc">Words under their sound, with help from typesetting and music engraving</div></a></li>
<li><a href="/lab/waveform/"><div class="t-name">Drawing a waveform</div><div class="t-desc">Every Nth sample, lowest and highest, RMS, brightness by level, true peaks, decibels, colour, stereo</div></a></li>
<li><a href="/lab/spectrogram/"><div class="t-name">Seeing sound</div><div class="t-desc">Frames, windows, frequency axes, colour maps, reassignment, many resolutions, multitapers, Wigner–Ville</div></a></li>
<li><a href="/lab/scrub/"><div class="t-name">Hearing a moment</div><div class="t-desc">Tape, loops, grains, noiscillators, random phase, phase vocoders: what a held caret plays, and what it costs</div></a></li>
<li><a href="/lab/layout/"><div class="t-name">Where the panels go</div><div class="t-desc">Splits, docks, activity bars, inspectors, tabs, floating windows: seven layouts of one audio editor, and the one to keep</div></a></li>
<li><a href="/lab/audio-in-javascript/"><div class="t-name">Audio in JavaScript</div><div class="t-desc">new Audio(), a Web Audio equalizer, files in and out, Node.js, and which library fits which job</div></a></li>
<li><a href="/lab/recording/"><div class="t-name">Recording audio in the browser</div><div class="t-desc">getUserMedia, the formats MediaRecorder gives your browser, every sample to a WAV, latency</div></a></li>
<li><a href="/lab/auditory-illusions/"><div class="t-name">Hearing what isn't there</div><div class="t-desc">Shepard tones, the Risset rhythm, Deutsch's scale illusion, binaural beats, the missing fundamental</div></a></li>
</ul>
</section>
<section class="sponsors" id="sponsors" aria-label="Sponsors">
<div class="s-label">Sponsors</div>
<div class="s-logos"></div>
<div class="s-note">Maintenance is funded by sponsorship — <a href="https://github.com/sponsors/audiojs" target="_blank" rel="noopener">become a sponsor</a> · <a href="/funding.json">Funding details</a></div>
</section>
</main>
<footer></footer>
<!-- <a href="https://github.com/krishnized/license" style="position: fixed; bottom: 1rem; right: 1rem; color: var(--ink); text-decoration: none; font-size: 1.25rem; line-height: 1; opacity: 0.5;" target="_blank" rel="noopener" title="krishnized license">ॐ</a> -->
<script>
const init = () => {
const el = document.getElementById('stripeBlock');
const ss = [...el.querySelectorAll('.stripe-row span')];
if (!ss.length) { requestAnimationFrame(init); return; }
const spans = ss.map(s => ({ s, ph: parseFloat(s.style.getPropertyValue('--phase')) || 0 }));
const wmax = 380, P = Math.PI;
let t = 0, last = null, dragging = false, dragX = 0, visible = true;
const tick = now => {
const dt = last ? (now - last) / 1000 : 0; last = now;
if (visible && !dragging) {
t += dt * P * 0.5;
spans.forEach(({ s, ph }) => {
const wt = wmax / 2 * (1 + Math.sin(ph + t));
s.style.fontVariationSettings = `'ROND' 0,'YELA' 0,'wght' ${Math.max(1, wt) | 0}`;
});
}
requestAnimationFrame(tick);
};
// pause when tab hidden or block scrolled off-screen
document.addEventListener('visibilitychange', () => { visible = !document.hidden; last = null; });
new IntersectionObserver(([e]) => { visible = e.isIntersecting; last = null; }).observe(el);
el.addEventListener('pointerenter', () => { visible = false; });
el.addEventListener('pointerleave', () => { if (!dragging) { visible = true; last = null; } });
el.addEventListener('pointerdown', e => { dragging = true; dragX = e.clientX; el.setPointerCapture(e.pointerId); });
el.addEventListener('pointermove', e => {
if (!dragging) return;
t -= (e.clientX - dragX) / el.getBoundingClientRect().width * P * 2;
dragX = e.clientX;
spans.forEach(({ s, ph }) => {
const wt = wmax / 2 * (1 + Math.sin(ph + t));
s.style.fontVariationSettings = `'ROND' 0,'YELA' 0,'wght' ${Math.max(1, wt) | 0}`;
});
});
el.addEventListener('pointerup', () => { dragging = false; last = null; });
document.fonts.ready.then(() => el.style.opacity = 1);
tick(performance.now());
};
requestAnimationFrame(init);
</script>
</html>