mindboost-rnbo-test-project/components/AudioReactiveBar.vue

114 lines
3.4 KiB
Vue

<template>
<div class="progress" style="height: 10px; width: 100%;">
<div
class="progress-bar bar"
role="progressbar"
aria-label="Basic example"
:style="{width:bar_width+'%'}"
style="background-color: #e9c046;transition: 0.1s"
aria-valuenow="75"
aria-valuemin="0"
aria-valuemax="100"
/>
</div>
<div v-if="false">
<h3>Debug Test</h3>
<h4>Current Microphone: {{ microphoneLabel }}</h4>
<h4>Current Steam ID: {{ deviceId }}</h4>
<button @click="updateMicrophone">Change Microphone</button>
</div>
</template>
<script>
import { mapState } from 'pinia'
import { useMicStore } from '@/stores/microphone'
export default {
components: {
},
data () {
return {
t: useI18n,
// meter
meter: null,
bar_width: 0,
analyser: null,
dataArray: null,
bar_val: 25,
microphoneLabel: null,
microAnalyse: null,
deviceId: null
}
},
computed: {
...mapState(useMicStore, 'microphone')
},
beforeUnmount () {
if (this.audioContext) { this.audioContext.close() }
this.audioContext = null
useMicStore().detachMicrophone()
},
mounted () {
// useNuxtApp().$logger.log('mounted ', this.microphone)
useMicStore().getMicrophone().then((mic) => {
// useNuxtApp().$logger.log('Microphone ready')
const audioCtx = mic.microphoneNode.context
useNuxtApp().$logger.log({ mic })
this.microphoneLabel = mic.microphoneLabel
this.deviceId = mic.deviceId || 'unknown'
this.analyser = audioCtx.createAnalyser()
mic.microphoneNode.connect(this.analyser)
this.analyser.fftSize = 2048
const bufferLength = this.analyser.frequencyBinCount
this.dataArray = new Uint8Array(bufferLength)
this.updateMeter()
})
},
methods: {
updateMeter () {
requestAnimationFrame(this.updateMeter)
this.analyser.getByteFrequencyData(this.dataArray)
const rms = this.getRMS(this.dataArray)
let level = 90 * Math.log10(rms / 128)
level = Math.max(0, Math.min(100, level + 100))
// bar.style.width = level + '%'
this.bar_width = level
},
getRMS (dataArray) {
let rms = 0
for (let i = 0; i < dataArray.length; i++) {
rms += dataArray[i] * dataArray[i]
}
rms /= dataArray.length
rms = Math.sqrt(rms)
return rms
},
async updateMicrophone () {
if (!(this.deviceId instanceof String)) {
let devices = useMicStore().availableDevices
devices = devices.filter(x => x.label !== this.microphoneLabel)
const newDevice = devices.pop()
this.microphoneLabel = newDevice.label
this.deviceId = newDevice.deviceId
await useMicStore().switchMicrophone(this.deviceId)
}
try {
const mic = useMicStore().microphone
if (mic && mic.microphoneNode) {
const audioCtx = mic.microphoneNode.context
this.analyser = audioCtx.createAnalyser()
mic.microphoneNode.connect(this.analyser)
this.analyser.fftSize = 2048
const bufferLength = this.analyser.frequencyBinCount
this.dataArray = new Uint8Array(bufferLength)
this.updateMeter()
}
} catch (error) {
useNuxtApp().$logger.error('Error updating microphone in AudioReactiveBar:', error)
}
}
}
}
</script>
<style scoped>
</style>