4track 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +80 -0
  3. package/dist/assets/btn_fwd.svg +30 -0
  4. package/dist/assets/btn_normal.png +0 -0
  5. package/dist/assets/btn_pause.svg +30 -0
  6. package/dist/assets/btn_play.svg +25 -0
  7. package/dist/assets/btn_pressed.png +0 -0
  8. package/dist/assets/btn_rec.svg +25 -0
  9. package/dist/assets/btn_rew.svg +30 -0
  10. package/dist/assets/btn_stop.svg +25 -0
  11. package/dist/assets/casette_hiss.mp3 +0 -0
  12. package/dist/assets/casette_hiss_compressed.mp3 +0 -0
  13. package/dist/assets/cassette.jpg +0 -0
  14. package/dist/assets/counter_bg.png +0 -0
  15. package/dist/assets/fx/counter.wav +0 -0
  16. package/dist/assets/fx/ffwd.wav +0 -0
  17. package/dist/assets/fx/pause.wav +0 -0
  18. package/dist/assets/fx/play.wav +0 -0
  19. package/dist/assets/fx/record.wav +0 -0
  20. package/dist/assets/fx/stop.wav +0 -0
  21. package/dist/assets/fx/track.wav +0 -0
  22. package/dist/assets/logo.svg +51 -0
  23. package/dist/assets/noise_50.jpg +0 -0
  24. package/dist/assets/openstudio.svg +38 -0
  25. package/dist/assets/recorder-worklet.d.ts +8 -0
  26. package/dist/assets/recorder-worklet.js +30 -0
  27. package/dist/assets/rotator.png +0 -0
  28. package/dist/assets/slider-indicator.svg +139 -0
  29. package/dist/assets/slider.png +0 -0
  30. package/dist/assets/slideselect-indicator.svg +64 -0
  31. package/dist/assets/slideselect-thumb.png +0 -0
  32. package/dist/assets/svg-icons.d.ts +6 -0
  33. package/dist/assets/svg-icons.js +8 -0
  34. package/dist/assets.d.ts +34 -0
  35. package/dist/audio/constants.d.ts +4 -0
  36. package/dist/audio/constants.js +27 -0
  37. package/dist/audio/engine.svelte.d.ts +90 -0
  38. package/dist/audio/engine.svelte.js +604 -0
  39. package/dist/audio/input-fx.d.ts +8 -0
  40. package/dist/audio/input-fx.js +44 -0
  41. package/dist/audio/metering.d.ts +3 -0
  42. package/dist/audio/metering.js +20 -0
  43. package/dist/audio/pcm.d.ts +2 -0
  44. package/dist/audio/pcm.js +43 -0
  45. package/dist/audio/project-io.d.ts +6 -0
  46. package/dist/audio/project-io.js +85 -0
  47. package/dist/audio/recording.d.ts +2 -0
  48. package/dist/audio/recording.js +80 -0
  49. package/dist/audio/track.svelte.d.ts +13 -0
  50. package/dist/audio/track.svelte.js +17 -0
  51. package/dist/components/Cassette.svelte +179 -0
  52. package/dist/components/Cassette.svelte.d.ts +9 -0
  53. package/dist/components/FourTrack.svelte +443 -0
  54. package/dist/components/FourTrack.svelte.d.ts +16 -0
  55. package/dist/components/Mixer.svelte +105 -0
  56. package/dist/components/Mixer.svelte.d.ts +7 -0
  57. package/dist/components/TransportButtons.svelte +299 -0
  58. package/dist/components/TransportButtons.svelte.d.ts +10 -0
  59. package/dist/components/els/DigitRoller.svelte +82 -0
  60. package/dist/components/els/DigitRoller.svelte.d.ts +5 -0
  61. package/dist/components/els/Knob.svelte +267 -0
  62. package/dist/components/els/Knob.svelte.d.ts +12 -0
  63. package/dist/components/els/Light.svelte +104 -0
  64. package/dist/components/els/Light.svelte.d.ts +8 -0
  65. package/dist/components/els/Lights.svelte +101 -0
  66. package/dist/components/els/Lights.svelte.d.ts +11 -0
  67. package/dist/components/els/SlideSelect.svelte +159 -0
  68. package/dist/components/els/SlideSelect.svelte.d.ts +15 -0
  69. package/dist/components/els/Slider.svelte +139 -0
  70. package/dist/components/els/Slider.svelte.d.ts +21 -0
  71. package/dist/components/els/Timestamp.svelte +92 -0
  72. package/dist/components/els/Timestamp.svelte.d.ts +5 -0
  73. package/dist/fx/soundfx.d.ts +14 -0
  74. package/dist/fx/soundfx.js +65 -0
  75. package/dist/index.d.ts +4 -0
  76. package/dist/index.js +3 -0
  77. package/dist/types.d.ts +40 -0
  78. package/dist/types.js +1 -0
  79. package/package.json +48 -0
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # 4track
2
+
3
+ A browser-based 4-track audio recorder built with the Web Audio API and SvelteKit. Designed for low-latency recording with overdub support, latency compensation, and sample-accurate multi-track playback — all running entirely client-side with no server required.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install 4-track-recorder
9
+ ```
10
+
11
+ ## Basic Usage
12
+
13
+ ```svelte
14
+ <script>
15
+ import { FourTrack } from '4-track-recorder'
16
+ </script>
17
+
18
+ <FourTrack />
19
+ ```
20
+
21
+ ## Saving and Loading Projects
22
+
23
+ The component uses a custom `.4trk` binary format that stores all track audio data and mixer settings (volume, pan, master volume).
24
+
25
+ ### Bind `save` and `load` functions
26
+
27
+ Use `bind:save` and `bind:load` to get functions you can call from your own UI:
28
+
29
+ ```svelte
30
+ <script>
31
+ import { FourTrack } from '4-track-recorder'
32
+
33
+ let save
34
+ let load
35
+
36
+ function handleSave() {
37
+ const blob = save()
38
+ // Download as file
39
+ const url = URL.createObjectURL(blob)
40
+ const a = document.createElement('a')
41
+ a.href = url
42
+ a.download = 'my-song.4trk'
43
+ a.click()
44
+ URL.revokeObjectURL(url)
45
+ }
46
+
47
+ function handleLoad(event) {
48
+ const file = event.target.files?.[0]
49
+ if (file) load(file)
50
+ }
51
+
52
+ // Or load directly from a URL
53
+ function loadFromUrl() {
54
+ load('https://example.com/songs/demo.4trk')
55
+ }
56
+ </script>
57
+
58
+ <FourTrack bind:save bind:load />
59
+
60
+ <button onclick={handleSave}>Save Project</button>
61
+ <input type="file" accept=".4trk" onchange={handleLoad} />
62
+ ```
63
+
64
+ ### Load a project on mount
65
+
66
+ Pass a URL or `File` to `initialProject` to auto-load a project when the component mounts:
67
+
68
+ ```svelte
69
+ <FourTrack initialProject="/songs/demo.4trk" />
70
+ ```
71
+
72
+ ## Props
73
+
74
+ | Prop | Type | Description |
75
+ |------|------|-------------|
76
+ | `hiddenTracks` | `HiddenTrackConfig[]` | Background audio tracks (e.g. cassette hiss) |
77
+ | `onready` | `(detail: { engine: AudioEngine }) => void` | Callback when the engine is initialized |
78
+ | `save` | `() => Blob` (bindable) | Bind to get a function that exports the project as a `.4trk` blob |
79
+ | `load` | `(source: File \| string) => Promise<void>` (bindable) | Bind to get a function that imports a `.4trk` file or URL |
80
+ | `initialProject` | `string \| File` | URL or File to auto-load on mount |
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 55 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-7227.548381,-6965.565037)">
19
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
20
+ <g transform="matrix(-0,0.384296,-0.287166,-0,8531.756364,5823.438267)">
21
+ <path d="M3017.5,4351L3063,4442L2972,4442L3017.5,4351Z" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
25
+ <g transform="matrix(-0,0.384296,-0.287166,-0,8503.360247,5823.438267)">
26
+ <path d="M3017.5,4351L3063,4442L2972,4442L3017.5,4351Z" fill="#808080"/>
27
+ </g>
28
+ </g>
29
+ </g>
30
+ </svg>
Binary file
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 31 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-7502.694122,-6966.11235)">
19
+ <g transform="matrix(0.713692,0,0,0.713692,4998.031255,3628.341326)">
20
+ <g transform="matrix(0.409091,0,0,1,2243.717876,-8.233124)">
21
+ <rect x="3094" y="4685" width="44" height="44" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ <g transform="matrix(0.713692,0,0,0.713692,4998.031255,3628.341326)">
25
+ <g transform="matrix(0.409091,0,0,1,2268.500379,-8.233124)">
26
+ <rect x="3094" y="4685" width="44" height="44" fill="#808080"/>
27
+ </g>
28
+ </g>
29
+ </g>
30
+ </svg>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 27 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-6932.417095,-6965.565037)">
19
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
20
+ <g transform="matrix(0,0.384296,-0.287166,0,8208.228962,5823.438267)">
21
+ <path d="M3017.5,4351L3063,4442L2972,4442L3017.5,4351Z" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ </g>
25
+ </svg>
Binary file
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 34 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-6789,-6966.095848)">
19
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
20
+ <g transform="matrix(0.706443,0,0,0.706443,4809.059465,3659.940473)">
21
+ <circle cx="2827" cy="4704" r="24" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ </g>
25
+ </svg>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 55 35" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-7088.586366,-6965.565037)">
19
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
20
+ <g transform="matrix(0,-0.384296,0.287166,0,5839.347551,8142.662714)">
21
+ <path d="M3017.5,4351L3063,4442L2972,4442L3017.5,4351Z" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
25
+ <g transform="matrix(0,-0.384296,0.287166,0,5867.743668,8142.662714)">
26
+ <path d="M3017.5,4351L3063,4442L2972,4442L3017.5,4351Z" fill="#808080"/>
27
+ </g>
28
+ </g>
29
+ </g>
30
+ </svg>
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <defs>
5
+ <filter id="bevel">
6
+ <feOffset in="SourceAlpha" dx="2.5" dy="2.5" result="a"/>
7
+ <feComposite in="SourceAlpha" in2="a" operator="out" result="b"/>
8
+ <feFlood flood-color="#000" flood-opacity="0.8"/>
9
+ <feComposite in2="b" operator="in" result="s"/>
10
+ <feOffset in="SourceAlpha" dx="-2" dy="-2" result="c"/>
11
+ <feComposite in="SourceAlpha" in2="c" operator="out" result="d"/>
12
+ <feFlood flood-color="#fff" flood-opacity="0.4"/>
13
+ <feComposite in2="d" operator="in" result="h"/>
14
+ <feComposite in="s" in2="SourceGraphic" operator="over" result="r"/>
15
+ <feComposite in="h" in2="r" operator="over"/>
16
+ </filter>
17
+ </defs>
18
+ <g filter="url(#bevel)" transform="matrix(1,0,0,1,-7364.046612,-6966.278729)">
19
+ <g transform="matrix(1,0,0,1,-0.220472,0)">
20
+ <g transform="matrix(0.713692,0,0,0.713692,5156.10409,3622.63179)">
21
+ <rect x="3094" y="4685" width="44" height="44" fill="#808080"/>
22
+ </g>
23
+ </g>
24
+ </g>
25
+ </svg>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 682 85" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <g transform="matrix(1,0,0,1,-9716.223497,-180.012349)">
5
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
6
+ <g transform="matrix(0.454874,0,0,0.414873,5205.62821,-3313.383095)">
7
+ <path d="M9331.346,945.851L9274.813,945.851L9186.279,1061.318L9186.279,1103.184L9295.079,1103.184L9295.079,1145.851L9331.346,1145.851L9331.346,1103.184L9354.813,1103.184L9354.813,1074.118L9331.346,1074.118L9331.346,945.851ZM9295.079,1074.118L9216.679,1074.118L9294.013,973.584L9295.079,973.584L9295.079,1074.118Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
8
+ </g>
9
+ </g>
10
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
11
+ <g transform="matrix(0.454874,0,0,0.414873,5203.62821,-3313.383095)">
12
+ <path d="M9463.879,978.651L9522.546,978.651L9522.546,945.851L9366.813,945.851L9366.813,978.651L9425.479,978.651L9425.479,1145.851L9463.879,1145.851L9463.879,978.651Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
13
+ </g>
14
+ </g>
15
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
16
+ <g transform="matrix(0.454874,0,0,0.414873,5203.62821,-3313.383095)">
17
+ <path d="M9636.413,1079.718C9654.813,1079.984 9661.746,1091.718 9661.746,1108.518L9661.746,1145.851L9700.146,1145.851L9700.146,1108.518C9700.146,1080.251 9693.479,1065.584 9666.279,1063.184L9666.279,1062.118C9700.146,1057.051 9701.746,1035.451 9701.746,1005.851C9701.746,960.518 9684.946,946.918 9641.213,945.851L9539.079,945.851L9539.079,1145.851L9577.479,1145.851L9577.479,1079.718L9636.413,1079.718ZM9577.479,1046.918L9577.479,978.651L9630.813,978.651C9658.279,978.651 9663.346,983.718 9663.346,1011.984C9663.346,1041.318 9656.413,1046.918 9628.146,1046.918L9577.479,1046.918Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
18
+ </g>
19
+ </g>
20
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
21
+ <g transform="matrix(0.454874,0,0,0.414873,5203.62821,-3313.383095)">
22
+ <path d="M9853.213,1107.984L9866.279,1145.851L9905.213,1145.851L9837.479,945.851L9780.946,945.851L9714.546,1145.851L9754.279,1145.851L9766.813,1107.984L9853.213,1107.984ZM9844.679,1078.918L9775.613,1078.918L9809.746,975.184L9810.279,975.184L9844.679,1078.918Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
23
+ </g>
24
+ </g>
25
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
26
+ <g transform="matrix(0.454874,0,0,0.414873,5203.62821,-3313.383095)">
27
+ <path d="M10079.079,1012.784L10079.079,1001.851C10076.413,944.518 10047.879,944.251 9998.013,944.251C9939.079,944.251 9914.279,958.651 9914.279,1022.651L9914.279,1068.518C9915.079,1126.918 9927.613,1150.118 9998.013,1147.451C10047.613,1145.318 10082.013,1147.451 10081.213,1087.184L10081.213,1074.118L10042.813,1074.118L10042.813,1085.051C10042.813,1113.584 10028.946,1114.651 9998.013,1114.651C9957.746,1114.651 9952.946,1106.918 9952.679,1066.918L9952.679,1022.651C9952.679,983.451 9959.346,977.051 9998.013,977.051C10031.613,977.051 10040.679,978.651 10040.679,1001.851L10040.679,1012.784L10079.079,1012.784Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
28
+ </g>
29
+ </g>
30
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
31
+ <g transform="matrix(0.454874,0,0,0.414873,5203.62821,-3313.383095)">
32
+ <path d="M10146.013,945.851L10107.613,945.851L10107.613,1145.851L10146.013,1145.851L10146.013,1060.251L10163.879,1060.251L10237.479,1145.851L10286.013,1145.851L10196.679,1043.451L10277.746,945.851L10230.546,945.851L10163.879,1027.451L10146.013,1027.451L10146.013,945.851Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
33
+ </g>
34
+ </g>
35
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
36
+ <g transform="matrix(0.454874,0,0,0.414873,5351.88282,-3313.952254)">
37
+ <path d="M10174.546,1012.784L10174.546,1001.851C10171.879,944.518 10143.346,944.251 10093.479,944.251C10034.546,944.251 10009.746,958.651 10009.746,1022.651L10009.746,1068.518C10010.546,1126.918 10023.079,1150.118 10093.479,1147.451C10143.079,1145.318 10177.479,1147.451 10176.679,1087.184L10176.679,1074.118L10138.279,1074.118L10138.279,1085.051C10138.279,1113.584 10124.413,1114.651 10093.479,1114.651C10053.213,1114.651 10048.413,1106.918 10048.146,1066.918L10048.146,1022.651C10048.146,983.451 10054.813,977.051 10093.479,977.051C10127.079,977.051 10136.146,978.651 10136.146,1001.851L10136.146,1012.784L10174.546,1012.784Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
38
+ </g>
39
+ </g>
40
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
41
+ <g transform="matrix(0.454874,0,0,0.414873,5351.88282,-3313.952254)">
42
+ <path d="M10360.146,1012.784L10360.146,1001.851C10357.479,944.518 10328.946,944.251 10279.079,944.251C10220.146,944.251 10195.346,958.651 10195.346,1022.651L10195.346,1068.518C10196.146,1126.918 10208.679,1150.118 10279.079,1147.451C10328.679,1145.318 10363.079,1147.451 10362.279,1087.184L10362.279,1074.118L10323.879,1074.118L10323.879,1085.051C10323.879,1113.584 10310.013,1114.651 10279.079,1114.651C10238.813,1114.651 10234.013,1106.918 10233.746,1066.918L10233.746,1022.651C10233.746,983.451 10240.413,977.051 10279.079,977.051C10312.679,977.051 10321.746,978.651 10321.746,1001.851L10321.746,1012.784L10360.146,1012.784Z" style="fill:rgb(164,53,53);fill-rule:nonzero;"/>
43
+ </g>
44
+ </g>
45
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
46
+ <g transform="matrix(0.615385,0,0,0.615385,3811.923077,-3128.297396)">
47
+ <rect x="9846" y="382" width="39" height="39" style="fill:rgb(163,53,53);"/>
48
+ </g>
49
+ </g>
50
+ </g>
51
+ </svg>
Binary file
@@ -0,0 +1,38 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="100%" height="100%" viewBox="0 0 740 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
4
+ <g transform="matrix(1,0,0,1,-9402.687119,-424.806087)">
5
+ <g transform="matrix(1,0,0,1,332,3102.220472)">
6
+ <g transform="matrix(0.357043,0,0,0.275182,5792.185669,-2953.64199)">
7
+ <path d="M9192.146,1075.984C9192.146,1134.918 9202.279,1147.451 9254.279,1147.451C9306.279,1147.451 9316.413,1134.918 9316.413,1075.984C9316.413,1016.784 9306.279,1004.251 9254.279,1004.251C9202.279,1004.251 9192.146,1016.784 9192.146,1075.984ZM9214.013,1075.984C9214.013,1027.184 9216.679,1021.318 9254.279,1021.318C9291.879,1021.318 9294.546,1027.184 9294.546,1075.984C9294.546,1124.518 9291.879,1130.384 9254.279,1130.384C9216.679,1130.384 9214.013,1124.518 9214.013,1075.984Z" style="fill:white;fill-rule:nonzero;"/>
8
+ <path d="M9408.679,1021.318C9444.413,1021.318 9447.346,1034.118 9447.346,1075.984C9447.346,1121.318 9441.213,1130.384 9408.679,1130.384C9371.079,1130.384 9368.946,1109.051 9368.946,1075.984C9368.946,1038.918 9368.946,1021.318 9408.679,1021.318ZM9368.946,1005.851L9347.879,1005.851L9347.879,1206.384L9368.946,1206.384L9368.946,1129.318L9369.479,1129.318C9377.479,1145.584 9398.546,1147.451 9414.546,1147.451C9455.613,1147.451 9469.213,1131.451 9469.213,1075.984C9469.213,1034.118 9465.479,1004.251 9414.546,1004.251C9396.946,1004.251 9378.013,1007.451 9369.479,1023.451L9368.946,1022.918L9368.946,1005.851Z" style="fill:white;fill-rule:nonzero;"/>
9
+ <path d="M9598.013,1103.451L9598.013,1108.784C9598.013,1128.518 9588.679,1130.384 9559.879,1130.384C9522.013,1130.384 9518.813,1124.784 9518.813,1080.518L9619.613,1080.518L9619.613,1066.384C9619.613,1014.651 9605.213,1004.251 9559.879,1004.251C9509.746,1004.251 9496.946,1017.851 9496.946,1075.984C9496.946,1129.318 9505.213,1147.451 9559.879,1147.451C9591.079,1147.451 9619.613,1145.584 9619.613,1108.518L9619.613,1103.451L9598.013,1103.451ZM9518.813,1063.451C9520.413,1031.184 9521.746,1021.318 9559.879,1021.318C9591.879,1021.318 9596.679,1023.718 9597.746,1063.451L9518.813,1063.451Z" style="fill:white;fill-rule:nonzero;"/>
10
+ <path d="M9673.213,1005.851L9652.146,1005.851L9652.146,1145.851L9673.213,1145.851L9673.213,1064.251C9673.213,1031.984 9680.679,1021.318 9715.079,1021.318C9738.813,1021.318 9748.679,1025.584 9748.679,1051.184L9748.679,1145.851L9769.746,1145.851L9769.746,1052.784C9770.279,1013.851 9752.946,1004.251 9716.946,1004.251C9700.946,1004.251 9680.413,1006.118 9673.746,1022.918L9673.213,1022.918L9673.213,1005.851Z" style="fill:white;fill-rule:nonzero;"/>
11
+ <path d="M9917.479,1037.051C9917.479,1005.318 9887.346,1004.251 9862.813,1004.251C9824.946,1004.251 9801.746,1005.051 9801.746,1045.584C9801.746,1085.318 9832.413,1082.118 9862.813,1084.251C9888.413,1085.851 9899.346,1081.051 9899.346,1107.184C9899.346,1131.984 9877.213,1128.784 9862.813,1128.784C9830.813,1128.784 9822.546,1125.851 9822.546,1112.518L9822.546,1101.584L9800.679,1101.584L9800.679,1114.651C9800.679,1145.851 9832.413,1147.451 9862.813,1147.451C9894.013,1147.451 9921.213,1145.851 9921.213,1106.384C9921.213,1060.784 9888.413,1066.384 9852.413,1064.251C9830.546,1063.184 9823.613,1065.051 9823.613,1039.984C9823.613,1022.651 9836.413,1022.918 9862.813,1022.918C9884.946,1022.918 9895.613,1022.918 9895.613,1037.051L9895.613,1042.384L9917.479,1042.384L9917.479,1037.051Z" style="fill:white;fill-rule:nonzero;"/>
12
+ <path d="M9945.479,1075.984C9945.479,1134.918 9955.613,1147.451 10007.613,1147.451C10059.613,1147.451 10069.746,1134.918 10069.746,1075.984C10069.746,1016.784 10059.613,1004.251 10007.613,1004.251C9955.613,1004.251 9945.479,1016.784 9945.479,1075.984ZM9967.346,1075.984C9967.346,1027.184 9970.013,1021.318 10007.613,1021.318C10045.213,1021.318 10047.879,1027.184 10047.879,1075.984C10047.879,1124.518 10045.213,1130.384 10007.613,1130.384C9970.013,1130.384 9967.346,1124.518 9967.346,1075.984Z" style="fill:white;fill-rule:nonzero;"/>
13
+ <path d="M10195.613,1145.851L10216.946,1145.851L10216.946,1005.851L10195.879,1005.851L10195.879,1092.251C10195.879,1125.584 10180.679,1130.384 10151.079,1130.384C10123.879,1130.384 10122.279,1118.384 10122.279,1095.718L10122.279,1005.851L10101.213,1005.851L10101.213,1095.718C10101.213,1132.518 10114.279,1147.451 10151.346,1147.451C10169.746,1147.451 10187.613,1144.251 10195.079,1127.184L10195.613,1127.184L10195.613,1145.851Z" style="fill:white;fill-rule:nonzero;"/>
14
+ <path d="M10251.079,1005.851L10251.079,1145.851L10272.146,1145.851L10272.146,1058.651C10271.613,1033.851 10280.146,1021.318 10306.279,1021.318C10323.879,1021.318 10329.746,1027.184 10329.746,1044.518L10329.746,1053.851L10349.746,1053.851L10349.746,1043.718C10349.746,1017.584 10337.746,1004.251 10310.813,1004.251C10295.079,1004.251 10278.279,1008.251 10271.079,1023.718L10270.546,1023.184L10271.613,1005.851L10251.079,1005.851Z" style="fill:white;fill-rule:nonzero;"/>
15
+ <path d="M10467.079,1095.184L10467.079,1102.118C10467.079,1127.451 10457.479,1130.384 10431.079,1130.384C10390.013,1130.384 10388.413,1118.384 10388.413,1078.918C10388.413,1034.118 10389.213,1021.318 10426.546,1021.318C10450.813,1021.318 10464.679,1021.851 10464.679,1047.184L10464.679,1051.451L10485.746,1051.451L10485.746,1047.718C10485.746,1007.984 10459.079,1004.251 10425.213,1004.251C10374.546,1004.251 10366.546,1027.451 10366.546,1073.051C10366.546,1125.051 10370.546,1147.451 10428.679,1147.451C10462.013,1147.451 10488.146,1142.384 10488.146,1102.918L10488.146,1095.184L10467.079,1095.184Z" style="fill:white;fill-rule:nonzero;"/>
16
+ <path d="M10614.013,1103.451L10614.013,1108.784C10614.013,1128.518 10604.679,1130.384 10575.879,1130.384C10538.013,1130.384 10534.813,1124.784 10534.813,1080.518L10635.613,1080.518L10635.613,1066.384C10635.613,1014.651 10621.213,1004.251 10575.879,1004.251C10525.746,1004.251 10512.946,1017.851 10512.946,1075.984C10512.946,1129.318 10521.213,1147.451 10575.879,1147.451C10607.079,1147.451 10635.613,1145.584 10635.613,1108.518L10635.613,1103.451L10614.013,1103.451ZM10534.813,1063.451C10536.413,1031.184 10537.746,1021.318 10575.879,1021.318C10607.879,1021.318 10612.679,1023.718 10613.746,1063.451L10534.813,1063.451Z" style="fill:white;fill-rule:nonzero;"/>
17
+ </g>
18
+ <g transform="matrix(0.580352,0,0,0.330075,3733.588741,-2932.860136)">
19
+ <path d="M9330.546,1037.051C9337.213,1005.318 9307.346,1004.251 9282.813,1004.251C9244.946,1004.251 9221.479,1005.051 9212.946,1045.584C9204.413,1085.318 9235.879,1082.118 9265.746,1084.251C9291.079,1085.851 9303.079,1081.051 9297.479,1107.184C9292.146,1131.984 9270.813,1128.784 9256.413,1128.784C9224.413,1128.784 9216.679,1125.851 9219.613,1112.518L9221.746,1101.584L9199.879,1101.584L9197.213,1114.651C9190.546,1145.851 9222.013,1147.451 9252.413,1147.451C9283.613,1147.451 9311.079,1145.851 9319.346,1106.384C9329.213,1060.784 9295.079,1066.384 9259.613,1064.251C9238.013,1063.184 9230.546,1065.051 9235.879,1039.984C9239.613,1022.651 9252.413,1022.918 9278.813,1022.918C9300.946,1022.918 9311.613,1022.918 9308.679,1037.051L9307.346,1042.384L9329.213,1042.384L9330.546,1037.051Z" style="fill:white;fill-rule:nonzero;"/>
20
+ <path d="M9443.613,1005.851L9389.479,1005.851L9396.679,971.984L9375.613,971.984L9368.413,1005.851L9349.746,1005.851L9346.013,1022.918L9364.679,1022.918L9347.079,1105.318C9340.146,1138.118 9345.746,1147.451 9378.546,1147.451C9407.346,1147.451 9421.479,1134.384 9427.346,1106.651L9429.746,1096.251L9409.746,1096.251L9407.346,1106.651C9404.679,1119.984 9402.279,1130.384 9382.546,1130.384C9367.079,1130.384 9363.879,1126.918 9366.813,1111.718L9385.746,1022.918L9439.879,1022.918L9443.613,1005.851Z" style="fill:white;fill-rule:nonzero;"/>
21
+ <path d="M9531.079,1145.851L9552.413,1145.851L9582.279,1005.851L9561.213,1005.851L9542.813,1092.251C9535.613,1125.584 9519.346,1130.384 9489.746,1130.384C9462.546,1130.384 9463.613,1118.384 9468.413,1095.718L9487.613,1005.851L9466.546,1005.851L9447.346,1095.718C9439.613,1132.518 9449.479,1147.451 9486.546,1147.451C9504.946,1147.451 9523.346,1144.251 9534.546,1127.184L9535.079,1127.184L9531.079,1145.851Z" style="fill:white;fill-rule:nonzero;"/>
22
+ <path d="M9648.946,1130.384C9618.813,1130.384 9610.546,1124.518 9620.946,1075.984C9631.346,1026.918 9639.879,1021.318 9672.146,1021.318C9706.546,1021.318 9707.613,1037.584 9699.613,1075.984C9690.279,1119.184 9681.746,1130.384 9648.946,1130.384ZM9684.679,1145.851L9705.746,1145.851L9748.146,945.851L9727.079,945.851L9710.813,1023.184L9710.279,1023.184C9707.613,1006.118 9684.679,1004.251 9669.213,1004.251C9619.079,1004.251 9607.879,1033.851 9599.079,1075.984C9590.013,1118.651 9588.946,1147.451 9638.813,1147.451C9657.746,1147.451 9676.146,1144.518 9687.879,1127.718L9688.413,1128.251L9684.679,1145.851Z" style="fill:white;fill-rule:nonzero;"/>
23
+ <path d="M9793.213,1005.851L9772.146,1005.851L9742.279,1145.851L9763.346,1145.851L9793.213,1005.851ZM9805.746,945.851L9784.679,945.851L9779.879,969.051L9800.946,969.051L9805.746,945.851Z" style="fill:white;fill-rule:nonzero;"/>
24
+ <path d="M9810.279,1075.984C9797.746,1134.918 9805.213,1147.451 9857.213,1147.451C9909.213,1147.451 9922.013,1134.918 9934.546,1075.984C9947.079,1016.784 9939.613,1004.251 9887.613,1004.251C9835.613,1004.251 9822.813,1016.784 9810.279,1075.984ZM9832.146,1075.984C9842.546,1027.184 9846.279,1021.318 9883.879,1021.318C9921.479,1021.318 9923.079,1027.184 9912.679,1075.984C9902.279,1124.518 9898.279,1130.384 9860.679,1130.384C9823.079,1130.384 9821.746,1124.518 9832.146,1075.984Z" style="fill:white;fill-rule:nonzero;"/>
25
+ </g>
26
+ <g transform="matrix(0.376419,0,0,0.316378,6076.752903,-2917.247314)">
27
+ <path d="M9330.013,1005.851L9307.079,1005.851L9242.279,1129.851L9241.746,1129.851L9228.413,1005.851L9207.079,1005.851L9223.613,1145.851L9253.213,1145.851L9330.013,1005.851Z" style="fill:white;fill-rule:nonzero;"/>
28
+ </g>
29
+ <g transform="matrix(0.566869,0,0,0.627631,4393.034649,-3270.05596)">
30
+ <path d="M9308.679,964.251C9358.279,964.251 9371.346,964.518 9360.146,1016.518L9347.613,1075.184C9336.679,1127.184 9323.613,1127.451 9274.013,1127.451C9224.946,1127.451 9211.879,1127.184 9222.813,1075.184L9235.346,1016.518C9246.546,964.518 9259.613,964.251 9308.679,964.251ZM9270.279,1147.451C9332.146,1147.451 9355.346,1139.184 9370.279,1075.184L9382.813,1016.518C9395.079,952.518 9375.346,944.251 9312.946,944.251C9251.079,944.251 9227.613,952.518 9212.679,1016.518L9200.146,1075.184C9187.879,1139.184 9207.879,1147.451 9270.279,1147.451Z" style="fill:white;fill-rule:nonzero;"/>
31
+ <path d="M9421.213,1118.651L9397.479,1118.651L9391.613,1145.851L9415.346,1145.851L9421.213,1118.651Z" style="fill:white;fill-rule:nonzero;"/>
32
+ </g>
33
+ <g transform="matrix(0.755038,0,0,0.627631,2757.914795,-3269.161772)">
34
+ <path d="M9340.146,945.851L9307.346,945.851L9239.613,1005.851L9250.813,1019.451L9314.013,963.184L9275.079,1145.851L9297.746,1145.851L9340.146,945.851Z" style="fill:white;fill-rule:nonzero;"/>
35
+ </g>
36
+ </g>
37
+ </g>
38
+ </svg>
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Low-latency recorder AudioWorklet.
3
+ * - Pass-through: input → output (for direct monitoring with minimal delay).
4
+ * - Captures PCM and sends to main thread for recording (no MediaRecorder buffering).
5
+ */
6
+ declare class RecorderWorkletProcessor {
7
+ process(inputs: any, outputs: any): boolean;
8
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Low-latency recorder AudioWorklet.
3
+ * - Pass-through: input → output (for direct monitoring with minimal delay).
4
+ * - Captures PCM and sends to main thread for recording (no MediaRecorder buffering).
5
+ */
6
+ class RecorderWorkletProcessor extends AudioWorkletProcessor {
7
+ process(inputs, outputs) {
8
+ const input = inputs[0];
9
+ const output = outputs[0];
10
+ if (!input?.length || !input[0]?.length) return true;
11
+
12
+ const channelIn = input[0];
13
+ const channelOut = output[0];
14
+ const length = Math.min(channelIn.length, channelOut?.length ?? 0);
15
+
16
+ // Pass-through for low-latency monitoring (mic → worklet → destination)
17
+ if (channelOut && length > 0) {
18
+ channelOut.set(channelIn.subarray(0, length));
19
+ }
20
+
21
+ // Send PCM to main thread (copy; worklet buffers are reused)
22
+ const copy = new Float32Array(length);
23
+ copy.set(channelIn.subarray(0, length));
24
+ this.port.postMessage({ type: "pcm", data: copy }, [copy.buffer]);
25
+
26
+ return true;
27
+ }
28
+ }
29
+
30
+ registerProcessor("recorder", RecorderWorkletProcessor);
Binary file