添加更多环境混响音效
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
|
||||
Reference in New Issue
Block a user