File size: 1,256 Bytes
f23825d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { SongStore } from "../../main/stores/SongStore"
import { getMeasureStart } from "../song/selector"

export default class Quantizer {
  private denominator: number
  private songStore: SongStore
  private isEnabled: boolean = true

  constructor(songStore: SongStore, denominator: number, isEnabled: boolean) {
    this.songStore = songStore

    // N 分音符の N
    // n-remnant note n
    this.denominator = denominator

    this.isEnabled = isEnabled
  }

  private get timebase() {
    return this.songStore.song.timebase
  }

  private calc(tick: number, fn: (tick: number) => number) {
    if (!this.isEnabled) {
      return Math.round(tick)
    }
    const measureStart = getMeasureStart(this.songStore.song, tick)
    const beats =
      this.denominator === 1 ? measureStart?.timeSignature.numerator ?? 4 : 4
    const u = (this.timebase * beats) / this.denominator
    const offset = measureStart?.tick ?? 0
    return fn((tick - offset) / u) * u + offset
  }

  round(tick: number) {
    return this.calc(tick, Math.round)
  }

  ceil(tick: number) {
    return this.calc(tick, Math.ceil)
  }

  floor(tick: number) {
    return this.calc(tick, Math.floor)
  }

  get unit() {
    return (this.timebase * 4) / this.denominator
  }
}