Gather and offset comments in repeated intervals
This commit is contained in:
parent
a30b020ac9
commit
46b2c1198f
|
|
@ -143,4 +143,74 @@ describe("detectRepeats()", () => {
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual(intervals);
|
expect(detectRepeats(intervals)).toEqual(intervals);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("gathers comments together", () => {
|
||||||
|
const intervals: Interval[] = [
|
||||||
|
{
|
||||||
|
type: "Interval",
|
||||||
|
duration: new Seconds(100),
|
||||||
|
intensity: { from: 1, to: 1 },
|
||||||
|
comments: [
|
||||||
|
{ offset: new Seconds(0), text: "Let's start" },
|
||||||
|
{ offset: new Seconds(20), text: "Stay strong!" },
|
||||||
|
{ offset: new Seconds(90), text: "Finish it!" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "Rest",
|
||||||
|
duration: new Seconds(100),
|
||||||
|
intensity: { from: 0.5, to: 0.5 },
|
||||||
|
comments: [
|
||||||
|
{ offset: new Seconds(0), text: "Huh... have a rest" },
|
||||||
|
{ offset: new Seconds(80), text: "Ready for next?" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "Interval",
|
||||||
|
duration: new Seconds(100),
|
||||||
|
intensity: { from: 1, to: 1 },
|
||||||
|
comments: [
|
||||||
|
{ offset: new Seconds(0), text: "Bring it on again!" },
|
||||||
|
{ offset: new Seconds(50), text: "Half way" },
|
||||||
|
{ offset: new Seconds(90), text: "Almost there!" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "Rest",
|
||||||
|
duration: new Seconds(100),
|
||||||
|
intensity: { from: 0.5, to: 0.5 },
|
||||||
|
comments: [
|
||||||
|
{ offset: new Seconds(30), text: "Wow... you did it!" },
|
||||||
|
{ offset: new Seconds(40), text: "Nice job." },
|
||||||
|
{ offset: new Seconds(50), text: "Until next time..." },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expect(detectRepeats(intervals)).toEqual([
|
||||||
|
{
|
||||||
|
type: "repeat",
|
||||||
|
times: 2,
|
||||||
|
intervals: [
|
||||||
|
{ type: "Interval", duration: new Seconds(100), intensity: { from: 1, to: 1 }, comments: [] },
|
||||||
|
{ type: "Rest", duration: new Seconds(100), intensity: { from: 0.5, to: 0.5 }, comments: [] },
|
||||||
|
],
|
||||||
|
comments: [
|
||||||
|
{ offset: new Seconds(0), text: "Let's start" },
|
||||||
|
{ offset: new Seconds(20), text: "Stay strong!" },
|
||||||
|
{ offset: new Seconds(90), text: "Finish it!" },
|
||||||
|
|
||||||
|
{ offset: new Seconds(100), text: "Huh... have a rest" },
|
||||||
|
{ offset: new Seconds(180), text: "Ready for next?" },
|
||||||
|
|
||||||
|
{ offset: new Seconds(200), text: "Bring it on again!" },
|
||||||
|
{ offset: new Seconds(250), text: "Half way" },
|
||||||
|
{ offset: new Seconds(290), text: "Almost there!" },
|
||||||
|
|
||||||
|
{ offset: new Seconds(330), text: "Wow... you did it!" },
|
||||||
|
{ offset: new Seconds(340), text: "Nice job." },
|
||||||
|
{ offset: new Seconds(350), text: "Until next time..." },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { equals } from "ramda";
|
import { eqProps, flatten, zip } from "ramda";
|
||||||
import { Interval, Comment } from "./ast";
|
import { Interval, Comment } from "./ast";
|
||||||
|
import { Seconds } from "./types";
|
||||||
|
|
||||||
export type RepeatedInterval = {
|
export type RepeatedInterval = {
|
||||||
type: "repeat";
|
type: "repeat";
|
||||||
|
|
@ -8,6 +9,13 @@ export type RepeatedInterval = {
|
||||||
comments: Comment[];
|
comments: Comment[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// All fields besides comments must equal
|
||||||
|
const equalIntervals = (a: Interval, b: Interval): boolean =>
|
||||||
|
eqProps("type", a, b) && eqProps("duration", a, b) && eqProps("intensity", a, b) && eqProps("cadence", a, b);
|
||||||
|
|
||||||
|
const equalIntervalArrays = (as: Interval[], bs: Interval[]): boolean =>
|
||||||
|
zip(as, bs).every(([a, b]) => equalIntervals(a, b));
|
||||||
|
|
||||||
const windowSize = 2;
|
const windowSize = 2;
|
||||||
|
|
||||||
const countRepetitions = (reference: Interval[], intervals: Interval[], startIndex: number): number => {
|
const countRepetitions = (reference: Interval[], intervals: Interval[], startIndex: number): number => {
|
||||||
|
|
@ -15,7 +23,7 @@ const countRepetitions = (reference: Interval[], intervals: Interval[], startInd
|
||||||
while (startIndex + repeats * windowSize < intervals.length) {
|
while (startIndex + repeats * windowSize < intervals.length) {
|
||||||
const from = startIndex + repeats * windowSize;
|
const from = startIndex + repeats * windowSize;
|
||||||
const possibleRepeat = intervals.slice(from, from + windowSize);
|
const possibleRepeat = intervals.slice(from, from + windowSize);
|
||||||
if (equals(reference, possibleRepeat)) {
|
if (equalIntervalArrays(reference, possibleRepeat)) {
|
||||||
repeats++;
|
repeats++;
|
||||||
} else {
|
} else {
|
||||||
return repeats;
|
return repeats;
|
||||||
|
|
@ -24,6 +32,28 @@ const countRepetitions = (reference: Interval[], intervals: Interval[], startInd
|
||||||
return repeats;
|
return repeats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const offsetComments = (interval: Interval, baseOffset: Seconds): Comment[] => {
|
||||||
|
return interval.comments.map(({ offset, ...rest }) => ({
|
||||||
|
offset: new Seconds(baseOffset.value + offset.value),
|
||||||
|
...rest,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const collectComments = (intervals: Interval[]): Comment[] => {
|
||||||
|
let previousIntervalsDuration = new Seconds(0);
|
||||||
|
return flatten(
|
||||||
|
intervals.map((interval) => {
|
||||||
|
const comments = offsetComments(interval, previousIntervalsDuration);
|
||||||
|
previousIntervalsDuration = new Seconds(previousIntervalsDuration.value + interval.duration.value);
|
||||||
|
return comments;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const stripComments = (intervals: Interval[]): Interval[] => {
|
||||||
|
return intervals.map(({ comments, ...rest }) => ({ comments: [], ...rest }));
|
||||||
|
};
|
||||||
|
|
||||||
const isRangeInterval = (interval: Interval): boolean => interval.intensity.from !== interval.intensity.to;
|
const isRangeInterval = (interval: Interval): boolean => interval.intensity.from !== interval.intensity.to;
|
||||||
|
|
||||||
export const detectRepeats = (intervals: Interval[]): (Interval | RepeatedInterval)[] => {
|
export const detectRepeats = (intervals: Interval[]): (Interval | RepeatedInterval)[] => {
|
||||||
|
|
@ -47,8 +77,8 @@ export const detectRepeats = (intervals: Interval[]): (Interval | RepeatedInterv
|
||||||
processed.push({
|
processed.push({
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: repeats,
|
times: repeats,
|
||||||
intervals: reference,
|
intervals: stripComments(reference),
|
||||||
comments: [],
|
comments: collectComments(intervals.slice(i, i + windowSize * repeats)),
|
||||||
});
|
});
|
||||||
i += repeats * windowSize;
|
i += repeats * windowSize;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue