diff --git a/src/API.ts b/src/API.ts
index cd94a7c..6de4545 100644
--- a/src/API.ts
+++ b/src/API.ts
@@ -383,6 +383,11 @@ export class UserAPI {
player.updateLastCallTime();
+ if(id !== "") {
+ // Sync named patterns to z0 by default
+ player.sync("z0");
+ }
+
return player;
};
diff --git a/src/classes/AbstractEvents.ts b/src/classes/AbstractEvents.ts
index 9c457d2..58417f9 100644
--- a/src/classes/AbstractEvents.ts
+++ b/src/classes/AbstractEvents.ts
@@ -74,8 +74,8 @@ export abstract class Event {
return this.modify(func);
};
- duration = (value: number): Event => {
- this.values["duration"] = value;
+ length = (value: number): Event => {
+ this.values["length"] = value;
return this;
};
}
diff --git a/src/classes/RestEvent.ts b/src/classes/RestEvent.ts
index 9d52711..4f4ec53 100644
--- a/src/classes/RestEvent.ts
+++ b/src/classes/RestEvent.ts
@@ -2,20 +2,20 @@ import { type Editor } from "../main";
import { Event } from "./AbstractEvents";
export class RestEvent extends Event {
- constructor(duration: number, app: Editor) {
+ constructor(length: number, app: Editor) {
super(app);
- this.values["duration"] = duration;
+ this.values["length"] = length;
}
_fallbackMethod = (): Event => {
- return RestEvent.createRestProxy(this.values["duration"], this.app);
+ return RestEvent.createRestProxy(this.values["length"], this.app);
};
public static createRestProxy = (
- duration: number,
+ length: number,
app: Editor
): RestEvent => {
- const instance = new RestEvent(duration, app);
+ const instance = new RestEvent(length, app);
return new Proxy(instance, {
// @ts-ignore
get(target, propKey, receiver) {
diff --git a/src/classes/ZPlayer.ts b/src/classes/ZPlayer.ts
index 248ba50..fc573aa 100644
--- a/src/classes/ZPlayer.ts
+++ b/src/classes/ZPlayer.ts
@@ -11,9 +11,9 @@ export type InputOptions = { [key: string]: string | number };
export class Player extends Event {
input: string;
ziffers: Ziffers;
- initCallTime: number = 1;
- startCallTime: number = 1;
- lastCallTime: number = 1;
+ initCallTime: number = 0;
+ startCallTime: number = 0;
+ lastCallTime: number = 0;
waitTime = 0;
startBeat: number = 0;
played: boolean = false;
@@ -98,6 +98,7 @@ export class Player extends Event {
this.startCallTime = 0;
this.index = 0;
this.waitTime = 0;
+ this.skipIndex = 0;
}
// Main logic
@@ -207,6 +208,23 @@ export class Player extends Event {
return this;
}
+ sync(value: string|Function) {
+ if(this.atTheBeginning() && this.notStarted()) {
+ const origin = this.app.clock.pulses_since_origin;
+ const syncId = typeof value === "function" ? value.name : value;
+ if(origin>0) {
+ const syncPattern = this.app.api.patternCache.get(syncId) as Player;
+ if(syncPattern) {
+ const syncPatternDuration = syncPattern.ziffers.duration;
+ const syncPatternStart = syncPattern.startCallTime;
+ const syncInPulses = syncPatternDuration*4*this.app.clock.ppqn;
+ this.waitTime = syncPatternStart + syncInPulses;
+ }
+ }
+ }
+ return this;
+ }
+
out = (): void => {
// TODO?
};
diff --git a/src/documentation/ziffers.ts b/src/documentation/ziffers.ts
index c344070..e4d492e 100644
--- a/src/documentation/ziffers.ts
+++ b/src/documentation/ziffers.ts
@@ -86,7 +86,7 @@ Ziffers provides shorthands for **many** numeric and algorithimic operations suc
* **List operations:** Cartesian operation (_e.g._ (3 2 1)+(2 5)) using the + operator. All the arithmetic operators are supported.
${makeExample(
- "Cartesian operation for melodic generation",
+ "Element-wise operations for melodic generation",
`
z1("q 0 s (3 2 1)+(2 5) q 0 s (4 5 6)-(2 3)").sound('sine')
.scale('minor').fmi(2).fmh(2).room(0.5).size(0.5).sustain(0.1)
@@ -192,7 +192,38 @@ mod(1, 1.75) :: snd(['kick', 'hat'].div(1)).out()
## Synchronization
-Ziffers numbered methods **(z0-z16)** can be used to parse and play patterns. Each method is individually cached and can be used to play multiple patterns simultaneously. They can be synchronized together by using a **cue** system. By default, each Ziffers expression will have a different duration. This system is thus necessary to make everything fit together in a loop-based environment like Topos.
+Ziffers numbered methods **(z0-z16)** can be used to parse and play patterns. Each method is individually cached and can be used to play multiple patterns simultaneously. By default, each Ziffers expression can have a different duration. This system is thus necessary to make everything fit together in a loop-based environment like Topos.
+
+Numbered methods are synced automatically to **z0** method if it exsists. Syncing can also be done manually by using either the wait method, which will always wait for the current pattern to finish before starting the next cycle, or the sync method will only wait for the synced pattern to finish on the first time.
+
+${makeExample(
+ "Automatic sync to z0",
+ `
+z0('w 0 8').sound('peri').gain(3.0).out()
+z1('e 0 4 5 9').sound('bell').gain(6.0).out()
+`,
+ true
+)}
+
+${makeExample(
+ "Sync with wait",
+ `
+z1('w 0 5').sound('pluck').release(0.1).sustain(0.25).out()
+z2('q 6 3').wait(z1).sound('sine').release(0.16).sustain(0.55).out()
+`,
+ true
+)}
+
+${makeExample(
+ "Sync on first run",
+ `
+ z1('w __ 0 5 9 3').sound('bin').out()
+ z2('q __ 4 2 e 6 3 q 6').sync(z1).sound('east').out()
+`,
+ true
+)}
+
+
## Examples