Skip to content

Commit fe4010c

Browse files
committed
Properly handle sequence.play({range}) for range[0] > 0.
Fixes #15
1 parent e395b84 commit fe4010c

File tree

6 files changed

+79
-35
lines changed

6 files changed

+79
-35
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {getProject} from '@theatre/core'
2+
import studio from '@theatre/studio'
3+
4+
studio.initialize()
5+
6+
const proj = getProject('Musical project')
7+
const sheet = proj.sheet('Scene')
8+
sheet.object('An object', {x: 0})
9+
10+
setTimeout(async () => {
11+
// const d = defer()
12+
// window.addEventListener('click', () => {
13+
// d.resolve(null)
14+
// })
15+
// await d.promise
16+
await sheet.sequence
17+
.attachAudio({
18+
source: 'http://localhost:5000/Kai%20Engel%20-%20Moonlight%20Reprise.mp3',
19+
})
20+
.then(() => {
21+
console.log('ready')
22+
})
23+
sheet.sequence.position = 11
24+
await sheet.sequence.play({
25+
iterationCount: 4,
26+
range: [10, 14],
27+
direction: 'normal',
28+
rate: 2,
29+
})
30+
// await sheet.sequence.play({
31+
// iterationCount: 2,
32+
// range: [20, 22],
33+
// direction: 'normal',
34+
// rate: 4,
35+
// })
36+
}, 10)

packages/playground/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import './space-exploration'
1+
import './audio'

theatre/core/src/sequences/Sequence.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ export default class Sequence {
167167
}
168168
if (range[0] >= sequenceDuration) {
169169
throw new InvalidArgumentError(
170-
`Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}ms. ${JSON.stringify(
170+
`Argument conf.range[0] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}s. ${JSON.stringify(
171171
range[0],
172172
)} given.`,
173173
)
@@ -182,7 +182,7 @@ export default class Sequence {
182182

183183
if (range[1] > sequenceDuration) {
184184
logger.warn(
185-
`Argument conf.range[1] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}ms. ${JSON.stringify(
185+
`Argument conf.range[1] in sequence.play(conf) cannot be longer than the duration of the sequence, which is ${sequenceDuration}s. ${JSON.stringify(
186186
range[1],
187187
)} given.`,
188188
)

theatre/core/src/sequences/playbackControllers/AudioPlaybackController.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default class AudioPlaybackController implements IPlaybackController {
6464
this.playing = true
6565

6666
const ticker = this._ticker
67-
const startPos = this.getCurrentPosition()
67+
let startPos = this.getCurrentPosition()
6868
const iterationLength = range[1] - range[0]
6969

7070
if (direction !== 'normal') {
@@ -74,20 +74,14 @@ export default class AudioPlaybackController implements IPlaybackController {
7474
)
7575
}
7676

77-
if (iterationCount !== 1) {
78-
throw new InvalidArgumentError(
79-
`Audio-controlled sequences can only have an iterationCount of 1 ` +
80-
`'${iterationCount}' given.`,
81-
)
82-
}
83-
8477
if (startPos < range[0] || startPos > range[1]) {
8578
// if we're currently out of the range
8679
this._updatePositionInState(range[0])
8780
} else if (startPos === range[1]) {
8881
// if we're currently at the very end of the range
8982
this._updatePositionInState(range[0])
9083
}
84+
startPos = this.getCurrentPosition()
9185

9286
const deferred = defer<boolean>()
9387

@@ -96,19 +90,25 @@ export default class AudioPlaybackController implements IPlaybackController {
9690
currentSource.connect(this._mainGain)
9791
currentSource.playbackRate.value = rate
9892

99-
const audioStartTimeInSeconds = this._audioContext.currentTime
100-
const wait = 0
101-
const timeToRangeEnd = range[1] - startPos
93+
if (iterationCount > 1000) {
94+
console.warn(
95+
`Audio-controlled sequences cannot have an iterationCount larger than 1000. It has been clamped to 1000.`,
96+
)
97+
iterationCount = 1000
98+
}
99+
100+
if (iterationCount > 1) {
101+
currentSource.loop = true
102+
currentSource.loopStart = range[0]
103+
currentSource.loopEnd = range[1]
104+
}
102105

103-
currentSource.start(
104-
audioStartTimeInSeconds + wait,
105-
startPos - wait,
106-
wait + timeToRangeEnd,
107-
)
108106
const initialTickerTime = ticker.time
109-
let initialElapsedPos = this.getCurrentPosition() - range[0]
107+
let initialElapsedPos = startPos - range[0]
110108
const totalPlaybackLength = iterationLength * iterationCount
111109

110+
currentSource.start(0, startPos, totalPlaybackLength - initialElapsedPos)
111+
112112
const tick = (currentTickerTime: number) => {
113113
const elapsedTickerTime = Math.max(
114114
currentTickerTime - initialTickerTime,
@@ -125,7 +125,7 @@ export default class AudioPlaybackController implements IPlaybackController {
125125
let currentIterationPos =
126126
((elapsedPos / iterationLength) % 1) * iterationLength
127127

128-
this._updatePositionInState(currentIterationPos)
128+
this._updatePositionInState(currentIterationPos + range[0])
129129
requestNextTick()
130130
} else {
131131
this._updatePositionInState(range[1])

theatre/core/src/sequences/playbackControllers/DefaultPlaybackController.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,33 @@ export default class DefaultPlaybackController implements IPlaybackController {
7676
const startPos = this.getCurrentPosition()
7777

7878
if (startPos < range[0] || startPos > range[1]) {
79-
this._updatePositionInState(range[0])
80-
} else if (
81-
startPos === range[1] &&
82-
(direction === 'normal' || direction === 'alternate')
83-
) {
84-
this._updatePositionInState(range[0])
85-
} else if (
86-
startPos === range[0] &&
87-
(direction === 'reverse' || direction === 'alternateReverse')
88-
) {
89-
this._updatePositionInState(range[1])
79+
if (direction === 'normal' || direction === 'alternate') {
80+
this._updatePositionInState(range[0])
81+
} else if (
82+
direction === 'reverse' ||
83+
direction === 'alternateReverse'
84+
) {
85+
this._updatePositionInState(range[1])
86+
}
87+
} else if (direction === 'normal' || direction === 'alternate') {
88+
if (startPos === range[1]) {
89+
this._updatePositionInState(range[0])
90+
}
91+
} else {
92+
if (startPos === range[0]) {
93+
this._updatePositionInState(range[1])
94+
}
9095
}
9196
}
9297

9398
const deferred = defer<boolean>()
9499
const initialTickerTime = ticker.time
95100
const totalPlaybackLength = iterationLength * iterationCount
101+
96102
let initialElapsedPos = this.getCurrentPosition() - range[0]
103+
97104
if (direction === 'reverse' || direction === 'alternateReverse') {
98-
initialElapsedPos = range[1] - initialElapsedPos
105+
initialElapsedPos = range[1] - this.getCurrentPosition()
99106
}
100107

101108
const tick = (currentTickerTime: number) => {
@@ -112,6 +119,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
112119

113120
if (elapsedPos !== totalPlaybackLength) {
114121
const iterationNumber = Math.floor(elapsedPos / iterationLength)
122+
115123
let currentIterationPos =
116124
((elapsedPos / iterationLength) % 1) * iterationLength
117125

@@ -132,7 +140,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
132140
}
133141
}
134142

135-
this._updatePositionInState(currentIterationPos)
143+
this._updatePositionInState(currentIterationPos + range[0])
136144
requestNextTick()
137145
} else {
138146
if (direction === 'normal') {

theatre/studio/src/UIRoot/useKeyboardShortcuts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default function useKeyboardShortcuts() {
3939
if (seq.playing) {
4040
seq.pause()
4141
} else {
42-
seq.play({iterationCount: Infinity})
42+
seq.play({iterationCount: 1000})
4343
}
4444
} else {
4545
return

0 commit comments

Comments
 (0)