Initial commit

This commit is contained in:
Mindboost
2025-07-01 10:53:26 +00:00
commit 38050e5c69
416 changed files with 48708 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
<!-- eslint-disable vue/no-multiple-template-root -->
<template>
<h4> Die Audio HowlWebAudioBridge sorgt zwar für ein sauberes Streaming, aber lässt sich dann nicht über WebAudio regeln</h4>
<div>
<HowlWebAudioBridge
:src="source"
:audio-context="audioContext"
:on-ready="handleAudioNode"
/>
<button @click="testAudio">Test Audio</button>
</div>
</template>
<script setup lang="ts">
import HowlWebAudioBridge from '~/components/Player/HowlWebAudioBridge.vue'
import tracksConfig from '~/tracks.config'
import { useAudioStore, ensureAudio } from '~/stores/audio'
const audioContext = useAudioStore().getContext()
const source = tracksConfig.debug_src
const audioNode = ref({} as AudioBufferSourceNode | MediaElementAudioSourceNode | MediaStreamAudioSourceNode)
const gainNode = ref({} as GainNode)
const audioReady = ref(false as boolean)
const howlElement = ref({} as Howl)
async function testAudio () {
await ensureAudio()
if (audioReady && gainNode && howlElement) {
howlElement.value.play()
const audioDestination = audioContext.destination
const gain = gainNode.value as GainNode
if (audioNode instanceof AudioBufferSourceNode) {
audioNode.loop = true
audioNode.playbackRate.value = 1
audioNode.connect(gain).connect(audioDestination)
}
if (audioNode instanceof MediaElementAudioSourceNode) {
audioNode.connect(gain).connect(audioDestination)
}
if (audioNode instanceof MediaStreamAudioSourceNode) {
audioNode.connect(gain).connect(audioDestination)
}
gain.gain.cancelScheduledValues(audioContext.currentTime)
gain.gain.linearRampToValueAtTime(1, audioContext.currentTime + 2)
useNuxtApp().$logger.log('Gain connected to destination')
} else {
useNuxtApp().$logger.warn('Audio is not yet ready to test it')
}
}
function handleAudioNode (node: MediaElementAudioSourceNode | AudioBufferSourceNode | MediaStreamAudioSourceNode, howl: Howl | null) {
useNuxtApp().$logger.log('AUDIONODE IST ANGEKOMMEN ')
useNuxtApp().$logger.log({ node })
useNuxtApp().$logger.log({ howl })
audioNode.value = node
if (howl) { howlElement.value = howl }
gainNode.value = audioContext.createGain() as GainNode
gainNode.value.gain.setValueAtTime(0, audioContext.currentTime)
// Not connected to any destination, gain currently muted
if (node instanceof AudioBufferSourceNode) {
node.loop = true
node.playbackRate.value = 1
node.connect(gainNode.value)
}
if (node instanceof MediaElementAudioSourceNode) {
node.connect(gainNode.value)
}
if (node instanceof MediaStreamAudioSourceNode) {
node.connect(gainNode.value)
}
audioReady.value = true
}
</script>

View File

@@ -0,0 +1,12 @@
<template>
<div>
<RNBODevice />
<GainController />
</div>
</template>
<script setup>
import GainController from '~/components/experiments/GainController.vue'
import RNBODevice from '~/components/experiments/homepages/RNBODevice.vue'
import NavigationBar from '~/components/NavigationBar.vue'
</script>

View File

@@ -0,0 +1,49 @@
<template>
<div class="p-4">
<h1 class="text-xl font-bold mb-4">Audio Fade-In Beispiel</h1>
<audio
ref="audioEl"
:src="source"
crossorigin="anonymous"
/>
<button
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition"
@click="playWithFadeIn"
>
Abspielen mit Fade-In
</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import tracksConfig from '~/tracks.config'
const audioEl = ref(null)
const source = ref(tracksConfig.lagoon_48_mp3_src)
const playWithFadeIn = async () => {
const audio = audioEl.value
const sink = useUserStore().audioOutputDevice
audio.value?.setSinkId(sink.deviceId)
if (!audio) { return }
const audioContext = new (window.AudioContext || window.webkitAudioContext)()
const sourceNode = audioContext.createMediaElementSource(audio)
const gainNode = audioContext.createGain()
// Anfangslautstärke auf 0 setzen
gainNode.gain.setValueAtTime(0, audioContext.currentTime)
// Ziel-Lautstärke in 3 Sekunden erreichen
gainNode.gain.linearRampToValueAtTime(1.0, audioContext.currentTime + 3)
// Verkabeln
sourceNode.connect(gainNode)
gainNode.connect(audioContext.destination)
// Abspielen
await audio.play()
}
</script>

View File

@@ -0,0 +1,68 @@
<template>
<div class="p-4">
<h1 class="text-xl font-bold mb-4">Howler MediaStream + volume Fade-In</h1>
<h3>Startet, Kontrolle der Lautstärke über volume-API, aber erst kommt 100% Lautstärke Audio, bevor es verstummt und dann einfaded</h3>
<button
class="px-4 py-2 bg-indigo-600 text-white rounded hover:bg-indigo-700 transition"
@click="startCaptureWithVolumeRamp"
>
Starten & Lautstärke einblenden
</button>
<div v-if="mediaStream" class="mt-4 text-green-700 font-mono">
MediaStream erzeugt!
</div>
<p v-if="error" class="text-red-600 mt-2">{{ error }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Howl } from 'howler'
import tracksConfig from '~/tracks.config'
const mediaStream = ref(null)
const error = ref(null)
const startCaptureWithVolumeRamp = async () => {
try {
const sound = new Howl({
src: [tracksConfig.lagoon_48_mp3_src],
html5: true,
preload: true,
muted: true
})
await new Promise(resolve => sound.once('load', resolve))
const audioElement = sound._sounds[0]._node
// Volume auf 0 (mute) setzen
audioElement.volume = 0
// captureStream vor play aufrufen
const stream = audioElement.captureStream()
// Starte Audio
sound.play()
// Starte Volume-Ramp (linear über ~3 Sekunden)
let volume = 0
const step = 0.05 // Schrittgröße
const interval = 150 // ms zwischen Schritten
const ramp = setInterval(() => {
volume += step
audioElement.volume = Math.min(1, volume)
if (volume >= 1) {
clearInterval(ramp)
}
}, interval)
mediaStream.value = stream
} catch (err) {
useNuxtApp().$logger.error(err)
error.value = 'Fehler beim Start: ' + err.message
}
}
</script>

View File

@@ -0,0 +1,9 @@
<template>
<div>
<Player />
</div>
</template>
<script setup>
import Player from '~/components/experiments/tests/showcases/PlayerComponent.vue'
</script>

View File

@@ -0,0 +1,168 @@
<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>

View File

@@ -0,0 +1,105 @@
<!--
/**
* @component ControlValueBasedPlayer
* @description A component that renders multiple NoiseControlledBand components,
* each centered around a specific frequency. This can be used for
* audio spectrum visualization or control. Now includes a loading spinner
* that disappears when all NoiseControlledBand components are ready.
*
* @uses NoiseControlledBand
*
* @example
* <ControlValueBasedPlayer />
*
* @remarks
* - Utilizes Vue 3 Composition API
* - Renders NoiseControlledBand components for standard audio frequency bands
* - Frequencies: 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000 Hz
* - Includes a loading spinner that disappears when all components are ready
*/
-->
<template>
<div>
<h1> Test Fall 1 mit Control Value Patch</h1>
<h3> Ein AudioTag, dass über die Volume-APi gesteuert wird</h3>
<div v-if="isExperimentsRoute">
<KeyboardPlayHandler />
<PlayButton />
</div>
<div v-if="loading" class="spinner-border spinner-border-sm" role="status">
<span class="sr-only">{{ t("Loading...") }}</span>
</div>
Loaded Bands: {{ loadedBands }}
<div>
<label>Attack: {{ (masterAttack / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterAttack"
type="range"
:min="4800"
:max="1920000"
>
<label>Release: {{ (masterRelease / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterRelease"
type="range"
:min="4800"
:max="1920000"
>
</div>
<NoiseControlledBand
v-for="frequency in frequencies"
:key="frequency"
:master-attack="masterAttack"
:master-release="masterRelease"
:center-frequency="frequency"
@ready="onBandReady"
/>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'
import PlayButton from '~/components/experiments/statemanagement/PlayButton.vue'
import NoiseControlledBand from '~/components/experiments/tests/ControlValues/NoiseControlledBand.vue'
export default defineComponent({
components: {
NoiseControlledBand,
KeyboardPlayHandler,
PlayButton
},
setup () {
const { t } = useI18n()
const frequencies = ref([63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000])
const loadedBands = ref(0)
const route = useRoute()
const isExperimentsRoute = computed(() => route.path.match(/\/[a-z]{2}\/experiments/))
const masterAttack = ref(120000) // Beispielwert in Samples
const masterRelease = ref(144000)
const loading = computed(() => loadedBands.value < frequencies.value.length)
const onBandReady = () => {
loadedBands.value++
}
return {
frequencies,
loading,
onBandReady,
t,
loadedBands,
masterAttack,
masterRelease,
isExperimentsRoute
}
}
})
</script>

View File

@@ -0,0 +1,74 @@
<template>
<div>
<KeyboardPlayHandler />
<h1> Test Fall 2 mit Control Value Patch</h1>
<h2>Use AudioBufferSourceNode over controlled NoiseControlledWebAudioBand</h2>
<h3> press space to start</h3>
<div>
Masking Gain : <input
id="gain-control"
:onchange="updateMasterGain"
type="range"
min="0"
max="1"
step="0.01"
>
</div>
<div v-if="loading" class="spinner-border spinner-border-sm" role="status">
<span class="sr-only">{{ t("Loading...") }}</span>
</div>
Loaded Bands: {{ loadedBands }}
<NoiseControlledWebAudioBand
v-for="frequency in frequencies"
v-show="false"
:key="frequency"
:center-frequency="frequency"
:master-gain="masterGainNode"
@ready="onBandReady"
/>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'
import NoiseControlledWebAudioBand from '~/components/experiments/tests/ControlValues/NoiseControlledWebAudioBand.vue'
import { useAudioStore } from '~/stores/audio'
export default defineComponent({
components: {
NoiseControlledWebAudioBand,
KeyboardPlayHandler
},
setup () {
const { t } = useI18n()
const frequencies = ref([63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000])
const loadedBands = ref(0)
const masterGainNode = computed(() => { return useAudioStore().getMasterGainNoise() })
const masterAttack = ref(120000 * 2) // Beispielwert in Samples
const masterRelease = ref(144000 * 2)
const loading = computed(() => loadedBands.value < frequencies.value.length)
const updateMasterGain = (changeEvent:Event) => {
const newValue = changeEvent?.target as any
masterGainNode.value.gain.linearRampToValueAtTime(newValue.value, masterGainNode.value.context.currentTime + 0.25)
}
const onBandReady = () => {
loadedBands.value++
}
return {
frequencies,
loading,
onBandReady,
t,
loadedBands,
masterGainNode,
updateMasterGain,
masterAttack,
masterRelease
}
}
})
</script>

View File

@@ -0,0 +1,110 @@
<!--
/**
* @component ControlValueBasedPlayer
* @description A component that renders multiple NoiseControlledBand components,
* each centered around a specific frequency. This can be used for
* audio spectrum visualization or control. Now includes a loading spinner
* that disappears when all NoiseControlledBand components are ready.
*
* @uses NoiseControlledBand
*
* @example
* <ControlValueBasedPlayer />
*
* @remarks
* - Utilizes Vue 3 Composition API
* - Renders NoiseControlledBand components for standard audio frequency bands
* - Frequencies: 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000 Hz
* - Includes a loading spinner that disappears when all components are ready
*/
-->
<template>
<div>
<h1> Test Fall 3 mit Control Value Patch</h1>
<h3> Drei AudioTags gesteuert über 3 RNBOControlValues. Über die Volume-APi wird die Lautstärke gesteuert</h3>
<div v-if="isExperimentsRoute">
<KeyboardPlayHandler />
<PlayButton />
<div v-if="loading" class="spinner-border spinner-border-sm" role="status">
<span class="sr-only">{{ t("Loading...") }}</span>
</div>
Loaded Bands: {{ loadedBands }}
<div>
<label>Attack: {{ (masterAttack / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterAttack"
type="range"
:min="4800"
:max="1920000"
>
<label>Release: {{ (masterRelease / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterRelease"
type="range"
:min="4800"
:max="1920000"
>
</div>
<NoiseControlled3Band
v-for="(frequency, index) in frequencies"
:key="frequency"
:master-attack="masterAttack"
:master-release="masterRelease"
:center-frequency="frequency"
:q-factor="qFactors[index]"
@ready="onBandReady"
@update:mid-volume="controlMusicGain"
/>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'
import PlayButton from '~/components/experiments/statemanagement/PlayButton.vue'
import NoiseControlled3Band from '~/components/experiments/tests/ControlValues/NoiseControlled3Band.vue'
export default defineComponent({
components: {
NoiseControlled3Band,
KeyboardPlayHandler,
PlayButton
},
setup () {
const { t } = useI18n()
const frequencies = ref([150, 1500, 8000])
const qFactors = ref([0.8, 0.9, 0.6])
const loadedBands = ref(0)
const route = useRoute()
const isExperimentsRoute = computed(() => route.path.match(/\/[a-z]{2}\/experiments/))
const masterAttack = ref(120000 * 2) // Beispielwert in Samples
const masterRelease = ref(144000 * 2)
const loading = computed(() => loadedBands.value < frequencies.value.length)
const onBandReady = () => {
loadedBands.value++
}
return {
frequencies,
loading,
onBandReady,
t,
loadedBands,
masterAttack,
masterRelease,
isExperimentsRoute,
qFactors,
controlMusicGain
}
}
})
</script>

View File

@@ -0,0 +1,180 @@
<!--
/**
* @component ControlValueBasedPlayer
* @description A component that renders multiple NoiseControlledBand components,
* each centered around a specific frequency. This can be used for
* audio spectrum visualization or control. Now includes a loading spinner
* that disappears when all NoiseControlledBand components are ready.
*
* @uses NoiseControlledBand
*
* @example
* <ControlValueBasedPlayer />
*
* @remarks
* - Utilizes Vue 3 Composition API
* - Renders NoiseControlledBand components for standard audio frequency bands
* - Frequencies: 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000 Hz
* - Includes a loading spinner that disappears when all components are ready
*/
-->
<template>
<div>
<div v-if="isExperimentsRoute">
<h1> Test Fall 4 mit Control Value Patch</h1>
<h3> Drei WebAudioTag gesteuert über 3 RNBOControlValues. Über die WebAudio-APi wird die Lautstärke gesteuert</h3>
<KeyboardPlayHandler />
<PlayButton />
<div v-if="loading" class="spinner-border spinner-border-sm" role="status">
<span class="sr-only">{{ t("Loading...") }}</span>
</div>
Loaded Bands: {{ loadedBands }}
<div>
<label>Attack: {{ (masterAttack / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterAttack"
type="range"
:min="4800"
:max="1920000"
>
<label>Release: {{ (masterRelease / 480000).toFixed(2) }}s</label>
<input
v-model.number="masterRelease"
type="range"
:min="4800"
:max="1920000"
>
</div>
</div>
<NoiseControlled3BandWebAudio
v-for="(frequency, index) in frequencies"
v-show="false"
:key="frequency"
:master-attack="masterAttack"
:master-release="masterRelease"
:center-frequency="frequency"
:master-gain="masterGain"
:q-factor="qFactors[index]"
@ready="onBandReady"
@update:mid-volume="controlMusicGain"
/>
<div class="slider-wrapper">
<img
v-if="muted"
style="width: 25px; height: 25px;"
src="~/assets/image/sound_muted.svg"
title="Click to unmute"
@click="toggleMute()"
>
<img
v-else
style="width: 25px; height: 25px;"
src="~/assets/image/sound.svg"
title="Click to mute"
@click="toggleMute()"
>
<div class="slider">
<input
id="gain-control"
v-model="masterGain.gain.value"
type="range"
min="0"
max="1"
step="0.02"
data-toggle="tooltip"
data-placement="top"
title="Change the volume by click, scroll or touch"
@wheel.prevent="changeVolumeOnWheel"
>
<span
class="slider-progress-bar"
:style="{ width: `${masterGain.gain.value * 100}%` }"
/>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router'
import KeyboardPlayHandler from '~/archive/components/KeyboardPlayHandler.vue'
import PlayButton from '~/components/experiments/statemanagement/PlayButton.vue'
import NoiseControlled3BandWebAudio from '~/components/experiments/tests/ControlValues/NoiseControlledWebAudio3Band.vue'
import { useAudioStore } from '~/stores/audio'
export default defineComponent({
components: {
NoiseControlled3BandWebAudio,
KeyboardPlayHandler,
PlayButton
},
setup () {
const masterGain = ref(useAudioStore().getMasterGainNoise())
const { t } = useI18n()
const frequencies = ref([150, 1500, 8000])
const qFactors = ref([0.8, 0.9, 0.6])
const loadedBands = ref(0)
const muted = computed(() => useAudioStore().getMasterGainNoise().gain.value === 0)
let oldVolume = 0
const route = useRoute()
const isExperimentsRoute = computed(() => route.path.match(/\/[a-z]{2}\/experiments/))
const masterAttack = ref(120000 * 2) // Beispielwert in Samples
const masterRelease = ref(144000 * 2)
const loading = computed(() => loadedBands.value < frequencies.value.length)
const onBandReady = () => {
loadedBands.value++
}
const toggleMute = () => {
if (!muted.value) {
oldVolume = masterGain.value.gain.value
masterGain.value.gain.linearRampToValueAtTime(0, masterGain.value.context.currentTime + 0.4)
} else if (oldVolume > 0) {
masterGain.value.gain.linearRampToValueAtTime(oldVolume, masterGain.value.context.currentTime + 0.4)
} else {
masterGain.value.gain.linearRampToValueAtTime(1, masterGain.value.context.currentTime + 0.4)
}
}
const controlMusicGain = (value: string) => {
}
const changeVolumeOnWheel = (event:WheelEvent) => {
let gainValue = masterGain.value.gain.value
// Adjust volume on wheel scroll
const deltaY = event.deltaY
if (deltaY < 0) {
const volumeAdd = (Math.min(1, gainValue + 0.02))
gainValue = volumeAdd
} else {
const volumeCut = (Math.max(0, gainValue - 0.02))
gainValue = volumeCut
}
}
return {
frequencies,
loading,
onBandReady,
t,
loadedBands,
masterAttack,
masterRelease,
isExperimentsRoute,
qFactors,
controlMusicGain,
masterGain,
changeVolumeOnWheel,
toggleMute,
muted
}
}
})
</script>