mindboost-rnbo-test-project/pages/experiments/Player/newRNBOPlayer.vue

169 lines
5.7 KiB
Vue

<template>
<div>
<h1>Test Fall 4</h1>
<h3>Howler als Stream mit der HowlWebAudioBridge (createMediaElementSource)</h3>
<KeyboardPlayHandler />
<button @click="play">Play</button>
<div v-if="false" id="statistics">
{{ Object.keys(gains).length }}
{{ Object.keys(nodes).length }}
</div>
<HowlWebAudioBridge
:src="source[0]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 63)"
/>
<HowlWebAudioBridge
:src="source[1]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 125)"
/>
<HowlWebAudioBridge
:src="source[2]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 250)"
/>
<HowlWebAudioBridge
:src="source[3]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 500)"
/>
<HowlWebAudioBridge
:src="source[4]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 1000)"
/>
<HowlWebAudioBridge
:src="source[5]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 2000)"
/>
<HowlWebAudioBridge
:src="source[6]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 4000)"
/>
<HowlWebAudioBridge
:src="source[7]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 8000)"
/>
<HowlWebAudioBridge
:src="source[8]"
:audio-context="audioContext"
:on-ready="(node, howl) => registerAudioNode(node, howl, 16000)"
/>
</div>
</template>
<script setup lang="ts">
import type { Logger } from 'pino'
import { useAudioStore } from '~/stores/audio'
import tracksConfig from '~/tracks.config'
import HowlWebAudioBridge from '~/components/Player/HowlWebAudioBridge.vue'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'
const source = ref([tracksConfig['63_src'], tracksConfig['125_src'], tracksConfig['250_src'], tracksConfig['500_src'], tracksConfig['1000_src'], tracksConfig['2000_src'], tracksConfig['4000_src'], tracksConfig['8000_src'], tracksConfig['16000_src']])
const audioContext = ref(useAudioStore().getContext()as AudioContext)
const nodes = ref([] as Record<number, AudioNode>)
const gains = ref([] as Record<number, GainNode>)
const howls = ref([] as Array<Howl>)
const masterGain = ref(null as (GainNode | null))
const lastAction = audioContext.value.currentTime
const logger = useNuxtApp().$logger as Logger
const registerAudioNode = (node:AudioNode | null, howl: Howl| null, freq: number) => {
if (howl) {
logger.info('register new Node push it', howl.state)
howls.value.push(howl)
const mediaElement = (howl as any)._sounds[0]._node as HTMLAudioElement
mediaElement.muted = false
logger.info('mediaElement muted')
}
if (node) {
const gainNode = node.context.createGain()
const pannerNode = audioContext.value.createStereoPanner()
pannerNode.pan.value = 1
gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
gainNode.gain.linearRampToValueAtTime(0.5, audioContext.value.currentTime + 2)
const master = masterGain.value || useAudioStore().getMasterGainNoise()
nodes.value[freq] = node
gains.value[freq] = gainNode
node.connect(gainNode)
gainNode.connect(master)
pannerNode.connect(master)
logger.info('mediaElement nicht mehr gemutet')
logger.info('AudioNode ready, but not connected to destination', { node })
logger.info('Number of GainNodes', Object.keys(gains.value).length)
logger.info('Number of AudioNodes', Object.keys(nodes.value).length)
}
}
watch(() => useAudioStore().playing, // Überwache explizit den state
(newState) => {
if (newState) {
play()
} else {
pause()
}
}
)
watch(() => lastAction, // Überwache explizit den state
(lastTimestamp) => {
if (lastTimestamp > 50) {
play() // Overlay anzeigen
} else {
pause()
}
}
)
const pause = () => {
logger.info('pause')
const master = masterGain.value
const currentTime = audioContext.value.currentTime
// master?.gain.cancelScheduledValues(currentTime)
master?.gain.linearRampToValueAtTime(0, currentTime + 5)
const lastAction = currentTime
howls.value.forEach((howl) => {
howl.pause()
}
)
master?.disconnect()
// if (gainNode) {
// gainNode.connect(audioContext.value.destination)
// gainNode.gain.cancelScheduledValues(audioContext.value.currentTime)
// gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
// gainNode.gain.linearRampToValueAtTime(2, audioContext.value.currentTime + 4)
// } else {
// logger.info('GAINNODE NOT CREATED WE WILL NOT START')
// }
}
const play = () => {
const newHowls = howls.value
const master = masterGain.value || useAudioStore().getMasterGainNoise()
logger.info('Start this', { newHowls })
howls.value.forEach(async (howl) => {
howl.play()
logger.info('Start this', { newHowls })
masterGain?.value?.gain.linearRampToValueAtTime(1, audioContext.value.currentTime + 3)
const mediaElement = await (howl as any)._sounds[0]._node as HTMLAudioElement
mediaElement.muted = false
}
)
master.connect(audioContext.value.destination)
// if (gainNode) {
// gainNode.connect(audioContext.value.destination)
// gainNode.gain.cancelScheduledValues(audioContext.value.currentTime)
// gainNode.gain.setValueAtTime(0, audioContext.value.currentTime)
// gainNode.gain.linearRampToValueAtTime(2, audioContext.value.currentTime + 4)
// } else {
// logger.info('GAINNODE NOT CREATED WE WILL NOT START')
// }
}
</script>