183 lines
4.9 KiB
Lua
183 lines
4.9 KiB
Lua
local lastLoaded={}
|
|
local maxLoadedCount=3
|
|
local nameList={}
|
|
local SourceObjList={}
|
|
local volume=1
|
|
|
|
local BGM={
|
|
default=false,
|
|
onChange=NULL,
|
|
--nowPlay=[str:playing ID]
|
|
--playing=[src:playing SRC]
|
|
--lastPlayed=[str:lastPlayed ID]
|
|
}
|
|
|
|
function BGM.getList()return nameList end
|
|
function BGM.getCount()return #nameList end
|
|
local function _addFile(name,path)
|
|
if not SourceObjList[name]then
|
|
table.insert(nameList,name)
|
|
SourceObjList[name]={path=path,source=false}
|
|
end
|
|
end
|
|
function BGM.load(name,path)
|
|
if type(name)=='table'then
|
|
for k,v in next,name do
|
|
_addFile(k,v)
|
|
end
|
|
else
|
|
_addFile(name,path)
|
|
end
|
|
table.sort(nameList)
|
|
LOG(BGM.getCount().." BGM files added")
|
|
end
|
|
|
|
local function _tryReleaseSources()
|
|
local n=#lastLoaded
|
|
while #lastLoaded>maxLoadedCount do
|
|
local name=lastLoaded[n]
|
|
if SourceObjList[name].source:isPlaying()then
|
|
n=n-1
|
|
if n<=0 then return end
|
|
else
|
|
SourceObjList[name].source=SourceObjList[name].source:release()and nil
|
|
table.remove(lastLoaded,n)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
function BGM.setDefault(bgm)
|
|
BGM.default=bgm
|
|
end
|
|
function BGM.setMaxSources(count)
|
|
maxLoadedCount=count
|
|
_tryReleaseSources()
|
|
end
|
|
function BGM.setChange(func)
|
|
BGM.onChange=func
|
|
end
|
|
function BGM.setVol(v)
|
|
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
|
volume=v
|
|
if BGM.playing then
|
|
if volume>0 then
|
|
BGM.playing:setVolume(volume)
|
|
BGM.playing:play()
|
|
elseif BGM.nowPlay then
|
|
BGM.playing:pause()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function task_fadeOut(src)
|
|
while true do
|
|
coroutine.yield()
|
|
if tostring(src):find('NULL')then return end
|
|
local v=src:getVolume()-.025*volume
|
|
src:setVolume(v>0 and v or 0)
|
|
if v<=0 then
|
|
src:stop()
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
local function task_fadeIn(src)
|
|
while true do
|
|
coroutine.yield()
|
|
local v=volume
|
|
v=math.min(v,src:getVolume()+.025*v)
|
|
src:setVolume(v)
|
|
if v>=volume then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
local function check_curFadeOut(task,code,src)
|
|
return task.code==code and task.args[1]==src
|
|
end
|
|
local function _tryLoad(name)
|
|
if SourceObjList[name]then
|
|
if SourceObjList[name].source then
|
|
return true
|
|
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
|
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
|
|
SourceObjList[name].source:setVolume(0)
|
|
table.insert(lastLoaded,1,name)
|
|
_tryReleaseSources()
|
|
return true
|
|
else
|
|
LOG("No BGM: "..SourceObjList[name],5)
|
|
end
|
|
elseif name then
|
|
LOG("No BGM: "..name,5)
|
|
end
|
|
end
|
|
function BGM.play(name,args)
|
|
name=name or BGM.default
|
|
args=args or""
|
|
if not _tryLoad(name)or args:sArg('-preLoad')then return end
|
|
if volume==0 then
|
|
BGM.nowPlay=name
|
|
BGM.playing=SourceObjList[name].source
|
|
return true
|
|
end
|
|
if name and SourceObjList[name].source then
|
|
if BGM.nowPlay~=name then
|
|
if BGM.nowPlay then
|
|
if not args:sArg('-sdout')then
|
|
TASK.new(task_fadeOut,BGM.playing)
|
|
else
|
|
BGM.playing:pause()
|
|
end
|
|
end
|
|
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
|
|
TASK.removeTask_code(task_fadeIn)
|
|
|
|
BGM.nowPlay=name
|
|
BGM.playing=SourceObjList[name].source
|
|
if not args:sArg('-sdin')then
|
|
BGM.playing:setVolume(0)
|
|
TASK.new(task_fadeIn,BGM.playing)
|
|
else
|
|
BGM.playing:setVolume(volume)
|
|
BGM.playing:play()
|
|
end
|
|
SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
|
|
BGM.lastPlayed=BGM.nowPlay
|
|
BGM.playing:play()
|
|
BGM.onChange(name)
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
function BGM.seek(t)
|
|
if BGM.playing then
|
|
BGM.playing:seek(t)
|
|
end
|
|
end
|
|
function BGM.isPlaying()
|
|
return BGM.playing and BGM.playing:isPlaying()
|
|
end
|
|
function BGM.continue()
|
|
if BGM.lastPlayed then
|
|
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
|
|
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
|
|
TASK.removeTask_code(task_fadeIn)
|
|
TASK.new(task_fadeIn,BGM.playing)
|
|
BGM.playing:play()
|
|
end
|
|
end
|
|
function BGM.stop(args)
|
|
args=args or""
|
|
TASK.removeTask_code(task_fadeIn)
|
|
if not args:sArg('-s')then
|
|
if BGM.nowPlay then
|
|
TASK.new(task_fadeOut,BGM.playing)
|
|
end
|
|
elseif BGM.playing then
|
|
BGM.playing:pause()
|
|
end
|
|
BGM.nowPlay,BGM.playing=nil
|
|
end
|
|
return BGM
|