mindboost-rnbo-test-project/components/Player/Nodes.ts

110 lines
4.6 KiB
TypeScript

import { usePlayerStore } from '~/stores/player'
import { createRNBODevice } from '~/lib/AudioFunctions'
import importedMusicPatcher from 'assets/patch/music_patch.export.json'
import importedNoisePatcher from 'assets/patch/noise_patch.export.json'
import { ANC } from '~/stores/interfaces/ANC'
import { HeadsetType } from '~/stores/interfaces/HeadsetType'
import { useUserStore } from '~/stores/user'
import { useMicStore } from '~/stores/microphone'
enum AttenuationFactor{
OverEarANC = 0.0562,
OverEar = 0.5623,
InEar = 0.1778,
InEarANC = 0.0316
}
const logger = useNuxtApp().$logger
function getAttenuationFactor (anc:ANC, ht:HeadsetType): Number {
if (anc === ANC.Yes && ht === HeadsetType.OverEar) { return AttenuationFactor.OverEarANC }
if (anc === ANC.No && ht === HeadsetType.OverEar) { return AttenuationFactor.OverEar }
if (anc === ANC.Yes && ht === HeadsetType.InEar) { return AttenuationFactor.InEarANC }
if (anc === ANC.No && ht === HeadsetType.InEar) { return AttenuationFactor.InEar }
return 0.5623
}
export default async function setupNodes (noiseAudioSource: MediaElementAudioSourceNode, musicAudioSource: MediaElementAudioSourceNode): Promise<Array<GainNode> | null> {
const playerStore = usePlayerStore()
const microphone = await useMicStore().getMicrophoneInHowlerContext()
const context = Howler.ctx
// Parameter validation
// Parameter validation
// Parameter validation
if(!(noiseAudioSource instanceof AudioNode)) {
useNuxtApp().$logger.warn("Parameter noiseAudioSource is not an AudioNode... skipping RNBO setup")
return null
}
if(!(musicAudioSource instanceof AudioNode)) {
useNuxtApp().$logger.warn("Parameter musicAudioSource is not an AudioNode... skipping RNBO setup")
return null
}
if(microphone.microphoneNode?.context !== noiseAudioSource.context && microphone.microphoneNode?.context !== musicAudioSource.context) {
logger.error("Microphone and AudioSources are in different AudioContexts... skipping RNBO setup" )
return null
}
// Register the source nodes at the audio store
// Register the source nodes at the audio store
const noiseSource = playerStore.addNode('noiseAudioSource', noiseAudioSource)
const musicSource = playerStore.addNode('musicAudioSource', musicAudioSource)
// Prepare gain nodes
// Prepare gain nodes
// Prepare gain nodes
const musicGainNode = context.createGain()
const noiseGainNode = context.createGain()
musicGainNode.gain.value = 0
noiseGainNode.gain.value = 0
const musicGain = playerStore.addNode('musicGainNode', musicGainNode)
const noiseGain = playerStore.addNode('noiseGainNode', noiseGainNode)
// create RNBO Devices
// create RNBO Devices
// create RNBO Devices
const noiseDevice = await createRNBODevice(context, importedNoisePatcher)
const musicDevice = await createRNBODevice(context, importedMusicPatcher)
const noiseDeviceNode = playerStore.addNode('noiseDevice', noiseDevice.node)
const musicDeviceNode = playerStore.addNode('musicDevice', musicDevice.node)
// create Channel-Splitter
// create Channel-Splitter
// create Channel-Splitter
const musicInputSplit = playerStore.addNode('musicInputChannelSplitter', new ChannelSplitterNode(context, { numberOfOutputs: 2 }))
const noiseInputSplit = playerStore.addNode('noiseInputChannelSplitter', new ChannelSplitterNode(context, { numberOfOutputs: 2 }))
// add microphone node
// add microphone node
// add microphone node
const micNode = playerStore.addNode('microphone', microphone.microphoneNode)
// MUSIC PATCH
// MUSIC PATCH
// MUSIC PATCH
playerStore.connectNodes(micNode, musicDeviceNode, 0, 0)
playerStore.connectNodes(musicSource, musicInputSplit, 0, 0)
playerStore.connectNodes(musicInputSplit, musicDeviceNode, 0, 1)
playerStore.connectNodes(musicInputSplit, musicDeviceNode, 1, 2)
playerStore.connectNodes(musicDeviceNode, musicGain) // Ausgang zu Gain
playerStore.connectNodes(musicGain, playerStore.addNode('contextDestination', context.destination)) // Output
// NOISE PATCH
// NOISE PATCH
// NOISE PATCH
playerStore.connectNodes(micNode, noiseDeviceNode, 0, 0)
playerStore.connectNodes(noiseSource, noiseInputSplit, 0, 0)
playerStore.connectNodes(noiseInputSplit, noiseDeviceNode, 0, 1)
playerStore.connectNodes(noiseInputSplit, noiseDeviceNode, 1, 2)
playerStore.connectNodes(noiseDeviceNode, noiseGain)
playerStore.connectNodes(noiseGain, playerStore.addNode('contextDestination', context.destination))
const attenuationFactor = noiseDevice.parametersById.get('attenuation')
attenuationFactor.value = getAttenuationFactor('Yes' as ANC, 'OverEar' as HeadsetType)
// Return the gainNodes
return [musicGainNode, noiseGainNode]
}