mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 05:38:34 +00:00
first
This commit is contained in:
parent
fb72bb2290
commit
40f2355fbf
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Bingo</title>
|
||||
</head>
|
||||
<body>
|
||||
<button onclick="foo()">hello</button>
|
||||
<button onclick="bar()">hello</button>
|
||||
|
||||
<script type="module" src="./js/strudel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
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))
|
||||
53
package-lock.json
generated
Normal file
53
package-lock.json
generated
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "strudel",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "strudel",
|
||||
"version": "1.0.0",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"fraction": "^0.2.0",
|
||||
"fraction.js": "^4.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/fraction": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fraction/-/fraction-0.2.0.tgz",
|
||||
"integrity": "sha1-ZassG7bt+JmJ2B1Q8FJeX6J7Hkw=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fraction.js": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
|
||||
"integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/infusion"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"fraction": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fraction/-/fraction-0.2.0.tgz",
|
||||
"integrity": "sha1-ZassG7bt+JmJ2B1Q8FJeX6J7Hkw=",
|
||||
"dev": true
|
||||
},
|
||||
"fraction.js": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
|
||||
"integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
29
package.json
Normal file
29
package.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "strudel",
|
||||
"version": "1.0.0",
|
||||
"description": "Experimental port of tidalcycles to javascript",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/yaxu/strudel.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tidalcycles",
|
||||
"strudel",
|
||||
"pattern",
|
||||
"livecoding",
|
||||
"algorave"
|
||||
],
|
||||
"author": "Alex McLean",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/yaxu/strudel/issues"
|
||||
},
|
||||
"homepage": "https://github.com/yaxu/strudel#readme",
|
||||
"devDependencies": {
|
||||
"fraction.js": "^4.1.2"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user