添加更多环境混响音效

This commit is contained in:
lyswhut
2023-05-04 19:14:00 +08:00
parent 9dc927b50b
commit 735f629ca1
23 changed files with 201 additions and 93 deletions
+8 -7
View File
@@ -56,6 +56,7 @@ const popupStyle = reactive({
const arrowHeight = 9
const arrowWidth = 8
const sidePadding = 50
watch(() => props.visible, (visible) => {
if (!visible || !dom_content.value || !props.btnEl) return
@@ -63,24 +64,24 @@ watch(() => props.visible, (visible) => {
const maxHeight = document.body.clientHeight
const elTop = rect.top - window.lx.rootOffset
const bottomTopVal = elTop + rect.height
const contentHeight = dom_content.value.scrollHeight + arrowHeight + 10
const contentHeight = dom_content.value.scrollHeight + arrowHeight + sidePadding
if (bottomTopVal + contentHeight < maxHeight || (contentHeight > elTop && elTop <= maxHeight - bottomTopVal)) {
isShowTop.value = false
popupStyle.top = bottomTopVal + arrowHeight + 'px'
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - 10 + 'px'
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - sidePadding + 'px'
} else {
isShowTop.value = true
let maxContentHeight = elTop - arrowHeight - 10
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + 10) + 'px'
let maxContentHeight = elTop - arrowHeight - sidePadding
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + sidePadding) + 'px'
popupStyle.maxHeight = maxContentHeight + 'px'
}
const maxWidth = document.body.clientWidth - 20
let center = dom_content.value.clientWidth / 2
let left = rect.left + rect.width / 2 - window.lx.rootOffset - center
if (left < 10) {
center -= 10 - left
left = 10
if (left < sidePadding) {
center -= sidePadding - left
left = sidePadding
} else if (left + dom_content.value.clientWidth > maxWidth) {
let newLeft = maxWidth - dom_content.value.clientWidth
center = center + left - newLeft
@@ -1,17 +1,31 @@
<template>
<div :class="$style.contnet">
<h3 class="player__sound_effect_title">{{ $t('player__sound_effect_convolution') }}</h3>
<div :class="$style.convolutionList">
<base-checkbox
v-for="item in convolutions"
:id="`player__convolution_${item.name}`"
:key="item.name"
:class="$style.checkbox"
:model-value="appSetting['player.soundEffect.convolution.fileName']"
:label="$t(`player__sound_effect_convolution_${item.name}`)"
:value="item.source"
@update:model-value="updateConvolution($event)"
/>
<div :class="$style.convolution">
<div :class="$style.convolutionList">
<base-checkbox
v-for="item in convolutions"
:id="`player__convolution_${item.name}`"
:key="item.name"
:class="$style.checkbox"
:model-value="appSetting['player.soundEffect.convolution.fileName']"
:label="$t(`player__sound_effect_convolution_file_${item.name}`)"
:value="item.source"
@update:model-value="updateConvolution($event)"
/>
</div>
<div :class="$style.sliderList">
<div :class="$style.sliderItem">
<span :class="$style.label">{{ $t('player__sound_effect_convolution_main_gain') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.convolution.mainGain']" :min="0" :max="50" @change="handleUpdateMainGain" />
<span :class="[$style.value]">{{ appSetting['player.soundEffect.convolution.mainGain'] * 10 }}%</span>
</div>
<div :class="$style.sliderItem">
<span :class="$style.label">{{ $t('player__sound_effect_convolution_send_gain') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.convolution.sendGain']" :min="0" :max="50" @change="handleUpdateSendGain" />
<span :class="[$style.value]">{{ appSetting['player.soundEffect.convolution.sendGain'] * 10 }}%</span>
</div>
</div>
</div>
</div>
</template>
@@ -22,10 +36,25 @@ import { appSetting, updateSetting } from '@renderer/store/setting'
import { convolutions } from '@renderer/plugins/player'
const updateConvolution = val => {
console.log(val)
updateSetting({ 'player.soundEffect.convolution.fileName': val })
const target = convolutions.find(c => c.source == val)
const setting = {
'player.soundEffect.convolution.fileName': val,
}
if (target) {
setting['player.soundEffect.convolution.mainGain'] = target.mainGain * 10
setting['player.soundEffect.convolution.sendGain'] = target.sendGain * 10
}
updateSetting(setting)
}
const handleUpdateMainGain = (value) => {
updateSetting({ 'player.soundEffect.convolution.mainGain': Math.round(value) })
}
const handleUpdateSendGain = (value) => {
updateSetting({ 'player.soundEffect.convolution.sendGain': Math.round(value) })
}
</script>
<style lang="less" module>
@@ -35,6 +64,12 @@ const updateConvolution = val => {
flex-flow: column nowrap;
gap: 3px;
}
.convolution {
display: flex;
flex-flow: column wrap;
gap: 15px;
width: 100%;
}
.convolutionList {
display: flex;
flex-flow: row wrap;
@@ -45,4 +80,34 @@ const updateConvolution = val => {
margin-right: 10px;
font-size: 12px;
}
.sliderList {
display: flex;
flex-flow: column nowrap;
gap: 15px;
width: 100%;
}
.sliderItem {
display: flex;
flex-flow: row nowrap;
gap: 8px;
}
.slider {
flex: auto;
}
.label {
flex: none;
// width: 50px;
font-size: 12px;
}
.value {
flex: none;
width: 40px;
font-size: 12px;
text-align: center;
&.active {
color: var(--color-primary-font);
}
}
</style>
@@ -1,7 +1,6 @@
import { watch } from '@common/utils/vueTools'
import {
freqs,
convolutions,
getAudioContext,
getBiquadFilter,
setConvolver,
@@ -9,6 +8,8 @@ import {
setPannerSpeed,
startPanner,
stopPanner,
setConvolverMainGain,
setConvolverSendGain,
} from '@renderer/plugins/player'
import { appSetting } from '@renderer/store/setting'
@@ -62,8 +63,7 @@ export default () => {
}
if (appSetting['player.soundEffect.convolution.fileName']) {
void loadBuffer(appSetting['player.soundEffect.convolution.fileName']).then((buffer) => {
const target = convolutions.find(c => c.source == appSetting['player.soundEffect.convolution.fileName'])
setConvolver(buffer, target!.sendGain, target!.mainGain)
setConvolver(buffer, appSetting['player.soundEffect.convolution.mainGain'] / 10, appSetting['player.soundEffect.convolution.sendGain'] / 10)
})
}
@@ -85,14 +85,19 @@ export default () => {
setTimeout(() => {
if (fileName) {
void loadBuffer(fileName).then((buffer) => {
const target = convolutions.find(c => c.source == fileName)
setConvolver(buffer, target!.sendGain, target!.mainGain)
setConvolver(buffer, appSetting['player.soundEffect.convolution.mainGain'] / 10, appSetting['player.soundEffect.convolution.sendGain'] / 10)
})
} else {
setConvolver(null, 0, 0)
}
})
})
watch(() => appSetting['player.soundEffect.convolution.mainGain'], (mainGain) => {
setConvolverMainGain(mainGain / 10)
})
watch(() => appSetting['player.soundEffect.convolution.sendGain'], (sendGain) => {
setConvolverSendGain(sendGain / 10)
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz31'], (hz31) => {
const bfs = getBiquadFilter()
bfs.get('hz31')!.gain.value = hz31
+35 -40
View File
@@ -8,42 +8,24 @@ export const freqs = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000] as c
type Freqs = (typeof freqs)[number]
let biquads: Map<`hz${Freqs}`, BiquadFilterNode>
export const convolutions = [
{
name: 'telephone', // 电话
mainGain: 0.0,
sendGain: 3.0,
source: 'filter-telephone.wav',
},
{
name: 'spreader', // 室内
mainGain: 1.0,
sendGain: 2.5,
source: 'spreader50-65ms.wav',
},
{
name: 'feedback_spring', // 山洞
mainGain: 0.0,
sendGain: 2.4,
source: 'feedback-spring.wav',
},
{
name: 'church', // 教堂
mainGain: 1.8,
sendGain: 0.9,
source: 's2_r4_bd.wav',
},
{
name: 'kitchen', // 厨房
mainGain: 0.6,
sendGain: 3.0,
source: 'kitchen-true-stereo.wav',
},
{
name: 'wc', // 厕所
mainGain: 0.6,
sendGain: 2.1,
source: 'living-bedroom-leveled.wav',
},
{ name: 'telephone', mainGain: 0.0, sendGain: 3.0, source: 'filter-telephone.wav' }, // 电话
{ name: 's2_r4_bd', mainGain: 1.8, sendGain: 0.9, source: 's2_r4_bd.wav' }, // 教堂
{ name: 's3_r1_bd', mainGain: 1.8, sendGain: 0.8, source: 's3_r1_bd.wav' },
{ name: 'matrix_1', mainGain: 1.5, sendGain: 0.9, source: 'matrix-reverb1.wav' },
{ name: 'matrix_2', mainGain: 1.3, sendGain: 1, source: 'matrix-reverb2.wav' },
{ name: 'bright_hall', mainGain: 0.8, sendGain: 2.4, source: 'bright-hall.wav' },
{ name: 'cinema_diningroom', mainGain: 0.6, sendGain: 2.3, source: 'cinema-diningroom.wav' },
{ name: 'dining_living_true_stereo', mainGain: 0.6, sendGain: 1.8, source: 'dining-living-true-stereo.wav' },
{ name: 'living_bedroom_leveled', mainGain: 0.6, sendGain: 2.1, source: 'living-bedroom-leveled.wav' },
{ name: 'spreader50_65ms', mainGain: 1, sendGain: 2.5, source: 'spreader50-65ms.wav' },
{ name: 'spreader25_125ms', mainGain: 1, sendGain: 2.5, source: 'spreader25-125ms.wav' },
// { name: 'backslap', mainGain: 1.8, sendGain: 0.8, source: 'backslap1.wav' },
{ name: 'cardiod_35_10_spread', mainGain: 1.8, sendGain: 0.8, source: 'cardiod-35-10-spread.wav' },
{ name: 'tim_omni_35_10_magnetic', mainGain: 1.8, sendGain: 0.8, source: 'tim-omni-35-10-magnetic.wav' },
// { name: 'spatialized', mainGain: 1.8, sendGain: 0.8, source: 'spatialized8.wav' },
// { name: 'zing_long_stereo', mainGain: 0.8, sendGain: 1.8, source: 'zing-long-stereo.wav' },
{ name: 'feedback_spring', mainGain: 1.8, sendGain: 0.8, source: 'feedback-spring.wav' },
// { name: 'tim_omni_rear_blend', mainGain: 1.8, sendGain: 0.8, source: 'tim-omni-rear-blend.wav' },
] as const
let convolver: ConvolverNode
let convolverSourceGainNode: GainNode
@@ -147,18 +129,31 @@ export const getBiquadFilter = () => {
}
// let isConvolverConnected = false
export const setConvolver = (buffer: AudioBuffer | null, sendGain: number, mainGain: number) => {
export const setConvolver = (buffer: AudioBuffer | null, mainGain: number, sendGain: number) => {
initAdvancedAudioFeatures()
convolver.buffer = buffer
// console.log(mainGain, sendGain)
if (buffer) {
convolverOutputGainNode.gain.value = sendGain
convolverSourceGainNode.gain.value = mainGain
convolverOutputGainNode.gain.value = sendGain
} else {
convolverOutputGainNode.gain.value = 0
convolverSourceGainNode.gain.value = 1
convolverOutputGainNode.gain.value = 0
}
}
export const setConvolverMainGain = (gain: number) => {
if (convolverSourceGainNode.gain.value == gain) return
// console.log(gain)
convolverSourceGainNode.gain.value = gain
}
export const setConvolverSendGain = (gain: number) => {
if (convolverOutputGainNode.gain.value == gain) return
// console.log(gain)
convolverOutputGainNode.gain.value = gain
}
let pannerInfo = {
x: 0,
y: 0,
@@ -210,7 +205,7 @@ export const startPanner = () => {
}, pannerInfo.speed * 10)
}
export const hasInitedAnalyser = (): boolean => audioContext != null
export const hasInitedAdvancedAudioFeatures = (): boolean => audioContext != null
export const setResource = (src: string) => {
if (audio) audio.src = src
@@ -29,7 +29,7 @@ dd(:aria-label="$t('setting__play_mediaDevice_title')")
<script>
import { ref, onBeforeUnmount, watch } from '@common/utils/vueTools'
import { hasInitedAnalyser } from '@renderer/plugins/player'
import { hasInitedAdvancedAudioFeatures } from '@renderer/plugins/player'
import { dialog } from '@renderer/plugins/Dialog'
import { useI18n } from '@renderer/plugins/i18n'
import { appSetting, updateSetting } from '@renderer/store/setting'
@@ -56,7 +56,7 @@ export default {
const mediaDeviceId = ref(appSetting['player.mediaDeviceId'])
const handleMediaDeviceIdChnage = async() => {
if (hasInitedAnalyser()) {
if (hasInitedAdvancedAudioFeatures()) {
await dialog({
message: t('setting__play_media_device_error_tip'),
confirmButtonText: t('alert_button_text'),