@dawcore/transport 0.0.1 → 0.0.2
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/README.md +28 -5
- package/dist/index.d.mts +68 -21
- package/dist/index.d.ts +68 -21
- package/dist/index.js +246 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +245 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,8 @@ editor.adapterFactory = () => new NativePlayoutAdapter(audioContext);
|
|
|
66
66
|
```typescript
|
|
67
67
|
const transport = new Transport(audioContext, {
|
|
68
68
|
tempo: 120,
|
|
69
|
-
|
|
69
|
+
numerator: 4,
|
|
70
|
+
denominator: 4,
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
transport.setMetronomeEnabled(true);
|
|
@@ -74,6 +75,22 @@ transport.setMetronomeClickSounds(accentBuffer, normalBuffer);
|
|
|
74
75
|
transport.play();
|
|
75
76
|
```
|
|
76
77
|
|
|
78
|
+
### Mixed Meter
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const transport = new Transport(audioContext, { tempo: 120, numerator: 4, denominator: 4 });
|
|
82
|
+
|
|
83
|
+
// Switch to 7/8 at bar 5
|
|
84
|
+
transport.setMeter(7, 8, transport.barToTick(5));
|
|
85
|
+
|
|
86
|
+
// Query active meter at any tick
|
|
87
|
+
const { numerator, denominator } = transport.getMeter(transport.barToTick(5));
|
|
88
|
+
// → { numerator: 7, denominator: 8 }
|
|
89
|
+
|
|
90
|
+
transport.setMetronomeEnabled(true);
|
|
91
|
+
transport.play();
|
|
92
|
+
```
|
|
93
|
+
|
|
77
94
|
### Effects
|
|
78
95
|
|
|
79
96
|
```typescript
|
|
@@ -102,7 +119,8 @@ new Transport(audioContext: AudioContext, options?: TransportOptions)
|
|
|
102
119
|
| `sampleRate` | `audioContext.sampleRate` | Sample rate for timeline conversions |
|
|
103
120
|
| `ppqn` | `960` | Ticks per quarter note |
|
|
104
121
|
| `tempo` | `120` | Initial tempo in BPM |
|
|
105
|
-
| `
|
|
122
|
+
| `numerator` | `4` | Beats per bar (time signature numerator) |
|
|
123
|
+
| `denominator` | `4` | Beat unit (time signature denominator) |
|
|
106
124
|
| `schedulerLookahead` | `0.2` | How far ahead to schedule (seconds) |
|
|
107
125
|
|
|
108
126
|
**Playback:**
|
|
@@ -129,9 +147,14 @@ new Transport(audioContext: AudioContext, options?: TransportOptions)
|
|
|
129
147
|
**Loop:**
|
|
130
148
|
- `setLoop(enabled, start, end)` — Set loop region in seconds
|
|
131
149
|
|
|
132
|
-
**Tempo &
|
|
133
|
-
- `setTempo(bpm)` / `getTempo()`
|
|
134
|
-
- `
|
|
150
|
+
**Tempo & Meter:**
|
|
151
|
+
- `setTempo(bpm, atTick?)` / `getTempo(atTick?)`
|
|
152
|
+
- `clearTempos()` — remove all tempo entries
|
|
153
|
+
- `setMeter(numerator, denominator, atTick?)` / `getMeter(atTick?)`
|
|
154
|
+
- `removeMeter(atTick)` / `clearMeters()`
|
|
155
|
+
- `barToTick(bar)` / `tickToBar(tick)`
|
|
156
|
+
|
|
157
|
+
**Metronome:**
|
|
135
158
|
- `setMetronomeEnabled(enabled)`
|
|
136
159
|
- `setMetronomeClickSounds(accent, normal)`
|
|
137
160
|
|
package/dist/index.d.mts
CHANGED
|
@@ -22,11 +22,29 @@ interface TransportOptions {
|
|
|
22
22
|
ppqn?: number;
|
|
23
23
|
/** Initial tempo in BPM. Default: 120 */
|
|
24
24
|
tempo?: number;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** Time signature numerator. Default: 4 */
|
|
26
|
+
numerator?: number;
|
|
27
|
+
/** Time signature denominator. Default: 4 */
|
|
28
|
+
denominator?: number;
|
|
27
29
|
/** How far ahead to schedule audio, in seconds. Default: 0.2 */
|
|
28
30
|
schedulerLookahead?: number;
|
|
29
31
|
}
|
|
32
|
+
/** Public return type for getMeter() */
|
|
33
|
+
interface MeterSignature {
|
|
34
|
+
numerator: number;
|
|
35
|
+
denominator: number;
|
|
36
|
+
}
|
|
37
|
+
/** Storage entry for MeterMap */
|
|
38
|
+
interface MeterEntry {
|
|
39
|
+
/** Tick position where this meter starts */
|
|
40
|
+
tick: number;
|
|
41
|
+
/** Time signature numerator (e.g., 6 in 6/8) */
|
|
42
|
+
numerator: number;
|
|
43
|
+
/** Time signature denominator (e.g., 8 in 6/8) */
|
|
44
|
+
denominator: number;
|
|
45
|
+
/** Cached cumulative bar count from tick 0 to this entry. Derived — do not set manually. */
|
|
46
|
+
readonly barAtTick: number;
|
|
47
|
+
}
|
|
30
48
|
interface TempoEntry {
|
|
31
49
|
/** Tick position where this tempo starts */
|
|
32
50
|
tick: number;
|
|
@@ -103,16 +121,6 @@ declare class SampleTimeline {
|
|
|
103
121
|
secondsToSamples(seconds: number): number;
|
|
104
122
|
}
|
|
105
123
|
|
|
106
|
-
declare class TickTimeline {
|
|
107
|
-
private _ppqn;
|
|
108
|
-
constructor(ppqn?: number);
|
|
109
|
-
get ppqn(): number;
|
|
110
|
-
ticksPerBeat(): number;
|
|
111
|
-
ticksPerBar(beatsPerBar: number): number;
|
|
112
|
-
toPosition(ticks: number, beatsPerBar: number): TransportPosition;
|
|
113
|
-
fromPosition(bar: number, beat: number, tick: number, beatsPerBar: number): number;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
124
|
declare class TempoMap {
|
|
117
125
|
private _ppqn;
|
|
118
126
|
private _entries;
|
|
@@ -123,11 +131,41 @@ declare class TempoMap {
|
|
|
123
131
|
secondsToTicks(seconds: number): number;
|
|
124
132
|
beatsToSeconds(beats: number): number;
|
|
125
133
|
secondsToBeats(seconds: number): number;
|
|
134
|
+
clearTempos(): void;
|
|
126
135
|
private _ticksToSecondsInternal;
|
|
127
136
|
private _entryAt;
|
|
128
137
|
private _recomputeCache;
|
|
129
138
|
}
|
|
130
139
|
|
|
140
|
+
declare class MeterMap {
|
|
141
|
+
private _ppqn;
|
|
142
|
+
private _entries;
|
|
143
|
+
constructor(ppqn: number, numerator?: number, denominator?: number);
|
|
144
|
+
get ppqn(): number;
|
|
145
|
+
getMeter(atTick?: number): MeterSignature;
|
|
146
|
+
setMeter(numerator: number, denominator: number, atTick?: number): void;
|
|
147
|
+
removeMeter(atTick: number): void;
|
|
148
|
+
clearMeters(): void;
|
|
149
|
+
ticksPerBeat(atTick?: number): number;
|
|
150
|
+
ticksPerBar(atTick?: number): number;
|
|
151
|
+
barToTick(bar: number): number;
|
|
152
|
+
tickToBar(tick: number): number;
|
|
153
|
+
isBarBoundary(tick: number): boolean;
|
|
154
|
+
/** Internal: get the full entry at a tick (for MetronomePlayer beat grid anchoring) */
|
|
155
|
+
getEntryAt(tick: number): MeterEntry;
|
|
156
|
+
private _entryAt;
|
|
157
|
+
private _ticksPerBarForEntry;
|
|
158
|
+
private _snapToBarBoundary;
|
|
159
|
+
private _computeBarAtTick;
|
|
160
|
+
private _recomputeCache;
|
|
161
|
+
/**
|
|
162
|
+
* After changing a meter entry, re-snap downstream entries to bar boundaries
|
|
163
|
+
* of their preceding meter so barAtTick stays integer.
|
|
164
|
+
*/
|
|
165
|
+
private _resnapDownstreamEntries;
|
|
166
|
+
private _validateMeter;
|
|
167
|
+
}
|
|
168
|
+
|
|
131
169
|
declare class MasterNode {
|
|
132
170
|
private _gainNode;
|
|
133
171
|
constructor(audioContext: AudioContext);
|
|
@@ -199,17 +237,15 @@ interface MetronomeEvent extends SchedulerEvent {
|
|
|
199
237
|
declare class MetronomePlayer implements SchedulerListener<MetronomeEvent> {
|
|
200
238
|
private _audioContext;
|
|
201
239
|
private _tempoMap;
|
|
202
|
-
private
|
|
240
|
+
private _meterMap;
|
|
203
241
|
private _destination;
|
|
204
242
|
private _toAudioTime;
|
|
205
243
|
private _enabled;
|
|
206
|
-
private _beatsPerBar;
|
|
207
244
|
private _accentBuffer;
|
|
208
245
|
private _normalBuffer;
|
|
209
246
|
private _activeSources;
|
|
210
|
-
constructor(audioContext: AudioContext, tempoMap: TempoMap,
|
|
247
|
+
constructor(audioContext: AudioContext, tempoMap: TempoMap, meterMap: MeterMap, destination: AudioNode, toAudioTime: (transportTime: number) => number);
|
|
211
248
|
setEnabled(enabled: boolean): void;
|
|
212
|
-
setBeatsPerBar(beats: number): void;
|
|
213
249
|
setClickSounds(accent: AudioBuffer, normal: AudioBuffer): void;
|
|
214
250
|
generate(fromTime: number, toTime: number): MetronomeEvent[];
|
|
215
251
|
consume(event: MetronomeEvent): void;
|
|
@@ -223,6 +259,7 @@ interface TransportEvents {
|
|
|
223
259
|
stop: () => void;
|
|
224
260
|
loop: () => void;
|
|
225
261
|
tempochange: () => void;
|
|
262
|
+
meterchange: () => void;
|
|
226
263
|
}
|
|
227
264
|
type TransportEventType = keyof TransportEvents;
|
|
228
265
|
declare class Transport {
|
|
@@ -231,7 +268,7 @@ declare class Transport {
|
|
|
231
268
|
private _scheduler;
|
|
232
269
|
private _timer;
|
|
233
270
|
private _sampleTimeline;
|
|
234
|
-
private
|
|
271
|
+
private _meterMap;
|
|
235
272
|
private _tempoMap;
|
|
236
273
|
private _clipPlayer;
|
|
237
274
|
private _metronomePlayer;
|
|
@@ -261,9 +298,19 @@ declare class Transport {
|
|
|
261
298
|
setTrackSolo(trackId: string, soloed: boolean): void;
|
|
262
299
|
setMasterVolume(volume: number): void;
|
|
263
300
|
setLoop(enabled: boolean, start: number, end: number): void;
|
|
264
|
-
setTempo(bpm: number): void;
|
|
265
|
-
getTempo(): number;
|
|
266
|
-
|
|
301
|
+
setTempo(bpm: number, atTick?: number): void;
|
|
302
|
+
getTempo(atTick?: number): number;
|
|
303
|
+
setMeter(numerator: number, denominator: number, atTick?: number): void;
|
|
304
|
+
getMeter(atTick?: number): MeterSignature;
|
|
305
|
+
removeMeter(atTick: number): void;
|
|
306
|
+
clearMeters(): void;
|
|
307
|
+
clearTempos(): void;
|
|
308
|
+
barToTick(bar: number): number;
|
|
309
|
+
tickToBar(tick: number): number;
|
|
310
|
+
/** Convert transport time (seconds) to tick position, using the tempo map. */
|
|
311
|
+
timeToTick(seconds: number): number;
|
|
312
|
+
/** Convert tick position to transport time (seconds), using the tempo map. */
|
|
313
|
+
tickToTime(tick: number): number;
|
|
267
314
|
setMetronomeEnabled(enabled: boolean): void;
|
|
268
315
|
setMetronomeClickSounds(accent: AudioBuffer, normal: AudioBuffer): void;
|
|
269
316
|
connectTrackOutput(trackId: string, node: AudioNode): void;
|
|
@@ -303,4 +350,4 @@ declare class NativePlayoutAdapter implements PlayoutAdapter {
|
|
|
303
350
|
dispose(): void;
|
|
304
351
|
}
|
|
305
352
|
|
|
306
|
-
export { type ClipEvent, ClipPlayer, Clock, MasterNode, type MetronomeEvent, MetronomePlayer, NativePlayoutAdapter, SampleTimeline, Scheduler, type SchedulerEvent, type SchedulerListener, type SchedulerOptions, type TempoEntry, TempoMap,
|
|
353
|
+
export { type ClipEvent, ClipPlayer, Clock, MasterNode, type MeterEntry, MeterMap, type MeterSignature, type MetronomeEvent, MetronomePlayer, NativePlayoutAdapter, SampleTimeline, Scheduler, type SchedulerEvent, type SchedulerListener, type SchedulerOptions, type TempoEntry, TempoMap, Timer, TrackNode, Transport, type TransportEvents, type TransportOptions, type TransportPosition };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,11 +22,29 @@ interface TransportOptions {
|
|
|
22
22
|
ppqn?: number;
|
|
23
23
|
/** Initial tempo in BPM. Default: 120 */
|
|
24
24
|
tempo?: number;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** Time signature numerator. Default: 4 */
|
|
26
|
+
numerator?: number;
|
|
27
|
+
/** Time signature denominator. Default: 4 */
|
|
28
|
+
denominator?: number;
|
|
27
29
|
/** How far ahead to schedule audio, in seconds. Default: 0.2 */
|
|
28
30
|
schedulerLookahead?: number;
|
|
29
31
|
}
|
|
32
|
+
/** Public return type for getMeter() */
|
|
33
|
+
interface MeterSignature {
|
|
34
|
+
numerator: number;
|
|
35
|
+
denominator: number;
|
|
36
|
+
}
|
|
37
|
+
/** Storage entry for MeterMap */
|
|
38
|
+
interface MeterEntry {
|
|
39
|
+
/** Tick position where this meter starts */
|
|
40
|
+
tick: number;
|
|
41
|
+
/** Time signature numerator (e.g., 6 in 6/8) */
|
|
42
|
+
numerator: number;
|
|
43
|
+
/** Time signature denominator (e.g., 8 in 6/8) */
|
|
44
|
+
denominator: number;
|
|
45
|
+
/** Cached cumulative bar count from tick 0 to this entry. Derived — do not set manually. */
|
|
46
|
+
readonly barAtTick: number;
|
|
47
|
+
}
|
|
30
48
|
interface TempoEntry {
|
|
31
49
|
/** Tick position where this tempo starts */
|
|
32
50
|
tick: number;
|
|
@@ -103,16 +121,6 @@ declare class SampleTimeline {
|
|
|
103
121
|
secondsToSamples(seconds: number): number;
|
|
104
122
|
}
|
|
105
123
|
|
|
106
|
-
declare class TickTimeline {
|
|
107
|
-
private _ppqn;
|
|
108
|
-
constructor(ppqn?: number);
|
|
109
|
-
get ppqn(): number;
|
|
110
|
-
ticksPerBeat(): number;
|
|
111
|
-
ticksPerBar(beatsPerBar: number): number;
|
|
112
|
-
toPosition(ticks: number, beatsPerBar: number): TransportPosition;
|
|
113
|
-
fromPosition(bar: number, beat: number, tick: number, beatsPerBar: number): number;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
124
|
declare class TempoMap {
|
|
117
125
|
private _ppqn;
|
|
118
126
|
private _entries;
|
|
@@ -123,11 +131,41 @@ declare class TempoMap {
|
|
|
123
131
|
secondsToTicks(seconds: number): number;
|
|
124
132
|
beatsToSeconds(beats: number): number;
|
|
125
133
|
secondsToBeats(seconds: number): number;
|
|
134
|
+
clearTempos(): void;
|
|
126
135
|
private _ticksToSecondsInternal;
|
|
127
136
|
private _entryAt;
|
|
128
137
|
private _recomputeCache;
|
|
129
138
|
}
|
|
130
139
|
|
|
140
|
+
declare class MeterMap {
|
|
141
|
+
private _ppqn;
|
|
142
|
+
private _entries;
|
|
143
|
+
constructor(ppqn: number, numerator?: number, denominator?: number);
|
|
144
|
+
get ppqn(): number;
|
|
145
|
+
getMeter(atTick?: number): MeterSignature;
|
|
146
|
+
setMeter(numerator: number, denominator: number, atTick?: number): void;
|
|
147
|
+
removeMeter(atTick: number): void;
|
|
148
|
+
clearMeters(): void;
|
|
149
|
+
ticksPerBeat(atTick?: number): number;
|
|
150
|
+
ticksPerBar(atTick?: number): number;
|
|
151
|
+
barToTick(bar: number): number;
|
|
152
|
+
tickToBar(tick: number): number;
|
|
153
|
+
isBarBoundary(tick: number): boolean;
|
|
154
|
+
/** Internal: get the full entry at a tick (for MetronomePlayer beat grid anchoring) */
|
|
155
|
+
getEntryAt(tick: number): MeterEntry;
|
|
156
|
+
private _entryAt;
|
|
157
|
+
private _ticksPerBarForEntry;
|
|
158
|
+
private _snapToBarBoundary;
|
|
159
|
+
private _computeBarAtTick;
|
|
160
|
+
private _recomputeCache;
|
|
161
|
+
/**
|
|
162
|
+
* After changing a meter entry, re-snap downstream entries to bar boundaries
|
|
163
|
+
* of their preceding meter so barAtTick stays integer.
|
|
164
|
+
*/
|
|
165
|
+
private _resnapDownstreamEntries;
|
|
166
|
+
private _validateMeter;
|
|
167
|
+
}
|
|
168
|
+
|
|
131
169
|
declare class MasterNode {
|
|
132
170
|
private _gainNode;
|
|
133
171
|
constructor(audioContext: AudioContext);
|
|
@@ -199,17 +237,15 @@ interface MetronomeEvent extends SchedulerEvent {
|
|
|
199
237
|
declare class MetronomePlayer implements SchedulerListener<MetronomeEvent> {
|
|
200
238
|
private _audioContext;
|
|
201
239
|
private _tempoMap;
|
|
202
|
-
private
|
|
240
|
+
private _meterMap;
|
|
203
241
|
private _destination;
|
|
204
242
|
private _toAudioTime;
|
|
205
243
|
private _enabled;
|
|
206
|
-
private _beatsPerBar;
|
|
207
244
|
private _accentBuffer;
|
|
208
245
|
private _normalBuffer;
|
|
209
246
|
private _activeSources;
|
|
210
|
-
constructor(audioContext: AudioContext, tempoMap: TempoMap,
|
|
247
|
+
constructor(audioContext: AudioContext, tempoMap: TempoMap, meterMap: MeterMap, destination: AudioNode, toAudioTime: (transportTime: number) => number);
|
|
211
248
|
setEnabled(enabled: boolean): void;
|
|
212
|
-
setBeatsPerBar(beats: number): void;
|
|
213
249
|
setClickSounds(accent: AudioBuffer, normal: AudioBuffer): void;
|
|
214
250
|
generate(fromTime: number, toTime: number): MetronomeEvent[];
|
|
215
251
|
consume(event: MetronomeEvent): void;
|
|
@@ -223,6 +259,7 @@ interface TransportEvents {
|
|
|
223
259
|
stop: () => void;
|
|
224
260
|
loop: () => void;
|
|
225
261
|
tempochange: () => void;
|
|
262
|
+
meterchange: () => void;
|
|
226
263
|
}
|
|
227
264
|
type TransportEventType = keyof TransportEvents;
|
|
228
265
|
declare class Transport {
|
|
@@ -231,7 +268,7 @@ declare class Transport {
|
|
|
231
268
|
private _scheduler;
|
|
232
269
|
private _timer;
|
|
233
270
|
private _sampleTimeline;
|
|
234
|
-
private
|
|
271
|
+
private _meterMap;
|
|
235
272
|
private _tempoMap;
|
|
236
273
|
private _clipPlayer;
|
|
237
274
|
private _metronomePlayer;
|
|
@@ -261,9 +298,19 @@ declare class Transport {
|
|
|
261
298
|
setTrackSolo(trackId: string, soloed: boolean): void;
|
|
262
299
|
setMasterVolume(volume: number): void;
|
|
263
300
|
setLoop(enabled: boolean, start: number, end: number): void;
|
|
264
|
-
setTempo(bpm: number): void;
|
|
265
|
-
getTempo(): number;
|
|
266
|
-
|
|
301
|
+
setTempo(bpm: number, atTick?: number): void;
|
|
302
|
+
getTempo(atTick?: number): number;
|
|
303
|
+
setMeter(numerator: number, denominator: number, atTick?: number): void;
|
|
304
|
+
getMeter(atTick?: number): MeterSignature;
|
|
305
|
+
removeMeter(atTick: number): void;
|
|
306
|
+
clearMeters(): void;
|
|
307
|
+
clearTempos(): void;
|
|
308
|
+
barToTick(bar: number): number;
|
|
309
|
+
tickToBar(tick: number): number;
|
|
310
|
+
/** Convert transport time (seconds) to tick position, using the tempo map. */
|
|
311
|
+
timeToTick(seconds: number): number;
|
|
312
|
+
/** Convert tick position to transport time (seconds), using the tempo map. */
|
|
313
|
+
tickToTime(tick: number): number;
|
|
267
314
|
setMetronomeEnabled(enabled: boolean): void;
|
|
268
315
|
setMetronomeClickSounds(accent: AudioBuffer, normal: AudioBuffer): void;
|
|
269
316
|
connectTrackOutput(trackId: string, node: AudioNode): void;
|
|
@@ -303,4 +350,4 @@ declare class NativePlayoutAdapter implements PlayoutAdapter {
|
|
|
303
350
|
dispose(): void;
|
|
304
351
|
}
|
|
305
352
|
|
|
306
|
-
export { type ClipEvent, ClipPlayer, Clock, MasterNode, type MetronomeEvent, MetronomePlayer, NativePlayoutAdapter, SampleTimeline, Scheduler, type SchedulerEvent, type SchedulerListener, type SchedulerOptions, type TempoEntry, TempoMap,
|
|
353
|
+
export { type ClipEvent, ClipPlayer, Clock, MasterNode, type MeterEntry, MeterMap, type MeterSignature, type MetronomeEvent, MetronomePlayer, NativePlayoutAdapter, SampleTimeline, Scheduler, type SchedulerEvent, type SchedulerListener, type SchedulerOptions, type TempoEntry, TempoMap, Timer, TrackNode, Transport, type TransportEvents, type TransportOptions, type TransportPosition };
|