-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlogUnit.js
More file actions
126 lines (121 loc) · 5.75 KB
/
logUnit.js
File metadata and controls
126 lines (121 loc) · 5.75 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
// logUnit.js - Logs timing markers with context awareness, writing to active buffer (c = c1 or c2) for proper file separation.
const V = validator.create('logUnit');
/**
* Logs timing markers with context awareness.
* Writes to active buffer (c = c1 or c2) for proper file separation.
*
* @param {string} type - Unit type: 'section', 'phrase', 'measure', 'beat', 'division', 'subdiv', 'subsubdiv'
*/
logUnit = (type) => {
let shouldLog = false;
type = type.toLowerCase();
// Localize all per-unit variables to avoid accidental global mutation across calls
let unit = null;
let unitsPerParent = null;
let startTime = null;
let endTime = null;
let composerDetails = '';
let progressionSymbols = '';
let actualMeter = null;
let meterInfo = '';
V.requireDefined(LM, 'LM');
V.assertObject(LM.layers, 'LM.layers');
V.assertNonEmptyString(LM.activeLayer, 'LM.activeLayer');
const activeLayerName = /** @type {string} */ (LM.activeLayer);
const activeLayerObj = LM.layers[activeLayerName];
const composerForLog = (activeLayerObj && activeLayerObj.measureComposer && typeof activeLayerObj.measureComposer === 'object')
? activeLayerObj.measureComposer
: composer;
if (LOG === 'none') shouldLog = false;
else if (LOG === 'all') shouldLog = true;
else {
const logList = LOG.toLowerCase().split(',').map(item => item.trim());
shouldLog = logList.length === 1 ? logList[0] === type : logList.includes(type);
}
if (!shouldLog) return null;
if (type === 'section') {
unit = sectionIndex + 1;
unitsPerParent = totalSections;
// Ensure we always have a safe numeric start for sections.
startTime = sectionStartTime;
// Section duration not known this early in the loop.
} else if (type === 'phrase') {
unit = phraseIndex + 1;
unitsPerParent = phrasesPerSection;
startTime = phraseStartTime;
endTime = startTime + spPhrase;
composerDetails = composerForLog ? `${composerForLog.constructor.name} ` : 'Unknown Composer ';
if (composerForLog && composerForLog.scale && composerForLog.scale.name) {
composerDetails += `${composerForLog.root} ${composerForLog.scale.name}`;
} else if (composerForLog && composerForLog.progression) {
progressionSymbols = composerForLog.progression.map(chord => {
return chord && chord.symbol ? chord.symbol : '[Unknown Symbol]';
}).join(' ');
composerDetails += `${progressionSymbols}`;
} else if (composerForLog && composerForLog.mode && composerForLog.mode.name) {
composerDetails += `${composerForLog.root} ${composerForLog.mode.name}`;
}
actualMeter = [numerator, denominator];
try {
if (Array.isArray(midiMeter) && midiMeter[1] === actualMeter[1]) {
meterInfo = `Meter: ${actualMeter.join('/')} Composer: ${composerDetails} BPM: ${trueBPM}`;
} else {
meterInfo = `Actual Meter: ${actualMeter.join('/')} MIDI Meter: ${Array.isArray(midiMeter) ? midiMeter.join('/') : String(midiMeter)} Composer: ${composerDetails} BPM: ${trueBPM}`;
}
} catch { meterInfo = `Meter: ${actualMeter.join('/')} Composer: ${composerDetails} BPM: ${trueBPM}`; }
} else if (type === 'measure') {
unit = measureIndex + 1;
unitsPerParent = measuresPerPhrase;
startTime = measureStartTime;
endTime = measureStartTime + spMeasure;
composerDetails = composerForLog ? `${composerForLog.constructor.name} ` : 'Unknown Composer ';
if (composerForLog && composerForLog.scale && composerForLog.scale.name) {
composerDetails += `${composerForLog.root} ${composerForLog.scale.name}`;
} else if (composerForLog && composerForLog.progression) {
progressionSymbols = composerForLog.progression.map(chord => {
return chord && chord.symbol ? chord.symbol : '[Unknown Symbol]';
}).join(' ');
composerDetails += `${progressionSymbols}`;
} else if (composerForLog && composerForLog.mode && composerForLog.mode.name) {
composerDetails += `${composerForLog.root} ${composerForLog.mode.name}`;
}
actualMeter = [numerator, denominator];
try {
if (Array.isArray(midiMeter) && midiMeter[1] === actualMeter[1]) {
meterInfo = `Meter: ${actualMeter.join('/')} Composer: ${composerDetails} BPM: ${trueBPM}`;
} else {
meterInfo = `Actual Meter: ${actualMeter.join('/')} MIDI Meter: ${Array.isArray(midiMeter) ? midiMeter.join('/') : String(midiMeter)} Composer: ${composerDetails} BPM: ${trueBPM}`;
}
} catch { meterInfo = `Meter: ${actualMeter.join('/')} Composer: ${composerDetails} BPM: ${trueBPM}`; }
} else if (type === 'beat') {
unit = beatIndex + 1;
unitsPerParent = numerator;
startTime = beatStartTime;
endTime = startTime + spBeat;
} else if (type === 'division') {
unit = divIndex + 1;
unitsPerParent = divsPerBeat;
startTime = divStartTime;
endTime = startTime + spDiv;
} else if (type === 'subdiv') {
unit = subdivIndex + 1;
unitsPerParent = subdivsPerDiv;
startTime = subdivStartTime;
endTime = startTime + spSubdiv;
} else if (type === 'subsubdiv') {
// Use defensively coerced indices/totals to avoid NaN/undefined emissions
const sIndex = subsubdivIndex;
unit = sIndex + 1;
// Prefer canonical name `subsubsPerSub` but accept legacy `subsubsPerSub` if present
unitsPerParent = subsubsPerSub;
startTime = subsubdivStartTime;
endTime = startTime + spSubsubdiv;
}
return (() => {
c.push({
timeInSeconds: startTime ?? 0,
type: 'marker_t',
vals: [`${activeLayerName} ${type.charAt(0).toUpperCase() + type.slice(1)} ${unit}/${unitsPerParent} ${endTime === null || startTime === null ? `Start: ${formatTime(startTime ?? 0)}` : `Length: ${formatTime(endTime - startTime)} (${formatTime(startTime)} - ${formatTime(endTime)})`} ${meterInfo ? meterInfo : ''}`]
});
})();
};