Compare commits

...

3 Commits

Author SHA1 Message Date
Felix Roos bb8cfa56ea snapshot 2023-03-02 22:47:23 +01:00
Felix Roos e4aa926ad5 remove double tag 2023-03-02 22:43:18 +01:00
Felix Roos 77eefc20f7 add loopBegin and loopEnd 2023-03-02 22:41:04 +01:00
3 changed files with 51 additions and 20 deletions
+23 -6
View File
@@ -193,16 +193,33 @@ const generic_params = [
*/
['end'],
/**
* Loops the sample (from `begin` to `end`) the specified number of times.
* Note that the tempo of the loop is not synced with the cycle tempo.
* Loops the sample from `loopBegin` to `loopEnd`. If one or both of those are set,
* the sample is looped to fill the event duration, instead of playing the whole sample.
* If only `loopBegin` is set, `loopEnd` defaults to 1.
* If only `loopEnd` is set, `loopBegin` defaults to 0.
*
* @name loop
* @param {number | Pattern} times How often the sample is looped
* @name loopBegin
* @param {number | Pattern} position position from 0 - 1 where the loop starts
* @example
* s("bd").loop("<1 2 3 4>").osc()
* note("<c a f e>").s("piano")
* .loopBegin("<0 .24 .32>").loopEnd(.5)
*
*/
['loop'],
['loopBegin'],
/**
* Loops the sample from `loopBegin` to `loopEnd`. If one or both of those are set,
* the sample is looped to fill the event duration, instead of playing the whole sample.
* If only `loopBegin` is set, `loopEnd` defaults to 1.
* If only `loopEnd` is set, `loopBegin` defaults to 0.
*
* @name loopEnd
* @param {number | Pattern} position position from 0 - 1 where the loop ends
* @example
* note("<c a f e>").s("piano")
* .loopBegin(.2).loopEnd("<.3 .4 .5 .6>")
*
*/
['loopEnd'],
// TODO: currently duplicated with "native" legato
// TODO: superdirt legato will do more: https://youtu.be/dQPmE1WaD1k?t=419
/**
+10 -5
View File
@@ -231,7 +231,8 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => {
unit,
nudge = 0, // TODO: is this in seconds?
cut,
loop,
loopBegin,
loopEnd,
orbit = 1,
room,
size = 2,
@@ -307,17 +308,21 @@ export const webaudioOutput = async (hap, deadline, hapDuration, cps) => {
// are there other units?
bufferSource.playbackRate.value = bufferSource.playbackRate.value * bufferSource.buffer.duration * cps;
}
let duration = soundfont || clip ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value;
const loop = loopBegin !== undefined || loopEnd !== undefined;
let duration =
soundfont || clip || loop ? hapDuration : bufferSource.buffer.duration / bufferSource.playbackRate.value;
// "The computation of the offset into the sound is performed using the sound buffer's natural sample rate,
// rather than the current playback rate, so even if the sound is playing at twice its normal speed,
// the midway point through a 10-second audio buffer is still 5."
const offset = begin * duration * bufferSource.playbackRate.value;
duration = (end - begin) * duration;
if (loop) {
loopBegin = loopBegin ?? 0;
loopEnd = loopEnd ?? 1;
bufferSource.loop = true;
bufferSource.loopStart = offset;
bufferSource.loopEnd = offset + duration;
duration = loop * duration;
bufferSource.loopStart = offset + loopBegin * duration;
bufferSource.loopEnd = offset + duration - (1 - loopEnd) * duration;
duration = hapDuration;
}
t += nudge;
+18 -9
View File
@@ -2354,15 +2354,6 @@ exports[`runs examples > example "linger" example index 0 1`] = `
]
`;
exports[`runs examples > example "loop" example index 0 1`] = `
[
"[ 0/1 → 1/1 | s:bd loop:1 ]",
"[ 1/1 → 2/1 | s:bd loop:2 ]",
"[ 2/1 → 3/1 | s:bd loop:3 ]",
"[ 3/1 → 4/1 | s:bd loop:4 ]",
]
`;
exports[`runs examples > example "loopAt" example index 0 1`] = `
[
"[ (0/1 → 1/1) ⇝ 4/1 | s:rhodes speed:0.25 unit:c ]",
@@ -2381,6 +2372,24 @@ exports[`runs examples > example "loopAtCps" example index 0 1`] = `
]
`;
exports[`runs examples > example "loopBegin" example index 0 1`] = `
[
"[ 0/1 → 1/1 | note:c s:piano loopBegin:0 loopEnd:0.5 ]",
"[ 1/1 → 2/1 | note:a s:piano loopBegin:0.24 loopEnd:0.5 ]",
"[ 2/1 → 3/1 | note:f s:piano loopBegin:0.32 loopEnd:0.5 ]",
"[ 3/1 → 4/1 | note:e s:piano loopBegin:0 loopEnd:0.5 ]",
]
`;
exports[`runs examples > example "loopEnd" example index 0 1`] = `
[
"[ 0/1 → 1/1 | note:c s:piano loopBegin:0.2 loopEnd:0.3 ]",
"[ 1/1 → 2/1 | note:a s:piano loopBegin:0.2 loopEnd:0.4 ]",
"[ 2/1 → 3/1 | note:f s:piano loopBegin:0.2 loopEnd:0.5 ]",
"[ 3/1 → 4/1 | note:e s:piano loopBegin:0.2 loopEnd:0.6 ]",
]
`;
exports[`runs examples > example "lpf" example index 0 1`] = `
[
"[ 0/1 → 1/2 | s:bd cutoff:4000 ]",