-
Notifications
You must be signed in to change notification settings - Fork 0
/
stereo.js
88 lines (79 loc) · 2.55 KB
/
stereo.js
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
const fluid = require('fluid-music')
/**
* @typedef {import('fluid-music').UseContext} UseContext
* @typedef {import('fluid-music').FluidTrack} FluidTrack
* @typedef {Object} AutomationPoint
* @property {number} startTime
* @property {number} value
* @property {number} curve
*/
/**
* Get the active automation point at a particular time. If there are no
* automation points before a particular time, create and return a point with
* the track's width. Note that if an automation point is created in this way,
* if you change its values, they will not be reflected in the track.
*
* @param {FluidTrack} track
* @param {number} time Time measured in whole notes
* @returns {AutomationPoint}
*/
function getWidthAtTime(track, time) {
// Charles: In the code below, we check `if point.startTime === 0`, but this
// shouldn't be relied on.
let candidate = {
value: track.width,
curve: 0,
startTime: 0
}
if (track.automation.width) {
for (const point of track.automation.width.points) {
if (point.startTime >= candidate.startTime && point.startTime <= time) {
candidate = point
}
}
}
return candidate
}
/**
* A WidthRamp inserts two automation points, ramping the width from it's
* starting value to the 'target' over the course of the event.
*/
class WidthRamp {
/**
* @param {number} target bipolar stereo width: 1=normal 0=mono -1=reversed
* @param {number} curve
*/
constructor (target, curve = 0) {
if (typeof target !== 'number') {
throw new Error('WidthRamp constructor expected an number')
}
this.target = target
this.curve = curve
}
/**
* @param {UseContext} context
*/
use(context) {
const point = getWidthAtTime(context.track, context.startTime)
if (point.startTime === 0 || point.startTime !== context.startTime) {
const params = { paramKey: 'width', curve: this.curve , value: point.value }
const point1 = new fluid.techniques.TrackAutomation(params)
point1.use(context)
}
context.startTime = context.startTime + context.duration
context.startTimeSeconds = context.startTimeSeconds + context.durationSeconds
const params = { paramKey: 'width', curve: 0, value: this.target }
const point2 = new fluid.techniques.TrackAutomation(params)
point2.use(context)
}
}
const tLibrary = {
'<': new WidthRamp(1), // ramp to stereo
'>': new WidthRamp(0), // ramp to mono
'=': new WidthRamp(0.5), // ramp to 'half' stereo
'I': new WidthRamp(-1), // ramp to swap left<->right
}
module.exports = {
tLibrary,
WidthRamp,
}