mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
171 lines
4.6 KiB
Ruby
171 lines
4.6 KiB
Ruby
#####################################
|
|
# Needed because RGSS doesn't call at_exit procs on exit
|
|
# Exit is not called when game is reset (using F12)
|
|
$AtExitProcs = [] if !$AtExitProcs
|
|
|
|
def exit(code = 0)
|
|
$AtExitProcs.each do |p|
|
|
p.call
|
|
end
|
|
raise SystemExit.new(code)
|
|
end
|
|
|
|
def at_exit(&block)
|
|
$AtExitProcs.push(Proc.new(&block))
|
|
end
|
|
|
|
#===============================================================================
|
|
# Methods that determine the duration of an audio file.
|
|
#===============================================================================
|
|
def getOggPage(file)
|
|
fgetdw = proc { |f|
|
|
(f.eof? ? 0 : (f.read(4).unpack("V")[0] || 0))
|
|
}
|
|
dw = fgetdw.call(file)
|
|
return nil if dw != 0x5367674F
|
|
header = file.read(22)
|
|
bodysize = 0
|
|
hdrbodysize = (file.read(1)[0].ord rescue 0)
|
|
hdrbodysize.times do
|
|
bodysize += (file.read(1)[0].ord rescue 0)
|
|
end
|
|
ret = [header, file.pos, bodysize, file.pos + bodysize]
|
|
return ret
|
|
end
|
|
|
|
# internal function
|
|
def oggfiletime(file)
|
|
fgetdw = proc { |f|
|
|
(f.eof? ? 0 : (f.read(4).unpack("V")[0] || 0))
|
|
}
|
|
pages = []
|
|
page = nil
|
|
loop do
|
|
page = getOggPage(file)
|
|
break if !page
|
|
pages.push(page)
|
|
file.pos = page[3]
|
|
end
|
|
return -1 if pages.length == 0
|
|
curserial = nil
|
|
i = -1
|
|
pcmlengths = []
|
|
rates = []
|
|
pages.each do |pg|
|
|
header = pg[0]
|
|
serial = header[10, 4].unpack("V")
|
|
frame = header[2, 8].unpack("C*")
|
|
frameno = frame[7]
|
|
frameno = (frameno << 8) | frame[6]
|
|
frameno = (frameno << 8) | frame[5]
|
|
frameno = (frameno << 8) | frame[4]
|
|
frameno = (frameno << 8) | frame[3]
|
|
frameno = (frameno << 8) | frame[2]
|
|
frameno = (frameno << 8) | frame[1]
|
|
frameno = (frameno << 8) | frame[0]
|
|
if serial != curserial
|
|
curserial = serial
|
|
file.pos = pg[1]
|
|
packtype = (file.read(1)[0].ord rescue 0)
|
|
string = file.read(6)
|
|
return -1 if string != "vorbis"
|
|
return -1 if packtype != 1
|
|
i += 1
|
|
version = fgetdw.call(file)
|
|
return -1 if version != 0
|
|
rates[i] = fgetdw.call(file)
|
|
end
|
|
pcmlengths[i] = frameno
|
|
end
|
|
ret = 0.0
|
|
pcmlengths.each_with_index { |length, j| ret += length.to_f / rates[j] }
|
|
return ret * 256.0
|
|
end
|
|
|
|
# Gets the length of an audio file in seconds. Supports WAV, MP3, and OGG files.
|
|
def getPlayTime(filename)
|
|
if safeExists?(filename)
|
|
return [getPlayTime2(filename), 0].max
|
|
elsif safeExists?(filename + ".wav")
|
|
return [getPlayTime2(filename + ".wav"), 0].max
|
|
elsif safeExists?(filename + ".mp3")
|
|
return [getPlayTime2(filename + ".mp3"), 0].max
|
|
elsif safeExists?(filename + ".ogg")
|
|
return [getPlayTime2(filename + ".ogg"), 0].max
|
|
end
|
|
return 0
|
|
end
|
|
|
|
def getPlayTime2(filename)
|
|
return -1 if !safeExists?(filename)
|
|
time = -1
|
|
fgetdw = proc { |file|
|
|
(file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0))
|
|
}
|
|
fgetw = proc { |file|
|
|
(file.eof? ? 0 : (file.read(2).unpack("v")[0] || 0))
|
|
}
|
|
File.open(filename, "rb") do |file|
|
|
file.pos = 0
|
|
fdw = fgetdw.call(file)
|
|
case fdw
|
|
when 0x46464952 # "RIFF"
|
|
filesize = fgetdw.call(file)
|
|
wave = fgetdw.call(file)
|
|
return -1 if wave != 0x45564157 # "WAVE"
|
|
fmt = fgetdw.call(file)
|
|
return -1 if fmt != 0x20746d66 # "fmt "
|
|
fgetdw.call(file) # fmtsize
|
|
fgetw.call(file) # format
|
|
fgetw.call(file) # channels
|
|
fgetdw.call(file) # rate
|
|
bytessec = fgetdw.call(file)
|
|
return -1 if bytessec == 0
|
|
fgetw.call(file) # bytessample
|
|
fgetw.call(file) # bitssample
|
|
data = fgetdw.call(file)
|
|
return -1 if data != 0x61746164 # "data"
|
|
datasize = fgetdw.call(file)
|
|
time = datasize.to_f / bytessec
|
|
return time
|
|
when 0x5367674F # "OggS"
|
|
file.pos = 0
|
|
time = oggfiletime(file)
|
|
return time
|
|
end
|
|
file.pos = 0
|
|
# Find the length of an MP3 file
|
|
loop do
|
|
rstr = ""
|
|
ateof = false
|
|
until file.eof?
|
|
if (file.read(1)[0] rescue 0) == 0xFF
|
|
begin
|
|
rstr = file.read(3)
|
|
rescue
|
|
ateof = true
|
|
end
|
|
break
|
|
end
|
|
end
|
|
break if ateof || !rstr || rstr.length != 3
|
|
if rstr[0] == 0xFB
|
|
t = rstr[1] >> 4
|
|
next if [0, 15].include?(t)
|
|
freqs = [44_100, 22_050, 11_025, 48_000]
|
|
bitrates = [32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320]
|
|
bitrate = bitrates[t]
|
|
t = (rstr[1] >> 2) & 3
|
|
freq = freqs[t]
|
|
t = (rstr[1] >> 1) & 1
|
|
filesize = FileTest.size(filename)
|
|
frameLength = ((144_000 * bitrate) / freq) + t
|
|
numFrames = filesize / (frameLength + 4)
|
|
time = (numFrames * 1152.0 / freq)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
return time
|
|
end
|