Skip to content

Commit

Permalink
feat: 初步实现步进器
Browse files Browse the repository at this point in the history
  • Loading branch information
KazariEX committed Feb 12, 2024
1 parent 12fd308 commit 3796bde
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default defineConfig({
{
text: "缓动",
link: "/advance/easing"
},
{
text: "步进",
link: "/advance/stepper"
}
]
}
Expand Down
46 changes: 46 additions & 0 deletions docs/advance/stepper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: 步进
---

# {{ $frontmatter.title }}

步进器用于按照指定的节奏模式生成时间片段。按照以下方式导入:

```javascript
import { Stepper } from "zaff";
```

## 基本用法

初始化步进器时,既可以传入一个配置对象,也可以直接传入一个 Timing:

```javascript
const stepper = new Stepper({
time: 2333,
bpm: 185,
beats: 4
});

// const timing = Aff.timing(...);
const stepper = new Stepper(timing);
```

在步进器上挂载了一个核心方法 ``generate()``,如果我们想生成 332 的节奏型,则可以这么做:

```javascript
const it = stepper.generate([3, 3, 2], {
noteValue: 8,
timeEnd: 7777
});
```

第一个参数 ``pattern`` 即为期望的节奏型数组,它表示依次按照 3 个音符、3 个音符、2 个音符的模式循环生成时间戳。第二个参数为配置对象,其中 ``noteValue`` 属性表示音符值,如 ``noteValue: 8`` 表示以 8 分音符为前者的基准,如果缺省则默认取步进器上的 ``beats`` 属性值。

这个方法实际上是一个 Generator 函数,使用 ``for ... of ...`` 来运行返回的遍历器对象,便可以生成相应的时间片段了:

```javascript
for (const time of it) {
console.log(Math.floor(time));
}
// 2333, 2819, 3305, 3630, 4116, 4603, 4927...
```
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Aff from "./aff.js";
import * as Easing from "./utils/easing.js";
import Stepper from "./utils/stepper.js";

declare global {
type EasingType = "b" | "l" | "qi" | "qo" | "reset" | "s" | "si" | "so" | "sisi" | "siso" | "sosi" | "soso";
Expand Down Expand Up @@ -71,5 +72,6 @@ declare global {
export default Aff;
export {
Aff,
Easing
Easing,
Stepper
};
39 changes: 39 additions & 0 deletions src/utils/stepper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Timing from "../note/timing.js";

class Stepper {
time: number;
bpm: number;
beats: number;

constructor(timing: Timing);
constructor(options: TimingOptions);
constructor({
time = 0,
bpm = 0,
beats = 0
}: Timing | TimingOptions = {}) {
this.time = time;
this.bpm = bpm;
this.beats = beats;
}

* generate(pattern: number[], {
noteValue = this.beats,
timeEnd = Infinity
} = {}) {
const duration = 240000 / this.bpm / noteValue;

if (!pattern || pattern.length === 0) {
pattern = [1];
}

let time = this.time;
for (let i = 0; time < timeEnd; i++, i %= pattern.length) {
yield time;
time += duration * pattern[i];
}
return time;
}
}

export default Stepper;

0 comments on commit 3796bde

Please sign in to comment.