first
This commit is contained in:
parent
fb72bb2290
commit
40f2355fbf
5 changed files with 233 additions and 0 deletions
0
js/package.json
Normal file
0
js/package.json
Normal file
138
js/strudel.js
Normal file
138
js/strudel.js
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import Fraction from 'fraction.js'
|
||||
|
||||
Fraction.prototype.sam = function() {
|
||||
return Fraction(Math.floor(this))
|
||||
}
|
||||
|
||||
Fraction.prototype.lt = function(other) {
|
||||
return this.compare(other) < 0
|
||||
}
|
||||
|
||||
Fraction.prototype.lte = function(other) {
|
||||
return this.compare(other) <= 0
|
||||
}
|
||||
|
||||
Fraction.prototype.gte = function(other) {
|
||||
return this.compare(other) >= 0
|
||||
}
|
||||
|
||||
class TimeSpan {
|
||||
constructor(begin, end) {
|
||||
this.begin = Fraction(begin)
|
||||
this.end = Fraction(end)
|
||||
}
|
||||
|
||||
get spanCycles() {
|
||||
var spans = []
|
||||
var begin = this.begin
|
||||
var end = this.end
|
||||
var end_sam = end.sam()
|
||||
|
||||
while (end.gt(begin)) {
|
||||
// If begin and end are in the same cycle, we're done.
|
||||
if (begin.sam() == end_sam) {
|
||||
spans.push(new TimeSpan(begin, this.end))
|
||||
break
|
||||
}
|
||||
// add a timespan up to the next sam
|
||||
var next_begin = begin.next_sam()
|
||||
spans.push(TimeSpan(begin, next_begin))
|
||||
|
||||
// continue with the next cycle
|
||||
begin = next_begin
|
||||
}
|
||||
return(spans)
|
||||
}
|
||||
|
||||
withTime(func_time) {
|
||||
// Applies given function to both the begin and end time value of the timespan"""
|
||||
return(new TimeSpan(func_time(this.begin), func_time(this.end)))
|
||||
}
|
||||
|
||||
intersection(other) {
|
||||
// Intersection of two timespans, returns None if they don't intersect.
|
||||
intersect_begin = Math.max(this.begin, other.begin)
|
||||
intersect_end = Math.min(this.end, other.end)
|
||||
|
||||
if (intersect_begin.gt(intersect_end)) {
|
||||
return(undefined)
|
||||
}
|
||||
if (intersect_begin.equals(intersect_end)) {
|
||||
// Zero-width (point) intersection - doesn't intersect if it's at the end of a
|
||||
// non-zero-width timespan.
|
||||
if (intersect_begin.equals(this.end) && this.begin.lt(this.end)) {
|
||||
return(undefined)
|
||||
}
|
||||
if (intersect_begin.equals(other.end) && other.begin.lt(other.end)) {
|
||||
return(undefined)
|
||||
}
|
||||
}
|
||||
return(new TimeSpan(intersect_begin, intersect_end))
|
||||
}
|
||||
|
||||
intersection_e(other) {
|
||||
// Like 'sect', but raises an exception if the timespans don't intersect.
|
||||
result = this.intersection(other)
|
||||
if (result == None) {
|
||||
// TODO - raise exception
|
||||
// raise ValueError(f'TimeSpan {self} and TimeSpan {other} do not intersect')
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
get midpoint() {
|
||||
return(this.begin.add((this.end.sub(this.begin)).div(Fraction(2))))
|
||||
}
|
||||
|
||||
equals(other) {
|
||||
return this.begin.equals(other.begin) && this.end.equals(other.end)
|
||||
}
|
||||
}
|
||||
|
||||
class Event {
|
||||
|
||||
/*
|
||||
Event class, representing a value active during the timespan
|
||||
'part'. This might be a fragment of an event, in which case the
|
||||
timespan will be smaller than the 'whole' timespan, otherwise the
|
||||
two timespans will be the same. The 'part' must never extend outside of the
|
||||
'whole'. If the event represents a continuously changing value
|
||||
then the whole will be returned as None, in which case the given
|
||||
value will have been sampled from the point halfway between the
|
||||
start and end of the 'part' timespan.
|
||||
*/
|
||||
|
||||
constructor(whole, part, value) {
|
||||
this.whole = whole
|
||||
this.part = part
|
||||
this.value = value
|
||||
}
|
||||
|
||||
with_span(func) {
|
||||
// Returns a new event with the function f applies to the event timespan.
|
||||
var whole = this.whole ? func(self.whole) : undefined
|
||||
return new Event(whole, func(this.part), this.value)
|
||||
}
|
||||
|
||||
with_value(func) {
|
||||
// Returns a new event with the function f applies to the event value.
|
||||
return new Event(this.whole, this.part, func(this.value))
|
||||
}
|
||||
|
||||
has_onset() {
|
||||
// Test whether the event contains the onset, i.e that
|
||||
// the beginning of the part is the same as that of the whole timespan."""
|
||||
return (this.whole != undefined) && (this.whole.begin == this.part.begin)
|
||||
}
|
||||
}
|
||||
|
||||
window.bar = function() {
|
||||
console.log("aha" + typeof(Fraction(3.5)));
|
||||
}
|
||||
|
||||
//console.log((new TimeSpan(3.5,4)).midpoint);
|
||||
|
||||
var ts = new TimeSpan(0,4)
|
||||
console.log((new Event(new TimeSpan(0,2), new TimeSpan(0,2), "aha")).has_onset());
|
||||
var x = new TimeSpan(0,4)
|
||||
console.log(ts.equals(x))
|
||||
Loading…
Add table
Add a link
Reference in a new issue