File size: 2,382 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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { IPoint } from "../geometry"
import { NoteEvent } from "../track"
import { NotePoint } from "./NotePoint"

export default class NoteCoordTransform {
  private _pixelsPerTick: number
  private _pixelsPerKey: number
  private _maxNoteNumber: number

  constructor(
    pixelsPerTick: number,
    pixelsPerKey: number,
    maxNoteNumber: number,
  ) {
    this._pixelsPerTick = pixelsPerTick
    this._pixelsPerKey = pixelsPerKey
    this._maxNoteNumber = maxNoteNumber
  }

  // pixels

  getX(tick: number) {
    return tick * this._pixelsPerTick
  }

  getY(noteNumber: number) {
    return (this._maxNoteNumber - noteNumber) * this._pixelsPerKey
  }

  getDeltaY(deltaNoteNumber: number) {
    return -deltaNoteNumber * this._pixelsPerKey
  }

  get pixelsPerTick() {
    return this._pixelsPerTick
  }

  // ticks

  getTicks(pixels: number) {
    return pixels / this._pixelsPerTick
  }

  getNoteNumber(pixels: number) {
    return Math.ceil(this.getNoteNumberFractional(pixels))
  }

  getNoteNumberFractional(pixels: number) {
    return this._maxNoteNumber - pixels / this._pixelsPerKey
  }

  getDeltaNoteNumber(deltaPixels: number) {
    return -deltaPixels / this._pixelsPerKey
  }

  get maxNoteNumber() {
    return this._maxNoteNumber
  }

  get numberOfKeys() {
    return this._maxNoteNumber + 1
  }

  get pixelsPerKey() {
    return this._pixelsPerKey
  }

  //

  getMaxY() {
    return (this._maxNoteNumber + 1) * this._pixelsPerKey
  }

  getRect(note: NoteEvent) {
    return {
      x: this.getX(note.tick),
      y: this.getY(note.noteNumber),
      width: this.getX(note.duration),
      height: this._pixelsPerKey,
    }
  }

  getDrumRect(note: NoteEvent) {
    return {
      x: this.getX(note.tick) - this._pixelsPerKey / 2,
      y: this.getY(note.noteNumber),
      width: this._pixelsPerKey,
      height: this._pixelsPerKey,
    }
  }

  getNotePoint(pos: IPoint): NotePoint {
    return {
      tick: this.getTicks(pos.x),
      noteNumber: this.getNoteNumber(pos.y),
    }
  }

  getNotePointFractional(pos: IPoint): NotePoint {
    return {
      tick: this.getTicks(pos.x),
      noteNumber: this.getNoteNumberFractional(pos.y),
    }
  }

  equals(t: NoteCoordTransform) {
    return (
      this.pixelsPerKey === t.pixelsPerKey &&
      this.pixelsPerTick === t.pixelsPerTick &&
      this.maxNoteNumber === t.maxNoteNumber
    )
  }
}