From 04337ef4b834933b0312af31602663e8d221e5b9 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Mon, 8 May 2023 18:04:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9F=B3=E6=95=88=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E9=A2=84=E8=AE=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- publish/changeLog.md | 2 +- src/common/constants.ts | 1 + src/common/ipcNames.ts | 4 + src/common/types/sound_effect.d.ts | 25 +++++ src/lang/en-us.json | 17 ++- src/lang/zh-cn.json | 26 +++-- src/lang/zh-tw.json | 17 ++- .../modules/winMain/rendererEvent/index.ts | 2 + .../winMain/rendererEvent/soundEffect.ts | 20 ++++ src/main/types/common.d.ts | 1 + .../AddConvolutionPresetBtn.vue | 92 ++++++++++++++++ .../common/SoundEffectBtn/AddEQPresetBtn.vue | 99 ++++++++++++++++++ .../SoundEffectBtn/AudioConvolution.vue | 34 +++++- .../common/SoundEffectBtn/AudioPanner.vue | 26 +++-- .../common/SoundEffectBtn/BiquadFilter.vue | 81 ++++++++++++-- .../common/SoundEffectBtn/index.vue | 85 +++++++++++---- src/renderer/plugins/player.ts | 23 ++-- src/renderer/store/soundEffect.ts | 56 ++++++++++ src/renderer/types/common.d.ts | 1 + src/renderer/utils/ipc.ts | 16 +++ .../medias/filters/spreader25-125ms.wav | Bin 356896 -> 0 bytes 22 files changed, 571 insertions(+), 60 deletions(-) create mode 100644 src/common/types/sound_effect.d.ts create mode 100644 src/main/modules/winMain/rendererEvent/soundEffect.ts create mode 100644 src/renderer/components/common/SoundEffectBtn/AddConvolutionPresetBtn.vue create mode 100644 src/renderer/components/common/SoundEffectBtn/AddEQPresetBtn.vue create mode 100644 src/renderer/store/soundEffect.ts delete mode 100644 src/static/medias/filters/spreader25-125ms.wav diff --git a/.vscode/settings.json b/.vscode/settings.json index f7f6200a..530848ce 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,5 +12,6 @@ ], "i18n-ally.sortKeys": true, "javascript.preferences.importModuleSpecifier": "non-relative", - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "vue.codeActions.enabled": false } diff --git a/publish/changeLog.md b/publish/changeLog.md index e4f3ca33..d5acce3b 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,3 +1,3 @@ ### 新增 -- 新增音效设置(实验性功能),支持10段均衡器设置、3D立体环绕音效、内置的一些环境混响音效 +- 新增音效设置(实验性功能),支持10段均衡器设置、内置的一些环境混响音效、3D立体环绕音效 diff --git a/src/common/constants.ts b/src/common/constants.ts index 4c0c2b70..3975dfcb 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -10,6 +10,7 @@ export const STORE_NAMES = { LRC_RAW: 'lyrics', LRC_EDITED: 'lyrics_edited', THEME: 'theme', + SOUND_EFFECT: 'sound_effect', } as const export const APP_EVENT_NAMES = { diff --git a/src/common/ipcNames.ts b/src/common/ipcNames.ts index cb653317..61cf2045 100644 --- a/src/common/ipcNames.ts +++ b/src/common/ipcNames.ts @@ -90,6 +90,10 @@ const modules = { get_other_source_count: 'get_other_source_count', get_data: 'get_data', save_data: 'save_data', + get_sound_effect_eq_preset: 'get_sound_effect_eq_preset', + save_sound_effect_eq_preset: 'save_sound_effect_eq_preset', + get_sound_effect_convolution_preset: 'get_sound_effect_convolution_preset', + save_sound_effect_convolution_preset: 'save_sound_effect_convolution_preset', get_hot_key: 'get_hot_key', import_user_api: 'import_user_api', diff --git a/src/common/types/sound_effect.d.ts b/src/common/types/sound_effect.d.ts new file mode 100644 index 00000000..89a7ea34 --- /dev/null +++ b/src/common/types/sound_effect.d.ts @@ -0,0 +1,25 @@ +declare namespace LX { + namespace SoundEffect { + interface EQPreset { + id: string + name: string + hz31: number + hz62: number + hz125: number + hz250: number + hz500: number + hz1000: number + hz2000: number + hz4000: number + hz8000: number + hz16000: number + } + interface ConvolutionPreset { + id: string + name: string + source: string + mainGain: number + sendGain: number + } + } +} diff --git a/src/lang/en-us.json b/src/lang/en-us.json index 9a09ff11..8c44a185 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -228,9 +228,20 @@ "player__playing": "Now playing...", "player__prev": "Prev", "player__refresh_url": "Music URL expired, refreshing...", - "player__sound_effect": "Sound settings", + "player__sound_effect": "Sound settings (experimental)", "player__sound_effect_biquad_filter": "Equalizer", - "player__sound_effect_biquad_filter_reset_btn": "Reset equalizer", + "player__sound_effect_biquad_filter_preset_classical": "Classical", + "player__sound_effect_biquad_filter_preset_dance": "Dance", + "player__sound_effect_biquad_filter_preset_electronic": "Electronic", + "player__sound_effect_biquad_filter_preset_pop": "Pop", + "player__sound_effect_biquad_filter_preset_rock": "Rock", + "player__sound_effect_biquad_filter_preset_slow": "Slow", + "player__sound_effect_biquad_filter_preset_soft": "Soft", + "player__sound_effect_biquad_filter_preset_subwoofer": "Subwoofer", + "player__sound_effect_biquad_filter_preset_vocal": "Vocal", + "player__sound_effect_biquad_filter_reset_btn": "Reset", + "player__sound_effect_biquad_filter_save_btn": "Save preset as", + "player__sound_effect_biquad_filter_save_input": "New presets...", "player__sound_effect_convolution": "Ambient reverb sound effect", "player__sound_effect_convolution_file_bright_hall": "Hall", "player__sound_effect_convolution_file_cardiod_35_10_spread": "Rock", @@ -241,7 +252,7 @@ "player__sound_effect_convolution_file_matrix_1": "Matrix", "player__sound_effect_convolution_file_matrix_2": "Matrix 2", "player__sound_effect_convolution_file_s2_r4_bd": "Church", - "player__sound_effect_convolution_file_s3_r1_bd": "Church 2", + "player__sound_effect_convolution_file_s3_r1_bd": "Stereo", "player__sound_effect_convolution_file_spreader25_125ms": "Indoor 2", "player__sound_effect_convolution_file_spreader50_65ms": "Indoor", "player__sound_effect_convolution_file_telephone": "Telephone", diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index 5f6c559d..70f4ef85 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -228,24 +228,34 @@ "player__playing": "播放中...", "player__prev": "上一首", "player__refresh_url": "URL过期,正在刷新URL...", - "player__sound_effect": "音效设置", + "player__sound_effect": "音效设置(实验性)", "player__sound_effect_biquad_filter": "均衡器", - "player__sound_effect_biquad_filter_reset_btn": "重置均衡器", + "player__sound_effect_biquad_filter_preset_classical": "古典", + "player__sound_effect_biquad_filter_preset_dance": "舞曲", + "player__sound_effect_biquad_filter_preset_electronic": "电子乐", + "player__sound_effect_biquad_filter_preset_pop": "流行", + "player__sound_effect_biquad_filter_preset_rock": "摇滚", + "player__sound_effect_biquad_filter_preset_slow": "慢歌", + "player__sound_effect_biquad_filter_preset_soft": "柔和", + "player__sound_effect_biquad_filter_preset_subwoofer": "重低音", + "player__sound_effect_biquad_filter_preset_vocal": "人声", + "player__sound_effect_biquad_filter_reset_btn": "重置", + "player__sound_effect_biquad_filter_save_btn": "另存预设", + "player__sound_effect_biquad_filter_save_input": "新预设...", "player__sound_effect_convolution": "环境混响音效", "player__sound_effect_convolution_file_bright_hall": "大厅", - "player__sound_effect_convolution_file_cardiod_35_10_spread": "摇滚", + "player__sound_effect_convolution_file_cardiod_35_10_spread": "心形扩散", "player__sound_effect_convolution_file_cinema_diningroom": "电影院", "player__sound_effect_convolution_file_dining_living_true_stereo": "餐厅", "player__sound_effect_convolution_file_feedback_spring": "反馈弹簧", "player__sound_effect_convolution_file_living_bedroom_leveled": "卫生间", - "player__sound_effect_convolution_file_matrix_1": "矩阵", - "player__sound_effect_convolution_file_matrix_2": "矩阵2", + "player__sound_effect_convolution_file_matrix_1": "矩阵混响", + "player__sound_effect_convolution_file_matrix_2": "矩阵混响2", "player__sound_effect_convolution_file_s2_r4_bd": "教堂", - "player__sound_effect_convolution_file_s3_r1_bd": "教堂2", - "player__sound_effect_convolution_file_spreader25_125ms": "室内2", + "player__sound_effect_convolution_file_s3_r1_bd": "立体声", "player__sound_effect_convolution_file_spreader50_65ms": "室内", "player__sound_effect_convolution_file_telephone": "电话", - "player__sound_effect_convolution_file_tim_omni_35_10_magnetic": "摇滚2", + "player__sound_effect_convolution_file_tim_omni_35_10_magnetic": "磁性立体声", "player__sound_effect_convolution_main_gain": "原始音频增益", "player__sound_effect_convolution_send_gain": "环境音效增益", "player__sound_effect_panner": "3D立体环绕(需使用耳机)", diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 6ed30e0a..1bd2cadf 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -228,9 +228,20 @@ "player__playing": "播放中...", "player__prev": "上一首", "player__refresh_url": "URL過期,正在刷新URL...", - "player__sound_effect": "音效設置", + "player__sound_effect": "音效設置(實驗性)", "player__sound_effect_biquad_filter": "均衡器", - "player__sound_effect_biquad_filter_reset_btn": "重置均衡器", + "player__sound_effect_biquad_filter_preset_classical": "古典", + "player__sound_effect_biquad_filter_preset_dance": "舞曲", + "player__sound_effect_biquad_filter_preset_electronic": "電子樂", + "player__sound_effect_biquad_filter_preset_pop": "流行", + "player__sound_effect_biquad_filter_preset_rock": "搖滾", + "player__sound_effect_biquad_filter_preset_slow": "慢歌", + "player__sound_effect_biquad_filter_preset_soft": "柔和", + "player__sound_effect_biquad_filter_preset_subwoofer": "重低音", + "player__sound_effect_biquad_filter_preset_vocal": "人聲", + "player__sound_effect_biquad_filter_reset_btn": "重置", + "player__sound_effect_biquad_filter_save_btn": "另存預設", + "player__sound_effect_biquad_filter_save_input": "新預設...", "player__sound_effect_convolution": "環境混響音效", "player__sound_effect_convolution_file_bright_hall": "大廳", "player__sound_effect_convolution_file_cardiod_35_10_spread": "搖滾", @@ -241,7 +252,7 @@ "player__sound_effect_convolution_file_matrix_1": "矩陣", "player__sound_effect_convolution_file_matrix_2": "矩陣2", "player__sound_effect_convolution_file_s2_r4_bd": "教堂", - "player__sound_effect_convolution_file_s3_r1_bd": "教堂2", + "player__sound_effect_convolution_file_s3_r1_bd": "立體聲", "player__sound_effect_convolution_file_spreader25_125ms": "室內2", "player__sound_effect_convolution_file_spreader50_65ms": "室內", "player__sound_effect_convolution_file_telephone": "電話", diff --git a/src/main/modules/winMain/rendererEvent/index.ts b/src/main/modules/winMain/rendererEvent/index.ts index 1f3700d8..240f8a0e 100644 --- a/src/main/modules/winMain/rendererEvent/index.ts +++ b/src/main/modules/winMain/rendererEvent/index.ts @@ -9,6 +9,7 @@ import sync from './sync' import data from './data' import music from './music' import download from './download' +import soundEffect from './soundEffect' import { sendEvent } from '../main' export * from './app' @@ -33,6 +34,7 @@ export default () => { data() music() download() + soundEffect() global.lx.event_app.on('updated_config', (keys, setting) => { sendConfigChange(setting) diff --git a/src/main/modules/winMain/rendererEvent/soundEffect.ts b/src/main/modules/winMain/rendererEvent/soundEffect.ts new file mode 100644 index 00000000..72df4ecb --- /dev/null +++ b/src/main/modules/winMain/rendererEvent/soundEffect.ts @@ -0,0 +1,20 @@ +import { STORE_NAMES } from '@common/constants' +import { WIN_MAIN_RENDERER_EVENT_NAME } from '@common/ipcNames' +import { mainOn, mainHandle } from '@common/mainIpc' +import getStore from '@main/utils/store' + +export default () => { + mainHandle(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_eq_preset, async() => { + return getStore(STORE_NAMES.SOUND_EFFECT).get('eqPreset') as LX.SoundEffect.EQPreset[] | null ?? [] + }) + mainOn(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_eq_preset, ({ params }) => { + getStore(STORE_NAMES.SOUND_EFFECT).set('eqPreset', params) + }) + + mainHandle(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_convolution_preset, async() => { + return getStore(STORE_NAMES.SOUND_EFFECT).get('convolutionPreset') as LX.SoundEffect.ConvolutionPreset[] | null ?? [] + }) + mainOn(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_convolution_preset, ({ params }) => { + getStore(STORE_NAMES.SOUND_EFFECT).set('convolutionPreset', params) + }) +} diff --git a/src/main/types/common.d.ts b/src/main/types/common.d.ts index 68cafe1b..28e03daa 100644 --- a/src/main/types/common.d.ts +++ b/src/main/types/common.d.ts @@ -10,3 +10,4 @@ import '@common/types/player' import '@common/types/desktop_lyric' import '@common/types/theme' import '@common/types/ipc_main' +import '@common/types/sound_effect' diff --git a/src/renderer/components/common/SoundEffectBtn/AddConvolutionPresetBtn.vue b/src/renderer/components/common/SoundEffectBtn/AddConvolutionPresetBtn.vue new file mode 100644 index 00000000..a4be500c --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/AddConvolutionPresetBtn.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/AddEQPresetBtn.vue b/src/renderer/components/common/SoundEffectBtn/AddEQPresetBtn.vue new file mode 100644 index 00000000..24bd9015 --- /dev/null +++ b/src/renderer/components/common/SoundEffectBtn/AddEQPresetBtn.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue b/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue index de7f3e75..547da43b 100644 --- a/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue +++ b/src/renderer/components/common/SoundEffectBtn/AudioConvolution.vue @@ -27,13 +27,19 @@ +
+ {{ item.name }} + +
@@ -63,6 +87,7 @@ const handleUpdateSendGain = (value) => { display: flex; flex-flow: column nowrap; gap: 3px; + min-height: 0; } .convolution { display: flex; @@ -110,4 +135,11 @@ const handleUpdateSendGain = (value) => { color: var(--color-primary-font); } } +.saveList { + display: flex; + flex-flow: row wrap; + margin-top: 10px; + gap: 10px; +} + diff --git a/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue b/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue index f664b6f1..ee28f1a8 100644 --- a/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue +++ b/src/renderer/components/common/SoundEffectBtn/AudioPanner.vue @@ -1,7 +1,7 @@ @@ -53,9 +53,19 @@ const handleUpdateSpeed = (value) => { diff --git a/src/renderer/components/common/SoundEffectBtn/index.vue b/src/renderer/components/common/SoundEffectBtn/index.vue index 6e3ac88f..fa67040d 100644 --- a/src/renderer/components/common/SoundEffectBtn/index.vue +++ b/src/renderer/components/common/SoundEffectBtn/index.vue @@ -1,22 +1,27 @@ diff --git a/src/renderer/plugins/player.ts b/src/renderer/plugins/player.ts index 0b4bfacd..6e93a610 100644 --- a/src/renderer/plugins/player.ts +++ b/src/renderer/plugins/player.ts @@ -7,21 +7,32 @@ let analyser: AnalyserNode export const freqs = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000] as const type Freqs = (typeof freqs)[number] let biquads: Map<`hz${Freqs}`, BiquadFilterNode> +export const freqsPreset = [ + { name: 'pop', hz31: 6, hz62: 5, hz125: -3, hz250: -2, hz500: 5, hz1000: 4, hz2000: -4, hz4000: -3, hz8000: 6, hz16000: 4 }, + { name: 'dance', hz31: 4, hz62: 3, hz125: -4, hz250: -6, hz500: 0, hz1000: 0, hz2000: 3, hz4000: 4, hz8000: 4, hz16000: 5 }, + { name: 'rock', hz31: 7, hz62: 6, hz125: 2, hz250: 1, hz500: -3, hz1000: -4, hz2000: 2, hz4000: 1, hz8000: 4, hz16000: 5 }, + { name: 'classical', hz31: 6, hz62: 7, hz125: 1, hz250: 2, hz500: -1, hz1000: 1, hz2000: -4, hz4000: -6, hz8000: -7, hz16000: -8 }, + { name: 'vocal', hz31: -5, hz62: -6, hz125: -4, hz250: -3, hz500: 3, hz1000: 4, hz2000: 5, hz4000: 4, hz8000: -3, hz16000: -3 }, + { name: 'slow', hz31: 5, hz62: 4, hz125: 2, hz250: 0, hz500: -2, hz1000: 0, hz2000: 3, hz4000: 6, hz8000: 7, hz16000: 8 }, + { name: 'electronic', hz31: 6, hz62: 5, hz125: 0, hz250: -5, hz500: -4, hz1000: 0, hz2000: 6, hz4000: 8, hz8000: 8, hz16000: 7 }, + { name: 'subwoofer', hz31: 8, hz62: 7, hz125: 5, hz250: 4, hz500: 0, hz1000: 0, hz2000: 0, hz4000: 0, hz8000: 0, hz16000: 0 }, + { name: 'soft', hz31: -5, hz62: -5, hz125: -4, hz250: -4, hz500: 3, hz1000: 2, hz2000: 4, hz4000: 4, hz8000: 0, hz16000: 0 }, +] as const export const convolutions = [ { 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: '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: '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: 'cardiod_35_10_spread', mainGain: 1.8, sendGain: 0.6, source: 'cardiod-35-10-spread.wav' }, + { name: 'tim_omni_35_10_magnetic', mainGain: 1, sendGain: 0.2, 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' }, diff --git a/src/renderer/store/soundEffect.ts b/src/renderer/store/soundEffect.ts new file mode 100644 index 00000000..b807bb27 --- /dev/null +++ b/src/renderer/store/soundEffect.ts @@ -0,0 +1,56 @@ +import { reactive, toRaw } from '@common/utils/vueTools' +import { getUserSoundEffectConvolutionPresetList, getUserSoundEffectEQPresetList, saveUserSoundEffectConvolutionPresetList, saveUserSoundEffectEQPresetList } from '@renderer/utils/ipc' + +let userEqPresetList: LX.SoundEffect.EQPreset[] | null = null + +export const getUserEQPresetList = async() => { + if (userEqPresetList == null) { + userEqPresetList = reactive(await getUserSoundEffectEQPresetList()) + } + return userEqPresetList +} +export const saveUserEQPreset = async(preset: LX.SoundEffect.EQPreset) => { + if (userEqPresetList == null) { + userEqPresetList = reactive(await getUserSoundEffectEQPresetList()) + } + const target = userEqPresetList.find(p => p.id == preset.id) + if (target) Object.assign(target, preset) + else userEqPresetList.push(preset) + saveUserSoundEffectEQPresetList(toRaw(userEqPresetList)) +} +export const removeUserEQPreset = async(id: string) => { + if (userEqPresetList == null) { + userEqPresetList = reactive(await getUserSoundEffectEQPresetList()) + } + const index = userEqPresetList.findIndex(p => p.id == id) + if (index < 0) return + userEqPresetList.splice(index, 1) + saveUserSoundEffectEQPresetList(toRaw(userEqPresetList)) +} + + +let userConvolutionPresetList: LX.SoundEffect.ConvolutionPreset[] | null = null +export const getUserConvolutionPresetList = async() => { + if (userEqPresetList == null) { + userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList()) + } + return userConvolutionPresetList +} +export const saveUserConvolutionPreset = async(preset: LX.SoundEffect.ConvolutionPreset) => { + if (userConvolutionPresetList == null) { + userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList()) + } + const target = userConvolutionPresetList.find(p => p.id == preset.id) + if (target) Object.assign(target, preset) + else userConvolutionPresetList.push(preset) + saveUserSoundEffectConvolutionPresetList(toRaw(userConvolutionPresetList)) +} +export const removeUserConvolutionPreset = async(id: string) => { + if (userConvolutionPresetList == null) { + userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList()) + } + const index = userConvolutionPresetList.findIndex(p => p.id == id) + if (index < 0) return + userConvolutionPresetList.splice(index, 1) + saveUserSoundEffectConvolutionPresetList(toRaw(userConvolutionPresetList)) +} diff --git a/src/renderer/types/common.d.ts b/src/renderer/types/common.d.ts index ae344a52..b80afb4c 100644 --- a/src/renderer/types/common.d.ts +++ b/src/renderer/types/common.d.ts @@ -13,3 +13,4 @@ import '@common/types/desktop_lyric' import '@common/types/ipc_renderer' import '@common/types/config_files' import '@common/types/music_metadata' +import '@common/types/sound_effect' diff --git a/src/renderer/utils/ipc.ts b/src/renderer/utils/ipc.ts index c66e455e..e345838a 100644 --- a/src/renderer/utils/ipc.ts +++ b/src/renderer/utils/ipc.ts @@ -291,6 +291,22 @@ export const getSystemFonts = async() => { }) } +export const getUserSoundEffectEQPresetList = async() => { + return await rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_eq_preset) +} + +export const saveUserSoundEffectEQPresetList = (list: LX.SoundEffect.EQPreset[]) => { + rendererSend(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_eq_preset, list) +} + +export const getUserSoundEffectConvolutionPresetList = async() => { + return await rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_convolution_preset) +} + +export const saveUserSoundEffectConvolutionPresetList = (list: LX.SoundEffect.ConvolutionPreset[]) => { + rendererSend(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_convolution_preset, list) +} + export const allHotKeys = markRaw({ local: [ diff --git a/src/static/medias/filters/spreader25-125ms.wav b/src/static/medias/filters/spreader25-125ms.wav deleted file mode 100644 index 37cc003ac38e441e066aac2413f2fb794112dcd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 356896 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 pW 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