4track 0.1.5 → 0.1.6
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/dist/assets/casette_hiss_compressed.mp3 +0 -0
- package/dist/audio/constants.d.ts +1 -1
- package/dist/audio/constants.js +3 -3
- package/dist/audio/engine.svelte.d.ts +2 -2
- package/dist/audio/engine.svelte.js +1 -1
- package/dist/audio/project-io.d.ts +1 -1
- package/dist/audio/project-io.js +6 -3
- package/dist/components/FourTrack.svelte +15 -6
- package/dist/components/FourTrack.svelte.d.ts +1 -1
- package/package.json +1 -1
- package/dist/assets/casette_hiss.mp3 +0 -0
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioEngineConfig } from
|
|
1
|
+
import type { AudioEngineConfig } from "../types.js";
|
|
2
2
|
export declare const PLAYBACK_TICK_MS = 50;
|
|
3
3
|
export declare const DEFAULT_CONFIG: AudioEngineConfig;
|
|
4
4
|
export declare const AUDIO_CONSTRAINTS: MediaTrackConstraints;
|
package/dist/audio/constants.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Default configuration and constraints for the audio engine.
|
|
2
|
-
import workletUrl from
|
|
2
|
+
import workletUrl from "../assets/recorder-worklet.js?url";
|
|
3
3
|
export const PLAYBACK_TICK_MS = 50;
|
|
4
4
|
export const DEFAULT_CONFIG = {
|
|
5
|
-
sampleRate:
|
|
5
|
+
sampleRate: 32000, // 44100 | 48000 | 96000
|
|
6
6
|
bitDepth: 16, // 8 = lo-fi, 16 = CD quality, 32 = float (uncompressed)
|
|
7
7
|
maxSeconds: 180, // max recording length per track (seconds)
|
|
8
8
|
trackCount: 4, // number of mixer tracks
|
|
9
9
|
workletUrl,
|
|
10
10
|
inputFx: [
|
|
11
11
|
{
|
|
12
|
-
type:
|
|
12
|
+
type: "trim",
|
|
13
13
|
enabled: true,
|
|
14
14
|
default: -1, // initial slider position: -1 (clean) → 1 (full saturation)
|
|
15
15
|
gainMin: 0.2, // gain at slider -1; lower = quieter clean tone (0.1–1.0)
|
|
@@ -81,8 +81,8 @@ export declare class AudioEngine {
|
|
|
81
81
|
setInputGain(value: number): void;
|
|
82
82
|
private startMeters;
|
|
83
83
|
private stopMeters;
|
|
84
|
-
/** Serializes all tracks and settings into a .4trk binary blob. */
|
|
85
|
-
exportProject(): Blob
|
|
84
|
+
/** Serializes all tracks and settings into a compressed .4trk binary blob. */
|
|
85
|
+
exportProject(): Promise<Blob>;
|
|
86
86
|
/** Loads a .4trk file, restoring all track buffers, mixer settings, and master volume. */
|
|
87
87
|
importProject(file: File | Blob): Promise<void>;
|
|
88
88
|
/** Disconnects all audio nodes, closes the AudioContext, and releases media streams. */
|
|
@@ -571,7 +571,7 @@ export class AudioEngine {
|
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
573
|
// ─── Save / Load ────────────────────────────────────────────────────
|
|
574
|
-
/** Serializes all tracks and settings into a .4trk binary blob. */
|
|
574
|
+
/** Serializes all tracks and settings into a compressed .4trk binary blob. */
|
|
575
575
|
exportProject() {
|
|
576
576
|
return _exportProject(this.tracks, this.config, this.masterVolume);
|
|
577
577
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Track } from './track.svelte.js';
|
|
2
2
|
import type { AudioEngineConfig } from '../types.js';
|
|
3
|
-
export declare function exportProject(tracks: Track[], config: AudioEngineConfig, masterVolume: number): Blob
|
|
3
|
+
export declare function exportProject(tracks: Track[], config: AudioEngineConfig, masterVolume: number): Promise<Blob>;
|
|
4
4
|
export declare function importProject(file: File | Blob, tracks: Track[], ensureContext: () => AudioContext): Promise<{
|
|
5
5
|
masterVolume: number;
|
|
6
6
|
}>;
|
package/dist/audio/project-io.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Uses integer quantization from ./pcm.ts for compact storage.
|
|
4
4
|
import { Track } from './track.svelte.js';
|
|
5
5
|
import { quantizePCM, dequantizePCM } from './pcm.js';
|
|
6
|
-
export function exportProject(tracks, config, masterVolume) {
|
|
6
|
+
export async function exportProject(tracks, config, masterVolume) {
|
|
7
7
|
const trackMeta = [];
|
|
8
8
|
const pcmParts = [];
|
|
9
9
|
for (const track of tracks) {
|
|
@@ -40,10 +40,13 @@ export function exportProject(tracks, config, masterVolume) {
|
|
|
40
40
|
const encoder = new TextEncoder();
|
|
41
41
|
const metaBytes = encoder.encode(JSON.stringify(metadata));
|
|
42
42
|
const metaLength = new Uint32Array([metaBytes.length]);
|
|
43
|
-
|
|
43
|
+
const raw = new Blob([metaLength, metaBytes, ...pcmParts]);
|
|
44
|
+
const compressed = raw.stream().pipeThrough(new CompressionStream('gzip'));
|
|
45
|
+
return new Response(compressed).blob();
|
|
44
46
|
}
|
|
45
47
|
export async function importProject(file, tracks, ensureContext) {
|
|
46
|
-
const
|
|
48
|
+
const decompressed = new Blob([file]).stream().pipeThrough(new DecompressionStream('gzip'));
|
|
49
|
+
const arrayBuffer = await new Response(decompressed).arrayBuffer();
|
|
47
50
|
const view = new DataView(arrayBuffer);
|
|
48
51
|
const metaLength = view.getUint32(0, true);
|
|
49
52
|
const metaBytes = new Uint8Array(arrayBuffer, 4, metaLength);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { AudioEngine } from "../audio/engine.svelte.js"
|
|
3
3
|
import type { HiddenTrackConfig, LoadStatus } from "../types.js"
|
|
4
|
-
import casetteHissUrl from "../assets/
|
|
4
|
+
import casetteHissUrl from "../assets/casette_hiss_compressed.mp3"
|
|
5
5
|
import noiseImg from "../assets/noise_50.jpg"
|
|
6
6
|
import logoImg from "../assets/logo.svg?url"
|
|
7
7
|
import openstudioImg from "../assets/openstudio.svg?url"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}: {
|
|
27
27
|
hiddenTracks?: HiddenTrackConfig[]
|
|
28
28
|
onready?: (detail: { engine: AudioEngine }) => void
|
|
29
|
-
save?: () => Blob
|
|
29
|
+
save?: () => Promise<Blob>
|
|
30
30
|
load?: (source: File | string) => Promise<void>
|
|
31
31
|
initialProject?: string | File
|
|
32
32
|
status?: LoadStatus
|
|
@@ -108,13 +108,16 @@
|
|
|
108
108
|
|
|
109
109
|
{#snippet channelStrip(track, i)}
|
|
110
110
|
<div
|
|
111
|
-
class="channel-lights cell-center"
|
|
111
|
+
class="track{i} channel-lights cell-center"
|
|
112
112
|
style="grid-area: {i + 3} / 2 / {i + 4} / 3"
|
|
113
113
|
>
|
|
114
114
|
<Lights level={track.level} />
|
|
115
115
|
</div>
|
|
116
116
|
|
|
117
|
-
<div
|
|
117
|
+
<div
|
|
118
|
+
class="track{i} volume cell-center"
|
|
119
|
+
style="grid-area: {i + 3} / 3 / {i + 4} / 4"
|
|
120
|
+
>
|
|
118
121
|
<Knob
|
|
119
122
|
min={0}
|
|
120
123
|
max={1.5}
|
|
@@ -123,7 +126,10 @@
|
|
|
123
126
|
/>
|
|
124
127
|
</div>
|
|
125
128
|
|
|
126
|
-
<div
|
|
129
|
+
<div
|
|
130
|
+
class="track{i} panning cell-center"
|
|
131
|
+
style="grid-area: {i + 3} / 4 / {i + 4} / 5"
|
|
132
|
+
>
|
|
127
133
|
<Knob
|
|
128
134
|
min={-1}
|
|
129
135
|
max={1}
|
|
@@ -232,7 +238,10 @@
|
|
|
232
238
|
/>
|
|
233
239
|
</div>
|
|
234
240
|
|
|
235
|
-
<div
|
|
241
|
+
<div
|
|
242
|
+
class="cell-center input-volume"
|
|
243
|
+
style="grid-area: 4 / 7 / 7 / 8"
|
|
244
|
+
>
|
|
236
245
|
<Slider
|
|
237
246
|
min={0}
|
|
238
247
|
max={1.5}
|
package/package.json
CHANGED
|
Binary file
|