From c16db0a4e10fcdedb41c78842d8db3e2e8c90305 Mon Sep 17 00:00:00 2001 From: MrZ_26 <1046101471@qq.com> Date: Sat, 20 Apr 2024 15:05:36 +0800 Subject: [PATCH] =?UTF-8?q?fmod=E6=A8=A1=E5=9D=97=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E9=87=8D=E5=90=AF=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4fmod=E6=A8=A1=E5=9D=97=E7=9A=84music.stop?= =?UTF-8?q?=E7=9A=84=E8=87=AA=E5=AE=9A=E4=B9=89=E6=B7=A1=E5=87=BA=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=8A=9F=E8=83=BD=EF=BC=88=E6=94=B9=E7=94=A8fmod?= =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E5=86=85=E8=87=AA=E5=B7=B1=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=EF=BC=89=20=E8=AE=BE=E7=BD=AE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0fmod=E9=AB=98=E7=BA=A7=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=B0=83=E6=95=B4=20=E5=88=A0=E6=B5=8B=E8=AF=95=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=20=E6=A1=86=E6=9E=B6=E8=B7=9F=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zenitha | 2 +- assets/fmod20221/init.lua | 49 ++++---- assets/game/mode/mino/exterior/sprint_40.lua | 6 - assets/gamefunc.lua | 6 +- assets/language/lang_en.lua | 4 + assets/language/lang_zh.lua | 4 + assets/progress.lua | 14 +-- assets/scene/app_calc.lua | 2 +- assets/scene/error.lua | 2 +- assets/scene/musicroom.lua | 2 +- assets/scene/setting_out.lua | 8 ++ assets/settings.lua | 6 +- main.lua | 125 ++++++++++--------- 13 files changed, 125 insertions(+), 105 deletions(-) diff --git a/Zenitha b/Zenitha index 1c3d3695..5d2adc39 160000 --- a/Zenitha +++ b/Zenitha @@ -1 +1 @@ -Subproject commit 1c3d3695b6065fe362fb26c92b0c0bd1e78d2102 +Subproject commit 5d2adc392654b0f2ad606d8d8705cf4297dcd1b2 diff --git a/assets/fmod20221/init.lua b/assets/fmod20221/init.lua index 51657504..48e4a7fb 100644 --- a/assets/fmod20221/init.lua +++ b/assets/fmod20221/init.lua @@ -25,23 +25,32 @@ require("errors") -------------------------------------------------------------- -M.studio=M.newStudio() -M.core=M.studio:getCoreSystem() - -local studio,core=M.studio,M.core +local studio ---@type FMOD.Studio.System +local core ---@type FMOD.Core.System ---@param args {maxChannel:number, DSPBufferLength:number, DSPBufferCount:number, studioFlag:FMOD.Const, coreFlag:FMOD.Const} function M.init(args) + local firstTime=true + if M.studio then + M.studio:release() + firstTime=false + end + M.studio=M.newStudio() + M.core=M.studio:getCoreSystem() + studio,core=M.studio,M.core core:setDSPBufferSize(args.DSPBufferLength or 128,args.DSPBufferCount or 4) studio:initialize(args.maxChannel,args.studioFlag,args.coreFlag) - TASK.new(function() - while true do - studio:update() - coroutine.yield() - end - end) + if firstTime then + TASK.new(function() + while true do + studio:update() + coroutine.yield() + end + end) + end end + ---@param bankPath string ---@param flag? FMOD.Const function M.loadBank(bankPath,flag) @@ -151,26 +160,22 @@ function M.music.play(name,args) return event end ----@param time? number -function M.music.stop(time) +---@param instant? boolean only `true` take effect +function M.music.stop(instant) if not playing then return end - time=time or 0.626 - local e=playing.event - playing=nil - if time<=0 then + local e=playing.event ---@type FMOD.Studio.EventInstance + if instant then e:stop(M.FMOD_STUDIO_STOP_IMMEDIATE) else TASK.new(function() - local startTime=love.timer.getTime() - while true do + e:setParameterByName("fade",0,true) + repeat coroutine.yield() - local v=1-(love.timer.getTime()-startTime)/time - if v<=0 then break end - e:setParameterByName("fade",v,true) - end + until e:getParameterByName("fade")==0 e:stop(M.FMOD_STUDIO_STOP_IMMEDIATE) end) end + playing=nil end ---@param name string diff --git a/assets/game/mode/mino/exterior/sprint_40.lua b/assets/game/mode/mino/exterior/sprint_40.lua index 0360d3b8..803d3bec 100644 --- a/assets/game/mode/mino/exterior/sprint_40.lua +++ b/assets/game/mode/mino/exterior/sprint_40.lua @@ -6,7 +6,6 @@ return { playBgm('race') end, settings={mino={ - skin='touhou.mino_reimu', -- seqType=mechLib.mino.sequence.distWeight.fake7bag, seqType='bag7_sprint', -- clearRule='line_float', @@ -17,11 +16,6 @@ return { P.modeData.curKeyCount=0 -- mechLib.mino.squeeze.turnOn_auto(P,4) -- P:setAction('func1',function(P) mechLib.mino.stack.turnOn_auto(P,true,60e3) end) - P.modeData.character={ - image=IMG.touhou.reimu, - effect=NULL, - } - P:setAction('func1',mechLib.common.characterAnim.start) end, beforePress=function(P) P.modeData.curKeyCount=P.modeData.curKeyCount+1 diff --git a/assets/gamefunc.lua b/assets/gamefunc.lua index 471ac2f2..c8a100e9 100644 --- a/assets/gamefunc.lua +++ b/assets/gamefunc.lua @@ -6,7 +6,7 @@ function sureCheck(event) end end -local _bgmPlaying ---@type string +local _bgmPlaying ---@type string? ---@param full? boolean ---@param noProgress? boolean function playBgm(name,full,noProgress) @@ -22,6 +22,10 @@ end function getBgm() return _bgmPlaying end +function stopBgm(instant) + FMOD.music.stop(instant) + _bgmPlaying=nil +end function playSample(...) local l={...} local inst diff --git a/assets/language/lang_en.lua b/assets/language/lang_en.lua index 1822c03c..0f227391 100644 --- a/assets/language/lang_en.lua +++ b/assets/language/lang_en.lua @@ -100,6 +100,10 @@ return { setting_updRate="Update rate", setting_drawRate="Draw rate", setting_msaa="MSAA", + setting_fmod_maxChannel="Max Channel", + setting_fmod_DSPBufferCount="DSPBufferCount", + setting_fmod_DSPBufferLength="DSPBufferLength", + setting_apply="Apply", lang_note="Chinese is the original game language.\nAll translations are contributed by volunteers and it may not be 100% accurate\nThere are some terms not translated directly, please check Zictionary for more information.", diff --git a/assets/language/lang_zh.lua b/assets/language/lang_zh.lua index 9194318e..c117d2da 100644 --- a/assets/language/lang_zh.lua +++ b/assets/language/lang_zh.lua @@ -100,6 +100,10 @@ return { setting_updRate="更新比率", setting_drawRate="绘制比率", setting_msaa="抗锯齿", + setting_fmod_maxChannel="最大音频数", + setting_fmod_DSPBufferCount="DSP缓冲区数量", + setting_fmod_DSPBufferLength="DSP缓冲区长度", + setting_apply="应用", lang_note="中文是本游戏的原始语言\n翻译由志愿者贡献,不保证100%准确\n部分术语可能没有翻译,请查阅词典获取更多信息", diff --git a/assets/progress.lua b/assets/progress.lua index e49d1d7b..d75c2999 100644 --- a/assets/progress.lua +++ b/assets/progress.lua @@ -154,8 +154,8 @@ function PROGRESS.applyCoolWaitTemplate() end function PROGRESS.setInteriorBG() BG.set('none') end function PROGRESS.setExteriorBG() BG.set(prgs.main==3 and 'space' or 'galaxy') end -function PROGRESS.playInteriorBGM() playBgm('blank',prgs.main==1 and 'simp' or 'full') end -function PROGRESS.playExteriorBGM() playBgm('vacuum',prgs.main==3 and 'simp' or 'full') end +function PROGRESS.playInteriorBGM() playBgm('blank',prgs.main~=1) end +function PROGRESS.playExteriorBGM() playBgm('vacuum',prgs.main~=3) end function PROGRESS.setEnv(env) if env=='interior' then PROGRESS.setInteriorBG() @@ -204,9 +204,7 @@ function PROGRESS.transcendTo(n) WAIT{ coverAlpha=0, noDefaultDraw=true, - init=function() - FMOD.music.stop() - end, + init=stopBgm, update=function(_,t) if WAIT.state=='wait' and t>=2.6 then PROGRESS.setMain(2) @@ -240,8 +238,8 @@ function PROGRESS.transcendTo(n) FMOD.music.seek(FMOD.music.tell()-.1) sumT=sumT-.1 end - elseif t<2 and FMOD.music.getPlaying() then - FMOD.music.stop(0) + elseif t<2 and getBgm() then + stopBgm(true) end if WAIT.state=='wait' and t>=2.6 then PROGRESS.setMain(3) @@ -290,7 +288,7 @@ function PROGRESS.quit() end, } elseif prgs.main<=4 then - FMOD.music.stop() + stopBgm() local t=1 WAIT.setDefaultDraw(NULL) WAIT{ diff --git a/assets/scene/app_calc.lua b/assets/scene/app_calc.lua index c0a75b5c..e0b157ad 100644 --- a/assets/scene/app_calc.lua +++ b/assets/scene/app_calc.lua @@ -17,7 +17,7 @@ end function scene.enter() BG.set('none') - FMOD.music.stop() + stopBgm() reg,val,sym=false,"0",false end diff --git a/assets/scene/error.lua b/assets/scene/error.lua index cded74b9..52b7d9ca 100644 --- a/assets/scene/error.lua +++ b/assets/scene/error.lua @@ -14,7 +14,7 @@ local texts={ local scene={} function scene.enter() - FMOD.music.stop() + FMOD.music.stop(true) time=0 err=Zenitha.getErr('#') or { scene="NULL", diff --git a/assets/scene/musicroom.lua b/assets/scene/musicroom.lua index dd3ca6e3..63b4efb3 100644 --- a/assets/scene/musicroom.lua +++ b/assets/scene/musicroom.lua @@ -147,7 +147,7 @@ function scene.keyDown(key,isRep) elseif not isRep then if key=='space' then if FMOD.music.getPlaying() then - FMOD.music.stop(.26) + stopBgm() else playBgm(selected,fullband,noProgress) end diff --git a/assets/scene/setting_out.lua b/assets/scene/setting_out.lua index d76d1f40..ffa433ae 100644 --- a/assets/scene/setting_out.lua +++ b/assets/scene/setting_out.lua @@ -74,6 +74,14 @@ scene.widgetList={ {name='2',type='slider_fill',pos={0,0},x=340, y=380,w=650, fontSize=40,text=LANG'setting_sfx', widthLimit=260, disp=TABLE.func_getVal(SETTINGS.system,'sfxVol'), code=TABLE.func_setVal(SETTINGS.system,'sfxVol')}, {name='2',type='slider_fill',pos={0,0},x=340, y=460,w=650, fontSize=40,text=LANG'setting_vib', widthLimit=260, disp=TABLE.func_getVal(SETTINGS.system,'vibVol'), code=TABLE.func_setVal(SETTINGS.system,'vibVol')}, {name='2',type='switch', pos={0,0},x=390, y=540,h=45, fontSize=40,text=LANG'setting_autoMute',widthLimit=550,labelPos='right', disp=TABLE.func_getVal(SETTINGS.system,'autoMute'), code=TABLE.func_revVal(SETTINGS.system,'autoMute')}, + {name='2',type='slider', pos={0,0},x=340, y=660,w=260, fontSize=30,text=LANG'setting_fmod_maxChannel', widthLimit=260, axis={4,8,1}, valueShow=function(S) return 2^S.disp() end, disp=function() return MATH.roundLog(SETTINGS.system.fmod_maxChannel,2) end, code=function(v) SETTINGS.system.fmod_maxChannel=2^v end}, + {name='2',type='slider', pos={0,0},x=340, y=730,w=390, fontSize=30,text=LANG'setting_fmod_DSPBufferCount', widthLimit=260, axis={2,8,1}, disp=TABLE.func_getVal(SETTINGS.system,'fmod_DSPBufferCount'), code=TABLE.func_setVal(SETTINGS.system,'fmod_DSPBufferCount')}, + {name='2',type='slider', pos={0,0},x=340, y=800,w=650, fontSize=30,text=LANG'setting_fmod_DSPBufferLength', widthLimit=260, axis={3,16,1},valueShow=function(S) return 2^S.disp() end, disp=function() return MATH.roundLog(SETTINGS.system.fmod_DSPBufferLength,2) end, code=function(v) SETTINGS.system.fmod_DSPBufferLength=2^v end}, + {name='2',type='button', pos={0,0},x=400, y=870,w=140, h=60,fontSize=30,text=LANG'setting_apply', code=function() + FMODLoadFunc() + debug.setupvalue(getBgm,1,nil) + PROGRESS.playExteriorBGM() + end}, -- Video {name='3',type='slider_fill',pos={0,0},x=340, y=220,w=500,h=30,text=LANG'setting_hitWavePower',widthLimit=260,axis={0,1}, disp=TABLE.func_getVal(SETTINGS.system,'hitWavePower'), code=TABLE.func_setVal(SETTINGS.system,'hitWavePower')}, diff --git a/assets/settings.lua b/assets/settings.lua index 9903976b..a8aeecce 100644 --- a/assets/settings.lua +++ b/assets/settings.lua @@ -7,9 +7,9 @@ local settings={ sfxVol=1, vocVol=0, vibVol=1, - fmod_maxChannel=64, - fmod_DSPBufferLength=128, - fmod_DSPBufferCount=4, + fmod_maxChannel=6, + fmod_DSPBufferCount=2, + fmod_DSPBufferLength=6, -- Video hitWavePower=.6, diff --git a/main.lua b/main.lua index a8deb50a..ca626d54 100644 --- a/main.lua +++ b/main.lua @@ -209,6 +209,70 @@ LANG.add{ LANG.setDefault('en') DEBUG.checkLoadTime("Load Zenitha resources") -------------------------------------------------------------- +function FMODLoadFunc() -- will be called again for restarting when applying advanced options + FMOD.init{ + maxChannel=math.min(SETTINGS.system.fmod_maxChannel,256), + DSPBufferCount=math.min(SETTINGS.system.fmod_DSPBufferCount,16), + DSPBufferLength=math.min(SETTINGS.system.fmod_DSPBufferLength,65536), + studioFlag=FMOD.FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, + coreFlag=FMOD.FMOD_INIT_NORMAL, + } + if not FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Master.strings.bank") then + MSG.new('warn',"Strings bank file load failed") + end + FMOD.registerMusic((function() + if not love.filesystem.getInfo("soundbank/Master.bank") then + MSG.new('warn',"Music bank not found") + return {} + end + local bankMusic=FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Master.bank") + if not bankMusic then + MSG.new('warn',"Music bank file load failed") + return {} + end + local L={} + local l,c=bankMusic:getEventList(bankMusic:getEventCount()) + for i=1,c do + local path=l[i-1]:getPath() + if path then + local name=path:match("/([^/]+)$"):lower() + L[name]=path + end + end + return L + end)()) + FMOD.registerEffect((function() + if not love.filesystem.getInfo("soundbank/Effect.bank") then + MSG.new('warn',"Effect bank not found") + return {} + end + local bankEffect=FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Effect.bank") + if not bankEffect then + MSG.new('warn',"Effect bank file load failed") + return {} + end + local L={} + local l,c=bankEffect:getEventList(bankEffect:getEventCount()) + for i=1,c do + local path=l[i-1]:getPath() + if path then + local name=path:match("/([^/]+)$"):lower() + L[name]=path + end + end + return L + end)()) +end +FMODLoadFunc() +-- Hijack the original SFX module, use FMOD instead +SFX[('play')]=function(name,vol,pos,tune) + FMOD.effect.play(name,{ + volume=vol, + tune=tune, + }) +end +DEBUG.checkLoadTime("Load FMod and Bank") +-------------------------------------------------------------- -- Load saving data TABLE.coverR(FILE.load('conf/settings','-json -canskip') or {},SETTINGS) for k,v in next,SETTINGS._system do @@ -360,65 +424,4 @@ SCN.addSwap('fastFadeHeader',{ }) DEBUG.checkLoadTime("Load shaders/BGs/SCNs/skins") -------------------------------------------------------------- -FMOD.init{ - maxChannel=SETTINGS.system.fmod_maxChannel, - DSPBufferLength=SETTINGS.system.fmod_DSPBufferLength, - DSPBufferCount=SETTINGS.system.fmod_DSPBufferCount, - studioFlag=FMOD.FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE, - coreFlag=FMOD.FMOD_INIT_NORMAL, -} -if not FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Master.strings.bank") then - MSG.new('warn',"Strings bank file load failed") -end -FMOD.registerMusic((function() - if not love.filesystem.getInfo("soundbank/Master.bank") then - MSG.new('warn',"Music bank not found") - return {} - end - local bankMusic=FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Master.bank") - if not bankMusic then - MSG.new('warn',"Music bank file load failed") - return {} - end - local L={} - local l,c=bankMusic:getEventList(bankMusic:getEventCount()) - for i=1,c do - local path=l[i-1]:getPath() - if path then - local name=path:match("/([^/]+)$"):lower() - L[name]=path - end - end - return L -end)()) -FMOD.registerEffect((function() - if not love.filesystem.getInfo("soundbank/Effect.bank") then - MSG.new('warn',"Effect bank not found") - return {} - end - local bankEffect=FMOD.loadBank(love.filesystem.getSaveDirectory().."/soundbank/Effect.bank") - if not bankEffect then - MSG.new('warn',"Effect bank file load failed") - return {} - end - local L={} - local l,c=bankEffect:getEventList(bankEffect:getEventCount()) - for i=1,c do - local path=l[i-1]:getPath() - if path then - local name=path:match("/([^/]+)$"):lower() - L[name]=path - end - end - return L -end)()) --- Hijack the original SFX module, use FMOD instead -SFX[('play')]=function(name,vol,pos,tune) - FMOD.effect.play(name,{ - volume=vol, - tune=tune, - }) -end -DEBUG.checkLoadTime("Load FMod and Bank") --------------------------------------------------------------- DEBUG.logLoadTime()