mgr.inz.Player I post too much Reputation: 218 Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Thu Sep 10, 2015 2:04 pm Post subject: playing MP3 files with CE [extended playSound function] |
|
|
Default playSound function:
Code: | playSound(stream, waittilldone OPTIONAL): Plays the given memorystream containing a .WAV formatted memory object. If waittilldone is true the script will stop executing till the sound has stopped
playSound(tablefile, waittilldone OPTIONAL) : Takes the memorystream from the tablefile and plays it. |
Usage:
playSound( findTableFile('mysoundtest.wav').Stream )
playSound( findTableFile('mysoundtest.wav') )
Extended playSound function:
Code: | playSound(tablefile, waittilldone OPTIONAL): -//- (and mp3)
playSound(stream, waittilldone OPTIONAL): -//- (and mp3)
playSound('mysoundtest.wav', waittilldone OPTIONAL): Takes the memorystream from the tablefile from the name and plays it
playSound('mysoundtest.mp3', waittilldone OPTIONAL): also mp3 |
Usage:
playSound( findTableFile('mysoundtest.wav') )
playSound( findTableFile('mysoundtest.mp3') )
playSound( findTableFile('mysoundtest.wav').Stream )
playSound( findTableFile('mysoundtest.mp3').Stream )
playSound( 'mysoundtest.wav' )
playSound( 'mysoundtest.mp3' )
The script:
Code: | -- fix CE6.4 MemoryStream write, and add other useful methods
if oldcreateMemoryStream==nil then oldcreateMemoryStream = createMemoryStream end
function createMemoryStream()
local obj = oldcreateMemoryStream()
local oldwrite=obj.write
obj.write = function (t,n) -- override default write
local count=0
for _,v in ipairs(t) do
if count==n then break end
oldwrite({v},1)
count=count+1
end
end
obj.writeDword = function (v) obj.write(dwordToByteTable(v)) end
obj.writeWord = function (v) obj.write(wordToByteTable(v)) end
return obj
end
--convertMP3ToRIFFMP3(stream)
function convertMP3ToRIFFMP3(stream)
local riffmp3 = createMemoryStream()
local header = {
0x46464952,0x00000000,0x45564157,0x20746D66,0x0000001E,0x00020055,
0x0000AC44,0x00000000,0x00000001,0x0001000C,0x00000002,0x00010001,
0x61660571,0x00047463,0x2FF80000,0x61640014
} -- default is 44100Hz , Stereo
local rateTable = {[0] = {11025,12000,8000}, --mpeg ver2.5
[2] = {22050,24000,16000}, --mpeg ver2
[3] = {44100,48000,32000}} --mpeg ver1
local bitrateTable = {[1]={32,64,96,128,160,192,224,256,288,320,352,384,416,448},
[2]={32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384},
[3]={32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320},
[4]={32,48,56, 64, 80, 96,112,128,144,160,176,192,224,256},
[5]={ 8,16,24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}}
for i,v in ipairs(header) do riffmp3.writeDword(v) end
riffmp3.writeWord(0x6174)
riffmp3.writeDword(stream.Size)
stream.Position = 0
riffmp3.copyFrom(stream,stream.Size)
riffmp3.Position = 0x4; riffmp3.writeDword(stream.Size+0x24)
stream.Position = 0
local chunk = stream.read( math.min(65536,stream.Size) )
local DWORD = byteTableToDword( {chunk[4],chunk[3],chunk[2],chunk[1]} )
--[[ looking for MPEG Audio frame header
bits 31 through 21 must all be set; Frame sync
bit 18 and bit 17, at least one set; Layer
bits 15 through 12, at least one clear; bitrate index
bits 11 through 10, at least one clear; sample rate index
also use above to find a header
bit 20 and 19; MPEG audio id
bit 7 and 6; channel mode
]]
local i=0x1
while (i<=#chunk-4) do
if (bAnd(DWORD,0xFFE00000)==0xFFE00000) and
(bAnd(DWORD,0x60000)~=0) and
(bAnd(DWORD,0xF000)~=0xF000) and
(bAnd(DWORD,0xC00)~=0xC00)
then
--probably MPEG Audio Layer I/II/III frame header
local channels =(bAnd(bShr(DWORD, 6), 3) == 3) and 1 or 2
local layer = 3 - bAnd(bShr(DWORD,17), 3) + 1;
local mpegaudioid = bAnd(bShr(DWORD,19), 3)
local rateindex = bAnd(bShr(DWORD,10), 3)
local bitrateindex= bAnd(bShr(DWORD,12),15)
local samplerate = rateTable[mpegaudioid][rateindex+1]
local row
if mpegaudioid==3 then row=layer -- mpeg ver1
elseif layer==1 then row=4 -- mpeg ver2 and ver2.5, Layer 1
else row=5 -- mpeg ver2 and ver2.5, Layer 2 and 3
end
local bitrate = bitrateTable[row][bitrateindex]
riffmp3.Position = 0x16;
riffmp3.writeWord(channels)
riffmp3.writeDword(samplerate)
riffmp3.writeDword(math.floor(bitrate*1000/8))
break
end
if (bAnd(DWORD,0xFFFFFF00)==0x49443300) and
(bAnd(DWORD,0xFF)<0xFF)
--ID3 tag found
then
local size = bOr(bShl(chunk[i+6],7),chunk[i+7])
size = bOr(bShl(size,7),chunk[i+8])
size = bOr(bShl(size,7),chunk[i+9])
i=i+size
end
DWORD = bOr( bShl(DWORD,8) , chunk[i+4] ) % 0x100000000
i=i+1
end
chunk = nil
riffmp3.Position = riffmp3.Size - 1
return riffmp3
end
function sound_prepare(track)
if track==nil then return nil end
if knownStreams==nil then knownStreams = {} end
local stream,streamID
-- set stream variable
if type(track)=='string' then
if knownStreams[track]~=nil then return track end -- check name as StreamID
if findTableFile(track) then stream=findTableFile(track).Stream else return nil end
elseif track.ClassName=='TMemoryStream' then
stream=track else stream=track.Stream
end
streamID=userDataToInteger(stream)
if knownStreams[streamID]~=nil then return streamID end
stream.Position = 0
if table.concat(stream.read(4),'-')=='82-73-70-70' then
-- RIFF format (wave file, etc.)
knownStreams[streamID]=stream
else
-- probably mp3 file, converting
-- convertMP3ToRIFFMP3(stream)
local riffmp3 = convertMP3ToRIFFMP3(stream)
knownStreams[streamID]=riffmp3
end
-- if string, use it as streamID too
if type(track)=='string' then knownStreams[track]=knownStreams[streamID] end
return streamID
end
if oldplaySound==nil then oldplaySound=playSound end
function playSound(track, ...)
local ID=sound_prepare(track)
if ID then oldplaySound(knownStreams[ID], ...)
else print('track not found') end
end |
Append above script to any lua file inside autorun folder, or create new lua file inside autorun, or append it to "cheat table lua script"
From now on, you can play any mp3 file with playSound function. _________________ Dark Souls II Item Swap and Item List
My Borderlands2 tables
Recent CheatEngine builds
|
|