parent
e395b84cc1
commit
fe4010c2c6
6 changed files with 79 additions and 35 deletions
36
packages/playground/src/audio/index.ts
Normal file
36
packages/playground/src/audio/index.ts
Normal 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)
|
|
@ -1 +1 @@
|
||||||
import './space-exploration'
|
import './audio'
|
||||||
|
|
|
@ -167,7 +167,7 @@ export default class Sequence {
|
||||||
}
|
}
|
||||||
if (range[0] >= sequenceDuration) {
|
if (range[0] >= sequenceDuration) {
|
||||||
throw new InvalidArgumentError(
|
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],
|
range[0],
|
||||||
)} given.`,
|
)} given.`,
|
||||||
)
|
)
|
||||||
|
@ -182,7 +182,7 @@ export default class Sequence {
|
||||||
|
|
||||||
if (range[1] > sequenceDuration) {
|
if (range[1] > sequenceDuration) {
|
||||||
logger.warn(
|
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],
|
range[1],
|
||||||
)} given.`,
|
)} given.`,
|
||||||
)
|
)
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default class AudioPlaybackController implements IPlaybackController {
|
||||||
this.playing = true
|
this.playing = true
|
||||||
|
|
||||||
const ticker = this._ticker
|
const ticker = this._ticker
|
||||||
const startPos = this.getCurrentPosition()
|
let startPos = this.getCurrentPosition()
|
||||||
const iterationLength = range[1] - range[0]
|
const iterationLength = range[1] - range[0]
|
||||||
|
|
||||||
if (direction !== 'normal') {
|
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 (startPos < range[0] || startPos > range[1]) {
|
||||||
// if we're currently out of the range
|
// if we're currently out of the range
|
||||||
this._updatePositionInState(range[0])
|
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
|
// if we're currently at the very end of the range
|
||||||
this._updatePositionInState(range[0])
|
this._updatePositionInState(range[0])
|
||||||
}
|
}
|
||||||
|
startPos = this.getCurrentPosition()
|
||||||
|
|
||||||
const deferred = defer<boolean>()
|
const deferred = defer<boolean>()
|
||||||
|
|
||||||
|
@ -96,19 +90,25 @@ export default class AudioPlaybackController implements IPlaybackController {
|
||||||
currentSource.connect(this._mainGain)
|
currentSource.connect(this._mainGain)
|
||||||
currentSource.playbackRate.value = rate
|
currentSource.playbackRate.value = rate
|
||||||
|
|
||||||
const audioStartTimeInSeconds = this._audioContext.currentTime
|
if (iterationCount > 1000) {
|
||||||
const wait = 0
|
console.warn(
|
||||||
const timeToRangeEnd = range[1] - startPos
|
`Audio-controlled sequences cannot have an iterationCount larger than 1000. It has been clamped to 1000.`,
|
||||||
|
|
||||||
currentSource.start(
|
|
||||||
audioStartTimeInSeconds + wait,
|
|
||||||
startPos - wait,
|
|
||||||
wait + timeToRangeEnd,
|
|
||||||
)
|
)
|
||||||
|
iterationCount = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterationCount > 1) {
|
||||||
|
currentSource.loop = true
|
||||||
|
currentSource.loopStart = range[0]
|
||||||
|
currentSource.loopEnd = range[1]
|
||||||
|
}
|
||||||
|
|
||||||
const initialTickerTime = ticker.time
|
const initialTickerTime = ticker.time
|
||||||
let initialElapsedPos = this.getCurrentPosition() - range[0]
|
let initialElapsedPos = startPos - range[0]
|
||||||
const totalPlaybackLength = iterationLength * iterationCount
|
const totalPlaybackLength = iterationLength * iterationCount
|
||||||
|
|
||||||
|
currentSource.start(0, startPos, totalPlaybackLength - initialElapsedPos)
|
||||||
|
|
||||||
const tick = (currentTickerTime: number) => {
|
const tick = (currentTickerTime: number) => {
|
||||||
const elapsedTickerTime = Math.max(
|
const elapsedTickerTime = Math.max(
|
||||||
currentTickerTime - initialTickerTime,
|
currentTickerTime - initialTickerTime,
|
||||||
|
@ -125,7 +125,7 @@ export default class AudioPlaybackController implements IPlaybackController {
|
||||||
let currentIterationPos =
|
let currentIterationPos =
|
||||||
((elapsedPos / iterationLength) % 1) * iterationLength
|
((elapsedPos / iterationLength) % 1) * iterationLength
|
||||||
|
|
||||||
this._updatePositionInState(currentIterationPos)
|
this._updatePositionInState(currentIterationPos + range[0])
|
||||||
requestNextTick()
|
requestNextTick()
|
||||||
} else {
|
} else {
|
||||||
this._updatePositionInState(range[1])
|
this._updatePositionInState(range[1])
|
||||||
|
|
|
@ -76,26 +76,33 @@ export default class DefaultPlaybackController implements IPlaybackController {
|
||||||
const startPos = this.getCurrentPosition()
|
const startPos = this.getCurrentPosition()
|
||||||
|
|
||||||
if (startPos < range[0] || startPos > range[1]) {
|
if (startPos < range[0] || startPos > range[1]) {
|
||||||
|
if (direction === 'normal' || direction === 'alternate') {
|
||||||
this._updatePositionInState(range[0])
|
this._updatePositionInState(range[0])
|
||||||
} else if (
|
} else if (
|
||||||
startPos === range[1] &&
|
direction === 'reverse' ||
|
||||||
(direction === 'normal' || direction === 'alternate')
|
direction === 'alternateReverse'
|
||||||
) {
|
|
||||||
this._updatePositionInState(range[0])
|
|
||||||
} else if (
|
|
||||||
startPos === range[0] &&
|
|
||||||
(direction === 'reverse' || direction === 'alternateReverse')
|
|
||||||
) {
|
) {
|
||||||
this._updatePositionInState(range[1])
|
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 deferred = defer<boolean>()
|
||||||
const initialTickerTime = ticker.time
|
const initialTickerTime = ticker.time
|
||||||
const totalPlaybackLength = iterationLength * iterationCount
|
const totalPlaybackLength = iterationLength * iterationCount
|
||||||
|
|
||||||
let initialElapsedPos = this.getCurrentPosition() - range[0]
|
let initialElapsedPos = this.getCurrentPosition() - range[0]
|
||||||
|
|
||||||
if (direction === 'reverse' || direction === 'alternateReverse') {
|
if (direction === 'reverse' || direction === 'alternateReverse') {
|
||||||
initialElapsedPos = range[1] - initialElapsedPos
|
initialElapsedPos = range[1] - this.getCurrentPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
const tick = (currentTickerTime: number) => {
|
const tick = (currentTickerTime: number) => {
|
||||||
|
@ -112,6 +119,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
|
||||||
|
|
||||||
if (elapsedPos !== totalPlaybackLength) {
|
if (elapsedPos !== totalPlaybackLength) {
|
||||||
const iterationNumber = Math.floor(elapsedPos / iterationLength)
|
const iterationNumber = Math.floor(elapsedPos / iterationLength)
|
||||||
|
|
||||||
let currentIterationPos =
|
let currentIterationPos =
|
||||||
((elapsedPos / iterationLength) % 1) * iterationLength
|
((elapsedPos / iterationLength) % 1) * iterationLength
|
||||||
|
|
||||||
|
@ -132,7 +140,7 @@ export default class DefaultPlaybackController implements IPlaybackController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updatePositionInState(currentIterationPos)
|
this._updatePositionInState(currentIterationPos + range[0])
|
||||||
requestNextTick()
|
requestNextTick()
|
||||||
} else {
|
} else {
|
||||||
if (direction === 'normal') {
|
if (direction === 'normal') {
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default function useKeyboardShortcuts() {
|
||||||
if (seq.playing) {
|
if (seq.playing) {
|
||||||
seq.pause()
|
seq.pause()
|
||||||
} else {
|
} else {
|
||||||
seq.play({iterationCount: Infinity})
|
seq.play({iterationCount: 1000})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue