@akshatbuilds/sonix 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +123 -0
- package/app/globals.css +110 -0
- package/app/layout.tsx +54 -0
- package/app/page.tsx +40 -0
- package/app/usage/page.tsx +9 -0
- package/cli/index.mjs +151 -0
- package/components/sound-card.tsx +595 -0
- package/components/sounds-gallery.tsx +137 -0
- package/components/theme-provider.tsx +11 -0
- package/components/theme-toggle.tsx +82 -0
- package/components/ui/button.tsx +57 -0
- package/components/ui/checkbox.tsx +30 -0
- package/components/ui/slider.tsx +28 -0
- package/components/ui/switch.tsx +29 -0
- package/components/ui/tooltip.tsx +30 -0
- package/components/usage-guide.tsx +155 -0
- package/components.json +21 -0
- package/lib/sounds.ts +329 -0
- package/lib/utils.ts +6 -0
- package/next-env.d.ts +6 -0
- package/next.config.mjs +5 -0
- package/package.json +96 -0
- package/postcss.config.mjs +8 -0
- package/public/click1.mp3 +0 -0
- package/public/click2.mp3 +0 -0
- package/public/registry/index.json +92 -0
- package/public/registry/sounds/button-click-secondary.json +13 -0
- package/public/registry/sounds/button-click.json +13 -0
- package/public/registry/sounds/error-beep.json +10 -0
- package/public/registry/sounds/error-buzz.json +10 -0
- package/public/registry/sounds/hover-blip.json +10 -0
- package/public/registry/sounds/hover-soft.json +10 -0
- package/public/registry/sounds/key-press.json +10 -0
- package/public/registry/sounds/notification-ping.json +10 -0
- package/public/registry/sounds/notification-subtle.json +10 -0
- package/public/registry/sounds/pop.json +10 -0
- package/public/registry/sounds/slider-tick.json +10 -0
- package/public/registry/sounds/success-bell.json +10 -0
- package/public/registry/sounds/success-chime.json +10 -0
- package/public/registry/sounds/swoosh.json +10 -0
- package/scripts/build-registry.mjs +293 -0
- package/tailwind.config.ts +100 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pop",
|
|
3
|
+
"type": "webaudio",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"name": "pop.ts",
|
|
7
|
+
"content": "export function playPop() {\n const ctx = new AudioContext();\n const now = ctx.currentTime;\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.type = 'sine';\n osc.frequency.setValueAtTime(950, now);\n osc.frequency.exponentialRampToValueAtTime(150, now + 0.08);\n gain.gain.setValueAtTime(0.35, now);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.08);\n osc.connect(gain).connect(ctx.destination);\n osc.start(now);\n osc.stop(now + 0.08);\n}"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "slider-tick",
|
|
3
|
+
"type": "webaudio",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"name": "slider-tick.ts",
|
|
7
|
+
"content": "export function playSliderTick() {\n const ctx = new AudioContext();\n const now = ctx.currentTime;\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.type = 'square';\n osc.frequency.setValueAtTime(5000, now);\n osc.frequency.exponentialRampToValueAtTime(1200, now + 0.005);\n gain.gain.setValueAtTime(0.08, now);\n gain.gain.exponentialRampToValueAtTime(0.001, now + 0.01);\n osc.connect(gain).connect(ctx.destination);\n osc.start(now);\n osc.stop(now + 0.01);\n}"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "success-bell",
|
|
3
|
+
"type": "webaudio",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"name": "success-bell.ts",
|
|
7
|
+
"content": "export function playSuccessBell() {\n const ctx = new AudioContext();\n const now = ctx.currentTime;\n [1000, 1250, 1500].forEach((freq, i) => {\n const osc = ctx.createOscillator();\n const gain = ctx.createGain();\n osc.type = 'sine';\n osc.frequency.setValueAtTime(freq, now + i * 0.08);\n gain.gain.setValueAtTime(0.001, now);\n gain.gain.setValueAtTime(0.2, now + i * 0.08);\n gain.gain.exponentialRampToValueAtTime(0.001, now + i * 0.08 + 0.15);\n osc.connect(gain).connect(ctx.destination);\n osc.start(now + i * 0.08);\n osc.stop(now + i * 0.08 + 0.15);\n });\n}"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "success-chime",
|
|
3
|
+
"type": "webaudio",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"name": "success-chime.ts",
|
|
7
|
+
"content": "export function playSuccessChime() {\n const ctx = new AudioContext();\n const now = ctx.currentTime;\n const osc1 = ctx.createOscillator();\n const gain1 = ctx.createGain();\n osc1.type = 'sine';\n osc1.frequency.setValueAtTime(800, now);\n gain1.gain.setValueAtTime(0.25, now);\n gain1.gain.exponentialRampToValueAtTime(0.001, now + 0.15);\n osc1.connect(gain1).connect(ctx.destination);\n osc1.start(now);\n osc1.stop(now + 0.15);\n const osc2 = ctx.createOscillator();\n const gain2 = ctx.createGain();\n osc2.type = 'sine';\n osc2.frequency.setValueAtTime(1200, now + 0.1);\n gain2.gain.setValueAtTime(0.001, now);\n gain2.gain.setValueAtTime(0.25, now + 0.1);\n gain2.gain.exponentialRampToValueAtTime(0.001, now + 0.3);\n osc2.connect(gain2).connect(ctx.destination);\n osc2.start(now + 0.1);\n osc2.stop(now + 0.3);\n}"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "swoosh",
|
|
3
|
+
"type": "webaudio",
|
|
4
|
+
"files": [
|
|
5
|
+
{
|
|
6
|
+
"name": "swoosh.ts",
|
|
7
|
+
"content": "export function playSwoosh() {\n const ctx = new AudioContext();\n const now = ctx.currentTime;\n const bufferSize = Math.floor(ctx.sampleRate * 0.4);\n const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;\n const noise = ctx.createBufferSource();\n noise.buffer = buffer;\n const lp = ctx.createBiquadFilter();\n lp.type = 'lowpass';\n lp.frequency.setValueAtTime(350, now);\n lp.frequency.linearRampToValueAtTime(500, now + 0.15);\n lp.frequency.linearRampToValueAtTime(250, now + 0.38);\n lp.Q.setValueAtTime(0.5, now);\n const noiseGain = ctx.createGain();\n noiseGain.gain.setValueAtTime(0.001, now);\n noiseGain.gain.linearRampToValueAtTime(0.06, now + 0.16);\n noiseGain.gain.linearRampToValueAtTime(0.05, now + 0.24);\n noiseGain.gain.exponentialRampToValueAtTime(0.001, now + 0.38);\n noise.connect(lp).connect(noiseGain).connect(ctx.destination);\n noise.start(now);\n noise.stop(now + 0.4);\n}"
|
|
8
|
+
}
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
2
|
+
import { resolve, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
6
|
+
|
|
7
|
+
// Read sound snippets from sounds.ts to generate registry sound files
|
|
8
|
+
// Each sound gets its own JSON file under public/registry/sounds/
|
|
9
|
+
|
|
10
|
+
const soundSnippets = {
|
|
11
|
+
"hover-blip": `export function playHoverBlip() {
|
|
12
|
+
const ctx = new AudioContext();
|
|
13
|
+
const now = ctx.currentTime;
|
|
14
|
+
const osc = ctx.createOscillator();
|
|
15
|
+
const gain = ctx.createGain();
|
|
16
|
+
osc.type = 'sine';
|
|
17
|
+
osc.frequency.setValueAtTime(1200, now);
|
|
18
|
+
osc.frequency.exponentialRampToValueAtTime(2400, now + 0.05);
|
|
19
|
+
gain.gain.setValueAtTime(0.15, now);
|
|
20
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.05);
|
|
21
|
+
osc.connect(gain).connect(ctx.destination);
|
|
22
|
+
osc.start(now);
|
|
23
|
+
osc.stop(now + 0.05);
|
|
24
|
+
}`,
|
|
25
|
+
"hover-soft": `export function playHoverSoft() {
|
|
26
|
+
const ctx = new AudioContext();
|
|
27
|
+
const now = ctx.currentTime;
|
|
28
|
+
const osc = ctx.createOscillator();
|
|
29
|
+
const gain = ctx.createGain();
|
|
30
|
+
osc.type = 'sine';
|
|
31
|
+
osc.frequency.setValueAtTime(900, now);
|
|
32
|
+
gain.gain.setValueAtTime(0.08, now);
|
|
33
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.06);
|
|
34
|
+
osc.connect(gain).connect(ctx.destination);
|
|
35
|
+
osc.start(now);
|
|
36
|
+
osc.stop(now + 0.06);
|
|
37
|
+
}`,
|
|
38
|
+
"success-chime": `export function playSuccessChime() {
|
|
39
|
+
const ctx = new AudioContext();
|
|
40
|
+
const now = ctx.currentTime;
|
|
41
|
+
const osc1 = ctx.createOscillator();
|
|
42
|
+
const gain1 = ctx.createGain();
|
|
43
|
+
osc1.type = 'sine';
|
|
44
|
+
osc1.frequency.setValueAtTime(800, now);
|
|
45
|
+
gain1.gain.setValueAtTime(0.25, now);
|
|
46
|
+
gain1.gain.exponentialRampToValueAtTime(0.001, now + 0.15);
|
|
47
|
+
osc1.connect(gain1).connect(ctx.destination);
|
|
48
|
+
osc1.start(now);
|
|
49
|
+
osc1.stop(now + 0.15);
|
|
50
|
+
const osc2 = ctx.createOscillator();
|
|
51
|
+
const gain2 = ctx.createGain();
|
|
52
|
+
osc2.type = 'sine';
|
|
53
|
+
osc2.frequency.setValueAtTime(1200, now + 0.1);
|
|
54
|
+
gain2.gain.setValueAtTime(0.001, now);
|
|
55
|
+
gain2.gain.setValueAtTime(0.25, now + 0.1);
|
|
56
|
+
gain2.gain.exponentialRampToValueAtTime(0.001, now + 0.3);
|
|
57
|
+
osc2.connect(gain2).connect(ctx.destination);
|
|
58
|
+
osc2.start(now + 0.1);
|
|
59
|
+
osc2.stop(now + 0.3);
|
|
60
|
+
}`,
|
|
61
|
+
"success-bell": `export function playSuccessBell() {
|
|
62
|
+
const ctx = new AudioContext();
|
|
63
|
+
const now = ctx.currentTime;
|
|
64
|
+
[1000, 1250, 1500].forEach((freq, i) => {
|
|
65
|
+
const osc = ctx.createOscillator();
|
|
66
|
+
const gain = ctx.createGain();
|
|
67
|
+
osc.type = 'sine';
|
|
68
|
+
osc.frequency.setValueAtTime(freq, now + i * 0.08);
|
|
69
|
+
gain.gain.setValueAtTime(0.001, now);
|
|
70
|
+
gain.gain.setValueAtTime(0.2, now + i * 0.08);
|
|
71
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + i * 0.08 + 0.15);
|
|
72
|
+
osc.connect(gain).connect(ctx.destination);
|
|
73
|
+
osc.start(now + i * 0.08);
|
|
74
|
+
osc.stop(now + i * 0.08 + 0.15);
|
|
75
|
+
});
|
|
76
|
+
}`,
|
|
77
|
+
"error-buzz": `export function playErrorBuzz() {
|
|
78
|
+
const ctx = new AudioContext();
|
|
79
|
+
const now = ctx.currentTime;
|
|
80
|
+
const osc = ctx.createOscillator();
|
|
81
|
+
const gain = ctx.createGain();
|
|
82
|
+
osc.type = 'sawtooth';
|
|
83
|
+
osc.frequency.setValueAtTime(150, now);
|
|
84
|
+
gain.gain.setValueAtTime(0.2, now);
|
|
85
|
+
gain.gain.setValueAtTime(0.001, now + 0.08);
|
|
86
|
+
gain.gain.setValueAtTime(0.2, now + 0.1);
|
|
87
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.2);
|
|
88
|
+
osc.connect(gain).connect(ctx.destination);
|
|
89
|
+
osc.start(now);
|
|
90
|
+
osc.stop(now + 0.2);
|
|
91
|
+
}`,
|
|
92
|
+
"error-beep": `export function playErrorBeep() {
|
|
93
|
+
const ctx = new AudioContext();
|
|
94
|
+
const now = ctx.currentTime;
|
|
95
|
+
[500, 350].forEach((freq, i) => {
|
|
96
|
+
const osc = ctx.createOscillator();
|
|
97
|
+
const gain = ctx.createGain();
|
|
98
|
+
osc.type = 'square';
|
|
99
|
+
osc.frequency.setValueAtTime(freq, now + i * 0.12);
|
|
100
|
+
gain.gain.setValueAtTime(0.001, now);
|
|
101
|
+
gain.gain.setValueAtTime(0.15, now + i * 0.12);
|
|
102
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + i * 0.12 + 0.1);
|
|
103
|
+
osc.connect(gain).connect(ctx.destination);
|
|
104
|
+
osc.start(now + i * 0.12);
|
|
105
|
+
osc.stop(now + i * 0.12 + 0.1);
|
|
106
|
+
});
|
|
107
|
+
}`,
|
|
108
|
+
"notification-ping": `export function playNotificationPing() {
|
|
109
|
+
const ctx = new AudioContext();
|
|
110
|
+
const now = ctx.currentTime;
|
|
111
|
+
const osc = ctx.createOscillator();
|
|
112
|
+
const gain = ctx.createGain();
|
|
113
|
+
osc.type = 'sine';
|
|
114
|
+
osc.frequency.setValueAtTime(1100, now);
|
|
115
|
+
osc.frequency.exponentialRampToValueAtTime(1800, now + 0.05);
|
|
116
|
+
osc.frequency.exponentialRampToValueAtTime(1100, now + 0.1);
|
|
117
|
+
gain.gain.setValueAtTime(0.25, now);
|
|
118
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.15);
|
|
119
|
+
osc.connect(gain).connect(ctx.destination);
|
|
120
|
+
osc.start(now);
|
|
121
|
+
osc.stop(now + 0.15);
|
|
122
|
+
}`,
|
|
123
|
+
"notification-subtle": `export function playNotificationSubtle() {
|
|
124
|
+
const ctx = new AudioContext();
|
|
125
|
+
const now = ctx.currentTime;
|
|
126
|
+
const osc = ctx.createOscillator();
|
|
127
|
+
const gain = ctx.createGain();
|
|
128
|
+
osc.type = 'sine';
|
|
129
|
+
osc.frequency.setValueAtTime(700, now);
|
|
130
|
+
gain.gain.setValueAtTime(0.1, now);
|
|
131
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.12);
|
|
132
|
+
osc.connect(gain).connect(ctx.destination);
|
|
133
|
+
osc.start(now);
|
|
134
|
+
osc.stop(now + 0.12);
|
|
135
|
+
}`,
|
|
136
|
+
swoosh: `export function playSwoosh() {
|
|
137
|
+
const ctx = new AudioContext();
|
|
138
|
+
const now = ctx.currentTime;
|
|
139
|
+
const bufferSize = Math.floor(ctx.sampleRate * 0.4);
|
|
140
|
+
const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
|
|
141
|
+
const data = buffer.getChannelData(0);
|
|
142
|
+
for (let i = 0; i < bufferSize; i++) data[i] = Math.random() * 2 - 1;
|
|
143
|
+
const noise = ctx.createBufferSource();
|
|
144
|
+
noise.buffer = buffer;
|
|
145
|
+
const lp = ctx.createBiquadFilter();
|
|
146
|
+
lp.type = 'lowpass';
|
|
147
|
+
lp.frequency.setValueAtTime(350, now);
|
|
148
|
+
lp.frequency.linearRampToValueAtTime(500, now + 0.15);
|
|
149
|
+
lp.frequency.linearRampToValueAtTime(250, now + 0.38);
|
|
150
|
+
lp.Q.setValueAtTime(0.5, now);
|
|
151
|
+
const noiseGain = ctx.createGain();
|
|
152
|
+
noiseGain.gain.setValueAtTime(0.001, now);
|
|
153
|
+
noiseGain.gain.linearRampToValueAtTime(0.06, now + 0.16);
|
|
154
|
+
noiseGain.gain.linearRampToValueAtTime(0.05, now + 0.24);
|
|
155
|
+
noiseGain.gain.exponentialRampToValueAtTime(0.001, now + 0.38);
|
|
156
|
+
noise.connect(lp).connect(noiseGain).connect(ctx.destination);
|
|
157
|
+
noise.start(now);
|
|
158
|
+
noise.stop(now + 0.4);
|
|
159
|
+
}`,
|
|
160
|
+
pop: `export function playPop() {
|
|
161
|
+
const ctx = new AudioContext();
|
|
162
|
+
const now = ctx.currentTime;
|
|
163
|
+
const osc = ctx.createOscillator();
|
|
164
|
+
const gain = ctx.createGain();
|
|
165
|
+
osc.type = 'sine';
|
|
166
|
+
osc.frequency.setValueAtTime(950, now);
|
|
167
|
+
osc.frequency.exponentialRampToValueAtTime(150, now + 0.08);
|
|
168
|
+
gain.gain.setValueAtTime(0.35, now);
|
|
169
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.08);
|
|
170
|
+
osc.connect(gain).connect(ctx.destination);
|
|
171
|
+
osc.start(now);
|
|
172
|
+
osc.stop(now + 0.08);
|
|
173
|
+
}`,
|
|
174
|
+
"slider-tick": `export function playSliderTick() {
|
|
175
|
+
const ctx = new AudioContext();
|
|
176
|
+
const now = ctx.currentTime;
|
|
177
|
+
const osc = ctx.createOscillator();
|
|
178
|
+
const gain = ctx.createGain();
|
|
179
|
+
osc.type = 'square';
|
|
180
|
+
osc.frequency.setValueAtTime(5000, now);
|
|
181
|
+
osc.frequency.exponentialRampToValueAtTime(1200, now + 0.005);
|
|
182
|
+
gain.gain.setValueAtTime(0.08, now);
|
|
183
|
+
gain.gain.exponentialRampToValueAtTime(0.001, now + 0.01);
|
|
184
|
+
osc.connect(gain).connect(ctx.destination);
|
|
185
|
+
osc.start(now);
|
|
186
|
+
osc.stop(now + 0.01);
|
|
187
|
+
}`,
|
|
188
|
+
"key-press": `export function playKeyPress() {
|
|
189
|
+
const ctx = new AudioContext();
|
|
190
|
+
const now = ctx.currentTime;
|
|
191
|
+
// Lubed Cherry MX Brown — deep muted thock, no click
|
|
192
|
+
const v = () => 0.94 + Math.random() * 0.12;
|
|
193
|
+
const drift = Math.random() * 0.0015;
|
|
194
|
+
// Layer 1: bottom-out thock (main sound)
|
|
195
|
+
const thud = ctx.createOscillator();
|
|
196
|
+
const thudGain = ctx.createGain();
|
|
197
|
+
const thudFilter = ctx.createBiquadFilter();
|
|
198
|
+
thud.type = 'sine';
|
|
199
|
+
thud.frequency.setValueAtTime(95 * v(), now + drift);
|
|
200
|
+
thud.frequency.exponentialRampToValueAtTime(38, now + drift + 0.04);
|
|
201
|
+
thudFilter.type = 'lowpass';
|
|
202
|
+
thudFilter.frequency.setValueAtTime(300, now + drift);
|
|
203
|
+
thudFilter.Q.setValueAtTime(0.5, now + drift);
|
|
204
|
+
thudGain.gain.setValueAtTime(0.22, now + drift);
|
|
205
|
+
thudGain.gain.exponentialRampToValueAtTime(0.001, now + drift + 0.055);
|
|
206
|
+
thud.connect(thudFilter).connect(thudGain).connect(ctx.destination);
|
|
207
|
+
thud.start(now + drift); thud.stop(now + drift + 0.06);
|
|
208
|
+
// Layer 2: tactile bump (barely audible)
|
|
209
|
+
const bump = ctx.createOscillator();
|
|
210
|
+
const bumpGain = ctx.createGain();
|
|
211
|
+
const bumpFilter = ctx.createBiquadFilter();
|
|
212
|
+
bump.type = 'triangle';
|
|
213
|
+
bump.frequency.setValueAtTime(420 * v(), now);
|
|
214
|
+
bump.frequency.exponentialRampToValueAtTime(180, now + 0.008);
|
|
215
|
+
bumpFilter.type = 'lowpass';
|
|
216
|
+
bumpFilter.frequency.setValueAtTime(600, now);
|
|
217
|
+
bumpGain.gain.setValueAtTime(0.03, now);
|
|
218
|
+
bumpGain.gain.exponentialRampToValueAtTime(0.001, now + 0.012);
|
|
219
|
+
bump.connect(bumpFilter).connect(bumpGain).connect(ctx.destination);
|
|
220
|
+
bump.start(now); bump.stop(now + 0.012);
|
|
221
|
+
// Layer 3: dampened noise (soft low puff)
|
|
222
|
+
const bufLen = Math.floor(ctx.sampleRate * 0.03);
|
|
223
|
+
const buf = ctx.createBuffer(1, bufLen, ctx.sampleRate);
|
|
224
|
+
const d = buf.getChannelData(0);
|
|
225
|
+
for (let i = 0; i < bufLen; i++) d[i] = Math.random() * 2 - 1;
|
|
226
|
+
const noise = ctx.createBufferSource();
|
|
227
|
+
noise.buffer = buf;
|
|
228
|
+
const noiseLp = ctx.createBiquadFilter();
|
|
229
|
+
noiseLp.type = 'lowpass';
|
|
230
|
+
noiseLp.frequency.setValueAtTime(400 * v(), now + drift);
|
|
231
|
+
noiseLp.Q.setValueAtTime(0.3, now + drift);
|
|
232
|
+
const noiseGain = ctx.createGain();
|
|
233
|
+
noiseGain.gain.setValueAtTime(0.025, now + drift);
|
|
234
|
+
noiseGain.gain.exponentialRampToValueAtTime(0.001, now + drift + 0.025);
|
|
235
|
+
noise.connect(noiseLp).connect(noiseGain).connect(ctx.destination);
|
|
236
|
+
noise.start(now + drift); noise.stop(now + drift + 0.03);
|
|
237
|
+
}`,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Generate individual JSON files for each sound
|
|
241
|
+
const outDir = resolve(__dirname, "..", "public", "registry", "sounds");
|
|
242
|
+
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
|
|
243
|
+
|
|
244
|
+
for (const [name, code] of Object.entries(soundSnippets)) {
|
|
245
|
+
const json = JSON.stringify(
|
|
246
|
+
{
|
|
247
|
+
name,
|
|
248
|
+
type: "webaudio",
|
|
249
|
+
files: [{ name: `${name}.ts`, content: code }],
|
|
250
|
+
},
|
|
251
|
+
null,
|
|
252
|
+
2
|
|
253
|
+
);
|
|
254
|
+
writeFileSync(join(outDir, `${name}.json`), json + "\n");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// MP3 sounds (these reference files, not code)
|
|
258
|
+
const mp3Sounds = [
|
|
259
|
+
{
|
|
260
|
+
name: "button-click",
|
|
261
|
+
file: "click1.mp3",
|
|
262
|
+
code: `// Requires click1.mp3 in your public folder
|
|
263
|
+
const audio = new Audio('/click1.mp3');
|
|
264
|
+
audio.volume = 0.5;
|
|
265
|
+
audio.play();`,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "button-click-secondary",
|
|
269
|
+
file: "click2.mp3",
|
|
270
|
+
code: `// Requires click2.mp3 in your public folder
|
|
271
|
+
const audio = new Audio('/click2.mp3');
|
|
272
|
+
audio.volume = 0.5;
|
|
273
|
+
audio.play();`,
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
for (const sound of mp3Sounds) {
|
|
278
|
+
const json = JSON.stringify(
|
|
279
|
+
{
|
|
280
|
+
name: sound.name,
|
|
281
|
+
type: "mp3",
|
|
282
|
+
files: [
|
|
283
|
+
{ name: `${sound.name}.ts`, content: `export function play() {\n${sound.code}\n}` },
|
|
284
|
+
],
|
|
285
|
+
assets: [sound.file],
|
|
286
|
+
},
|
|
287
|
+
null,
|
|
288
|
+
2
|
|
289
|
+
);
|
|
290
|
+
writeFileSync(join(outDir, `${sound.name}.json`), json + "\n");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(`✅ Generated ${Object.keys(soundSnippets).length + mp3Sounds.length} sound registry files in public/registry/sounds/`);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { Config } from 'tailwindcss'
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
darkMode: ['class'],
|
|
5
|
+
content: [
|
|
6
|
+
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
|
7
|
+
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
|
8
|
+
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
|
9
|
+
'*.{js,ts,jsx,tsx,mdx}',
|
|
10
|
+
],
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {
|
|
13
|
+
fontFamily: {
|
|
14
|
+
sans: ['var(--font-geist)', 'system-ui', 'sans-serif'],
|
|
15
|
+
mono: ['var(--font-geist-mono)', 'monospace'],
|
|
16
|
+
},
|
|
17
|
+
colors: {
|
|
18
|
+
background: 'hsl(var(--background))',
|
|
19
|
+
foreground: 'hsl(var(--foreground))',
|
|
20
|
+
card: {
|
|
21
|
+
DEFAULT: 'hsl(var(--card))',
|
|
22
|
+
foreground: 'hsl(var(--card-foreground))',
|
|
23
|
+
},
|
|
24
|
+
popover: {
|
|
25
|
+
DEFAULT: 'hsl(var(--popover))',
|
|
26
|
+
foreground: 'hsl(var(--popover-foreground))',
|
|
27
|
+
},
|
|
28
|
+
primary: {
|
|
29
|
+
DEFAULT: 'hsl(var(--primary))',
|
|
30
|
+
foreground: 'hsl(var(--primary-foreground))',
|
|
31
|
+
},
|
|
32
|
+
secondary: {
|
|
33
|
+
DEFAULT: 'hsl(var(--secondary))',
|
|
34
|
+
foreground: 'hsl(var(--secondary-foreground))',
|
|
35
|
+
},
|
|
36
|
+
muted: {
|
|
37
|
+
DEFAULT: 'hsl(var(--muted))',
|
|
38
|
+
foreground: 'hsl(var(--muted-foreground))',
|
|
39
|
+
},
|
|
40
|
+
accent: {
|
|
41
|
+
DEFAULT: 'hsl(var(--accent))',
|
|
42
|
+
foreground: 'hsl(var(--accent-foreground))',
|
|
43
|
+
},
|
|
44
|
+
destructive: {
|
|
45
|
+
DEFAULT: 'hsl(var(--destructive))',
|
|
46
|
+
foreground: 'hsl(var(--destructive-foreground))',
|
|
47
|
+
},
|
|
48
|
+
border: 'hsl(var(--border))',
|
|
49
|
+
input: 'hsl(var(--input))',
|
|
50
|
+
ring: 'hsl(var(--ring))',
|
|
51
|
+
chart: {
|
|
52
|
+
'1': 'hsl(var(--chart-1))',
|
|
53
|
+
'2': 'hsl(var(--chart-2))',
|
|
54
|
+
'3': 'hsl(var(--chart-3))',
|
|
55
|
+
'4': 'hsl(var(--chart-4))',
|
|
56
|
+
'5': 'hsl(var(--chart-5))',
|
|
57
|
+
},
|
|
58
|
+
sidebar: {
|
|
59
|
+
DEFAULT: 'hsl(var(--sidebar-background))',
|
|
60
|
+
foreground: 'hsl(var(--sidebar-foreground))',
|
|
61
|
+
primary: 'hsl(var(--sidebar-primary))',
|
|
62
|
+
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
|
|
63
|
+
accent: 'hsl(var(--sidebar-accent))',
|
|
64
|
+
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
|
|
65
|
+
border: 'hsl(var(--sidebar-border))',
|
|
66
|
+
ring: 'hsl(var(--sidebar-ring))',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
borderRadius: {
|
|
70
|
+
lg: 'var(--radius)',
|
|
71
|
+
md: 'calc(var(--radius) - 2px)',
|
|
72
|
+
sm: 'calc(var(--radius) - 4px)',
|
|
73
|
+
},
|
|
74
|
+
keyframes: {
|
|
75
|
+
'accordion-down': {
|
|
76
|
+
from: {
|
|
77
|
+
height: '0',
|
|
78
|
+
},
|
|
79
|
+
to: {
|
|
80
|
+
height: 'var(--radix-accordion-content-height)',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
'accordion-up': {
|
|
84
|
+
from: {
|
|
85
|
+
height: 'var(--radix-accordion-content-height)',
|
|
86
|
+
},
|
|
87
|
+
to: {
|
|
88
|
+
height: '0',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
animation: {
|
|
93
|
+
'accordion-down': 'accordion-down 0.2s ease-out',
|
|
94
|
+
'accordion-up': 'accordion-up 0.2s ease-out',
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
plugins: [require('tailwindcss-animate')],
|
|
99
|
+
}
|
|
100
|
+
export default config
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
4
|
+
"allowJs": true,
|
|
5
|
+
"target": "ES6",
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"next-env.d.ts",
|
|
27
|
+
"**/*.ts",
|
|
28
|
+
"**/*.tsx",
|
|
29
|
+
".next/types/**/*.ts",
|
|
30
|
+
".next/dev/types/**/*.ts"
|
|
31
|
+
],
|
|
32
|
+
"exclude": ["node_modules"]
|
|
33
|
+
}
|