Properly handle sequence.play({range}) for range[0] > 0.

Fixes #15
This commit is contained in:
Aria Minaei 2021-09-21 21:22:26 +02:00
parent e395b84cc1
commit fe4010c2c6
6 changed files with 79 additions and 35 deletions

View file

@ -0,0 +1,36 @@
import {getProject} from '@theatre/core'
import studio from '@theatre/studio'
studio.initialize()
const proj = getProject('Musical project')
const sheet = proj.sheet('Scene')
sheet.object('An object', {x: 0})
setTimeout(async () => {
// const d = defer()
// window.addEventListener('click', () => {
// d.resolve(null)
// })
// await d.promise
await sheet.sequence
.attachAudio({
source: 'http://localhost:5000/Kai%20Engel%20-%20Moonlight%20Reprise.mp3',
})
.then(() => {
console.log('ready')
})
sheet.sequence.position = 11
await sheet.sequence.play({
iterationCount: 4,
range: [10, 14],
direction: 'normal',
rate: 2,
})
// await sheet.sequence.play({
// iterationCount: 2,
// range: [20, 22],
// direction: 'normal',
// rate: 4,
// })
}, 10)

View file

@ -1 +1 @@
import './space-exploration'
import './audio'

View file

@ -167,7 +167,7 @@ export default class Sequence {
}
if (range[0] >= sequenceDuration) {
throw new InvalidArgumentError(
`Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}ms. ${JSON.stringify(
`Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}s. ${JSON.stringify(
range[0],
)} given.`,
)
@ -182,7 +182,7 @@ export default class Sequence {
if (range[1] > sequenceDuration) {
logger.warn(
`Argument conf.range[1] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}ms. ${JSON.stringify(
`Argument conf.range[1] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}s. ${JSON.stringify(
range[1],
)} given.`,
)

View file

@ -64,7 +64,7 @@ export default class AudioPlaybackController implements IPlaybackController {
this.playing = true
const ticker = this._ticker
const startPos = this.getCurrentPosition()
let startPos = this.getCurrentPosition()
const iterationLength = range[1] - range[0]
if (direction !== 'normal') {
@ -74,13 +74,6 @@ export default class AudioPlaybackController implements IPlaybackController {
)
}
if (iterationCount !== 1) {
throw new InvalidArgumentError(
`Audio-controlled sequences can only have an iterationCount of 1 ` +
`'${iterationCount}' given.`,
)
}
if (startPos < range[0] || startPos > range[1]) {
// if we're currently out of the range
this._updatePositionInState(range[0])
@ -88,6 +81,7 @@ export default class AudioPlaybackController implements IPlaybackController {
// if we're currently at the very end of the range
this._updatePositionInState(range[0])
}
startPos = this.getCurrentPosition()
const deferred = defer<boolean>()
@ -96,19 +90,25 @@ export default class AudioPlaybackController implements IPlaybackController {
currentSource.connect(this._mainGain)
currentSource.playbackRate.value = rate
const audioStartTimeInSeconds = this._audioContext.currentTime
const wait = 0
const timeToRangeEnd = range[1] - startPos
if (iterationCount > 1000) {
console.warn(
`Audio-controlled sequences cannot have an iterationCount larger than 1000. It has been clamped to 1000.`,
)
iterationCount = 1000
}
if (iterationCount > 1) {
currentSource.loop = true
currentSource.loopStart = range[0]
currentSource.loopEnd = range[1]
}
currentSource.start(
audioStartTimeInSeconds + wait,
startPos - wait,
wait + timeToRangeEnd,
)
const initialTickerTime = ticker.time
let initialElapsedPos = this.getCurrentPosition() - range[0]
let initialElapsedPos = startPos - range[0]
const totalPlaybackLength = iterationLength * iterationCount
currentSource.start(0, startPos, totalPlaybackLength - initialElapsedPos)
const tick = (currentTickerTime: number) => {
const elapsedTickerTime = Math.max(
currentTickerTime - initialTickerTime,
@ -125,7 +125,7 @@ export default class AudioPlaybackController implements IPlaybackController {
let currentIterationPos =
((elapsedPos / iterationLength) % 1) * iterationLength
this._updatePositionInState(currentIterationPos)
this._updatePositionInState(currentIterationPos + range[0])
requestNextTick()
} else {
this._updatePositionInState(range[1])

View file

@ -76,26 +76,33 @@ export default class DefaultPlaybackController implements IPlaybackController {
const startPos = this.getCurrentPosition()
if (startPos < range[0] || startPos > range[1]) {
this._updatePositionInState(range[0])
} else if (
startPos === range[1] &&
(direction === 'normal' || direction === 'alternate')
) {
this._updatePositionInState(range[0])
} else if (
startPos === range[0] &&
(direction === 'reverse' || direction === 'alternateReverse')
) {
this._updatePositionInState(range[1])
if (direction === 'normal' || direction === 'alternate') {
this._updatePositionInState(range[0])
} else if (
direction === 'reverse' ||
direction === 'alternateReverse'
) {
this._updatePositionInState(range[1])
}
} else if (direction === 'normal' || direction === 'alternate') {
if (startPos === range[1]) {
this._updatePositionInState(range[0])
}
} else {
if (startPos === range[0]) {
this._updatePositionInState(range[1])
}
}
}
const deferred = defer<boolean>()
const initialTickerTime = ticker.time
const totalPlaybackLength = iterationLength * iterationCount
let initialElapsedPos = this.getCurrentPosition() - range[0]
if (direction === 'reverse' || direction === 'alternateReverse') {
initialElapsedPos = range[1] - initialElapsedPos
initialElapsedPos = range[1] - this.getCurrentPosition()
}
const tick = (currentTickerTime: number) => {
@ -112,6 +119,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
if (elapsedPos !== totalPlaybackLength) {
const iterationNumber = Math.floor(elapsedPos / iterationLength)
let currentIterationPos =
((elapsedPos / iterationLength) % 1) * iterationLength
@ -132,7 +140,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
}
}
this._updatePositionInState(currentIterationPos)
this._updatePositionInState(currentIterationPos + range[0])
requestNextTick()
} else {
if (direction === 'normal') {

View file

@ -39,7 +39,7 @@ export default function useKeyboardShortcuts() {
if (seq.playing) {
seq.pause()
} else {
seq.play({iterationCount: Infinity})
seq.play({iterationCount: 1000})
}
} else {
return