|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Sat Mar 03, 2018 2:17 am Post subject: Implementing Lua Scripting To Creating CE Mp3 Player |
|
|
In connection to these topics :
http://forum.cheatengine.org/viewtopic.php?t=584021
http://forum.cheatengine.org/viewtopic.php?t=606901
which already answerd by the 'play MP3 sound in CE function' creator : mgr.inz.Player
as also knew as ones most respected Cheat Engine / CEF users.
So, the fisrt thing I want to do is to thank so much to mgr.inz.Player and also Dark Byte as
Cheat Engine creator.
Form those topics above, I have created a 'Simple MP3 Player' by followed 'play MP3 sound in CE function'
including added and modified some functions and use pure Cheat Engine Lua scripting.
My goal by doing this project is for learning purpose and more than it is to prove and show if CE not only use
for memory hacking, it also can use for other purpose, specially for Lua scripting.
The project as below :
--================================================================--
-- Project name : CRDR-MP3Player-Ver.4.0
-- Creator : Corroder a.k.a VCLBro
-- Created date : 28-02-2018
-- Scripting Language : Lua 5.3 compatible Lua 5.1, Lua 5.2
-- Scripting IDE : CE 6.7 Lua Engine
-- Special thanks to : mgr.inz.Player, Dark Byte, CEF Members
-- Purpose : Learning, show CE not only use for hack
--================================================================--
-- Note :
-- 1.All Form GUI on this project made use Lua Scripting
-- 2.GUI Images and Icons, has store as stream files
-- 3.Some notes has added inside script code for references
-- 4.NOT FOR COMMERCIAL USE
--================================================================--
What inside this project ? :
A. Work with Lua Table
1.Function to save and load lua table to a file
Code: | do
local function exportstring( s )
s = string.format( "%q",s )
s = string.gsub( s,"\\\n","\\n" )
s = string.gsub( s,"\r","\\r" )
s = string.gsub( s,string.char(26),"\"..string.char(26)..\"" )
return s
end
function table.save( tbl,filename )
local charS,charE = " ","\n"
local file,err
if not filename then
file = { write = function( self,newstr ) self.str = self.str..newstr end, str = "" }
charS,charE = "",""
elseif filename == true or filename == 1 then
charS,charE,file = "","",io.tmpfile()
else
file,err = io.open( filename, "w" )
if err then return _,err end
end
local tables,lookup = { tbl },{ [tbl] = 1 }
file:write( "return {"..charE )
for idx,t in ipairs( tables ) do
if filename and filename ~= true and filename ~= 1 then
file:write( "-- Table: {"..idx.."}"..charE )
end
file:write( "{"..charE )
local thandled = {}
for i,v in ipairs( t ) do
thandled[i] = true
if type( v ) ~= "userdata" then
if type( v ) == "table" then
if not lookup[v] then
table.insert( tables, v )
lookup[v] = #tables
end
file:write( charS.."{"..lookup[v].."},"..charE )
elseif type( v ) == "function" then
file:write( charS.."loadstring("..exportstring(string.dump( v )).."),"..charE )
else
local value = ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
file:write( charS..value..","..charE )
end
end
end
for i,v in pairs( t ) do
if (not thandled[i]) and type( v ) ~= "userdata" then
if type( i ) == "table" then
if not lookup[i] then
table.insert( tables,i )
lookup[i] = #tables
end
file:write( charS.."[{"..lookup[i].."}]=" )
else
local index = ( type( i ) == "string" and "["..exportstring( i ).."]" ) or string.format( "[%d]",i )
file:write( charS..index.."=" )
end
if type( v ) == "table" then
if not lookup[v] then
table.insert( tables,v )
lookup[v] = #tables
end
file:write( "{"..lookup[v].."},"..charE )
elseif type( v ) == "function" then
file:write( "loadstring("..exportstring(string.dump( v )).."),"..charE )
else
local value = ( type( v ) == "string" and exportstring( v ) ) or tostring( v )
file:write( value..","..charE )
end
end
end
file:write( "},"..charE )
end
file:write( "}" )
if not filename then
return file.str.."--|"
elseif filename == true or filename == 1 then
file:seek ( "set" )
return file:read( "*a" ).."--|"
else
file:close()
return 1
end
end
function table.load( sfile )
local tables, err, _
if string.sub( sfile,-3,-1 ) == "--|" then
tables,err = loadstring( sfile )
else
tables,err = loadfile( sfile )
end
if err then return _,err
end
tables = tables()
for idx = 1,#tables do
local tolinkv,tolinki = {},{}
for i,v in pairs( tables[idx] ) do
if type( v ) == "table" and tables[v[1]] then
table.insert( tolinkv,{ i,tables[v[1]] } )
end
if type( i ) == "table" and tables[i[1]] then
table.insert( tolinki,{ i,tables[i[1]] } )
end
end
for _,v in ipairs( tolinkv ) do
tables[idx][v[1]] = v[2]
end
for _,v in ipairs( tolinki ) do
tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil
end
end
return tables[1]
end
end |
2.Get a table length
Code: | function tablelength(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end |
3.Clearing / empty a table
Code: | function clearTable(tb)
for i, v in pairs(tb) do
tb[i] = nil
end
end
-- [table] = {} also use to clear a table, but in fact with this function but in fact the table still store a nil value
|
B. Function to convert seconds to time format HH:MM:SS or 00:00:00
Code: | function SecondsToClock(seconds)
local seconds = tonumber(seconds)
if seconds <= 0 then
return "00:00:00";
else
hours = string.format("%02.f", math.floor(seconds/3600));
mins = string.format("%02.f", math.floor(seconds/60 - (hours*60)));
secs = string.format("%02.f", math.floor(seconds - hours*3600 - mins *60));
return hours..":"..mins..":"..secs
end
end |
C. Other functions or and logics to create custom GUI, etc
What about this CRDR-MP3Player-Ver.4.0 player ?
1. Common mp3 player functions : Play, Stop, Resume, Pause
2. Added : Mute / Un-mute volume
3. Added : Filtering mp3 files when browsing on PC/Extrnal storage
4. Added : Created mp3 songs playlist which editable and save
5. Added : Automatic load last saved songs playlist
6. Added : Option to play single song or play songs shuffle
7. Added : Song info when playing -> Title, Path, Duration, File Size
8. Added : Song play elapsed time with custom progress bar
9. Added : MP3 player skin theme selector
10. Added : Loud speaker control -> Balance, Left/Right Volume, Bass/Treble Volume
On future update (plan) :
- Added 'media seek = fast forward / back'
- Added 'sound visualization'
Download Source Code (CT file) :
https://mega.nz/#!Xw8FVZAB!cUOGWWogAvdB5Xxv8XzgSCZcfJDiYVV7Y6JZUPHqQSs
NOTE 2 :
This project is not perfect, it's possible contain some error (I hope not). Anyhow, if you think you can create better then goes on,
then use this project as your motivation.
Even I can do same thing like this using other programming language such as VB, C++ and others but
the main purpose from this project is to prove and show if CE is not iuse for hacking only.
It's more than it if on right hands...
EDIT : 18/03/2018
CRDR-MP3 Player V.5
https://youtu.be/pwBsDrFQEic
Download source code / CT file CRDR-MP3-Player-V5:
https://mega.nz/#!jtkjmQ7Z!_DC-ri1R_CEMQN-mkTBgzH1celOtwBf97GMrxZ_Nc8c
Also if you want play MIDI file format, add this :
Code: | function playMID(path)
if not initializeMP3Player() then return end
MP3PlayerSendCommand('close midifile')
MP3PlayerSendCommand(string.format('open "%s" type sequencer alias midifile',path))
MP3PlayerSendCommand('play midifile')
end |
To play WMA file format (example with openDialog to locate wma file)
Code: | function playWMA() -- work
if not initializeMP3Player() then return end
load_dialog = createOpenDialog(self)
load_dialog.InitalDir = os.getenv('%USERPROFILE%')
-- load_dialog.Filter = 'MP3 files|*.mp3|*'
load_dialog.Filter = 'Audio files|*.mp3;*.mid;*.wav;*.wma|Mp3 files (*.mp3)|*.MP3|Mid files (*.mid)|*.MID|Wav files (*.wav)|*.WAV|Wma files (*.wma)|*.WMA|*'
load_dialog.execute()
local file = load_dialog.FileName
s_file = string.sub(file, -4)
print(s_file)
if s_file == '.wma' then
MP3PlayerSendCommand('play '..file)
else
print('not WMA file...')
end
end |
Cheers...
Corroder
_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL
Last edited by Corroder on Thu Mar 15, 2018 4:01 am; edited 3 times in total |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sat Mar 03, 2018 8:03 am Post subject: |
|
|
Nice work, original work. Congratulations.
still foreign to me a lot of coding.
I guess I'm used to 'UDF1' coding.
'CreateTable' is an encoding I still can not figure out.
It also opens and the sliding menu is great. You do it for the 2nd time.
I noticed something;
Still does not install multiple song list.
Songs single, single loading.
A file, 'Ctrl + A' or list selection can not be made.
Without changing any letters in this file,
By registering as a trainer,
Do we have a chance to open it in another trainer?
The writer's identity and identity are present,
there is no need to make a new table.
It will be more accurate to present original articles and works to members.
'AddFile' with this file, we will apply your previous coding?
Thanks @Corroder.
_________________
|
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sat May 16, 2020 9:37 am Post subject: |
|
|
@Corroder, MP3 code, if it returns to the beginning,
(In simple MP3 player mode)
Can we add and use "findTableFile" to the table without "TrainerOrigin"?
MP3 files will be in the table (add file).
How should we code to execute from table memory?
This code did not work;
Code: | local mp3File9 = findTableFile('music111.mp3').Stream
playMP3(mp3File9) |
Is there a solution?
_________________
|
|
Back to top |
|
|
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Sat May 16, 2020 11:51 am Post subject: |
|
|
I think not to use mciSendString, but use memoryStream.
Example:
Code: | --- Music MP3 Function
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]} )
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
knownStreams[streamID]=stream
else
local riffmp3 = convertMP3ToRIFFMP3(stream)
knownStreams[streamID]=riffmp3
end
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
--- Test play
file = findTableFile('test.mp3')
playSound(file)
--- Stop play
file = findTableFile('silence.mp3') -- find somewhere a file with name silence.mp3 which produce no sound
playSound(file) |
_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sat May 16, 2020 2:42 pm Post subject: |
|
|
Corroder wrote: | I think not to use mciSendString, but use memoryStream.
|
Yes, I have the same code at the moment and "playSound" does not run 2 mp3s at the same time.
I guess it is not possible to play 5 different sounds at the same time.
I tried with playSound and playMP3, it didn't.
I think I should copy 5 "winmm.dll".
_________________
|
|
Back to top |
|
|
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Sat May 16, 2020 3:46 pm Post subject: |
|
|
Aylin wrote: | I think I should copy 5 "winmm.dll". |
No you dont. If the songs are on local disk (not table file), use mciSendString like this :
Code: | function playMulti(song1, song2,...)
if not initializeMP3Player() then return end
local fileName
fileName = song1
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias FirstSound", 0, 0, 0)
MP3PlayerSendCommand("play FirstSound", 0, 0, 0)
fileName = song2
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias SecondSound", 0, 0, 0)
MP3PlayerSendCommand("play SecondSound",0, 0, 0)
-- add here until filename = song5
end
s1 = "E:\\test1.mp3"
s2 = "E:\\test2.mp3"
playMulti(s1,s2) |
EDIT:
If your song2 are on table file then you need to find them and save as local files on temporary dir. and then play the sounds from there.
And when then delete them all when the trainer closes. As usual, we did.
_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sun May 17, 2020 6:49 am Post subject: |
|
|
Sorry, it didn't work.
Also, 5 different songs are not in one command.
So there are 17 songs (or audio files) and they are all on separate buttons.
For example; I am trying to add effects to a music.
Commands should not be together, they should work on separate buttons.
Whenever I run it, it turns off the current sound and works. This shouldn't happen.
When I disable this code, the sound does not play at all.
Code: | --MP3PlayerSendCommand('close MediaFile')
MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
MP3PlayerSendCommand('play MediaFile') |
I think the following example is enough to understand;
Like a Karoeke,
When playing music, add sound to it.
_________________
|
|
Back to top |
|
|
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Sun May 17, 2020 7:07 am Post subject: |
|
|
For me this is work. I note you said 'play sound at the same time'.
Code: | function initializeMP3Player()
if initializeMP3Player_done then return true end
local script64bit=[[loadlibrary(C:\Windows\System32\winmm.dll)
alloc(SimpleMp3Player,4096)
registersymbol(SimpleMp3Player)
SimpleMp3Player:
lea rsp,[rsp-28]
lea rsi,[rcx+400]
lea rdx,[rcx+300]
mov r8d,80
xor r9d,r9d
call mciSendStringW
mov rcx,rax
mov rdx,rsi
mov r8,200
call mciGetErrorStringW
lea rsp,[rsp+28]
ret]]
local script32bit=[[loadlibrary(C:\Windows\System32\winmm.dll)
alloc(SimpleMp3Player,4096)
registersymbol(SimpleMp3Player)
SimpleMp3Player:
push ebp
mov ebp,esp
push ebx
mov ebx,[ebp+8]
sub esp,10
mov [esp],ebx
lea ebx,[ebx+300]
mov [esp+4],ebx
mov [esp+8],80
mov [esp+c],0
call mciSendStringW
mov ebx,[ebp+8]
lea ebx,[ebx+400]
sub esp,0c
mov [esp],eax
mov [esp+0x4],ebx
mov [esp+0x8],200
call mciGetErrorStringW
pop ebx
leave
ret 004]]
if cheatEngineIs64Bit() then script = script64bit else script = script32bit end
if autoAssemble(script,true)
then
initializeMP3Player_done = true
MP3PlayerCommandMS = createMemoryStream()
MP3PlayerCommandMS.Size = 2048
return true
else
return false
end
end
function MP3PlayerSendCommand(command)
writeStringLocal(MP3PlayerCommandMS.Memory, command, true)
writeBytesLocal (MP3PlayerCommandMS.Memory+2*#command, 0, 0)
executeCodeLocal('SimpleMp3Player',MP3PlayerCommandMS.Memory)
return readStringLocal(MP3PlayerCommandMS.Memory+1024,512,true),
readStringLocal(MP3PlayerCommandMS.Memory+768,128,true)
end
function playMP3(path)
if not initializeMP3Player() then return end
MP3PlayerSendCommand('close MediaFile')
MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
MP3PlayerSendCommand('play MediaFile')
end
function playMulti(song1, song2,...)
if not initializeMP3Player() then return end
local fileName
fileName = song1
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias FirstSound", 0, 0, 0)
MP3PlayerSendCommand("play FirstSound", 0, 0, 0)
fileName = song2
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias SecondSound", 0, 0, 0)
MP3PlayerSendCommand("play SecondSound",0, 0, 0)
end
----- Test, change song files with your own
s1 = "E:\\test1.mp3"
s2 = "E:\\test2.mp3"
playMulti(s1,s2)
|
And here my old file with song list on a combobox.
Code: | getLuaEngine().cbShowOnPrint.Checked=false
getLuaEngine().hide()
function loadTableCode(n)
local t = findTableFile(n)
if t ~= nil then
local s = t.Stream
local c = readStringLocal(s.Memory,s.Size)
return c ~= nil and loadstring(c) -- return a function
end
end
--
local f = loadTableCode('plsound.lua')
print(type(f))
if type(f) == 'function' then f() else print('not loaded') end
local Mform = createForm()
Mform.Width = 280
Mform.Height = 180
Mform.Position = 'poScreenCenter'
Mform.BorderStyle = 'bsNone'
Mform.Color = '0x00595959'
Mform.Name = 'Mform'
local TitlePanel = createPanel(Mform)
TitlePanel.Left = 1
TitlePanel.Top = 1
TitlePanel.Height = 30
TitlePanel.Width = Mform.Width - 1
TitlePanel.Caption = ' '
TitlePanel.BavelInner = 'bvRaised'
TitlePanel.BavelOuter = 'bvRaised'
TitlePanel.Color = '0x00DFF7FF' --'0x00868686'
TitlePanel.Name = 'TitlePanel'
TitlePanel.OnMouseDown = function() Mform.DragNow() end
local TitleLabel = createLabel(TitlePanel)
TitleLabel.Left = 10
TitleLabel.Top = 7
TitleLabel.Font.Name = 'Armalite Rifle'
TitleLabel.Font.Style = 'fsBold'
TitleLabel.Font.Size = '12'
TitleLabel.Font.Color = '0x00595959'
TitleLabel.Caption = 'MP3 Song - Player'
TitleLabel.Name = 'TitleLabel'
local SongBox = createComboBox(Mform)
SongBox.Top = TitlePanel.Top + TitlePanel.Height + 10
SongBox.Left = 10
SongBox.Width = Mform.Width - SongBox.Left - 10
SongBox.Color = '0x00DFF7FF'
SongBox.Style = 'csDropDown'
SongBox.Text = 'Pick a song..'
SongBox.Name = 'SongBox'
MsLabel = createLabel(Mform)
MsLabel.Left = 10
MsLabel.Top = SongBox.Top + SongBox.Height + 10
MsLabel.Font.Name = 'Arial'
MsLabel.Font.Size = 9
MsLabel.AutoSize = false
MsLabel.Width = Mform.Width - MsLabel.Left - 10
MsLabel.Height = 50
MsLabel.WordWrap = true
MsLabel.Font.Style = 'fsBold'
MsLabel.Font.Color = '0x00DFF7FF'
MsLabel.Caption = 'Idle..'
MsLabel.Name = 'MsLabel'
items = combobox_getItems(SongBox)
strings_add(items, "Pick a song..")
SongBox.ItemIndex = 0
songTable = {
{songName = "Adele - Hello", songPath = "E:\\Lagu Film Dll\\Filmograph\\Lagu MP3\\Barat\\Adele - Hello.mp3"},
{songName = "Billy Joel - An Innocent Man", songPath = "E:\\Lagu Film Dll\\Filmograph\\Lagu MP3\\Barat\\Billy Joel - An Innocent Man.mp3"},
{songName = "Celine Dion - My Heart Will Go On", songPath = "E:\\Lagu Film Dll\\Filmograph\\Lagu MP3\\Barat\\Celine Dion - My Heart Will Go On.mp3"},
{songName = "Chris Brown - Dont Wake Up", songPath = "E:\\Lagu Film Dll\\Filmograph\\Lagu MP3\\Barat\\Chris Brown - Dont Wake Up.mp3"},
{songName = 'Kate Bush - Wuthering Height', songPath = "E:\\Lagu Film Dll\\Filmograph\\Lagu MP3\\Barat\\Kate Bush - Wuthering Height.mp3"}
}
for i,v in ipairs(songTable) do
strings_add(items, v.songName)
end
function cbboxOnChange()
index = getProperty(SongBox, "ItemIndex")
index = songTable[index]
if index == nil then
MsLabel.Caption = 'Idle..'
else
local ss = createMemoryStream()
path = index.songPath
ss.loadFromFile(path)
playSound(ss)
ss.Destroy()
MsLabel.Caption = "Playing - "..index.songName
end
end
SongBox.onChange = cbboxOnChange
bStop = createButton(Mform)
bStop.Left = 10
bStop.Top = MsLabel.Top + MsLabel.Height + 20
bStop.Height = 25
bStop.Width = 70
bStop.Caption = 'Stop'
bStop.Cursor = -21
bStop.Name = 'bStop'
bExplo = createButton(Mform)
bExplo.Left = bStop.Left + bStop.Width + 25
bExplo.Top = MsLabel.Top + MsLabel.Height + 20
bExplo.Height = 25
bExplo.Width = 70
bExplo.Caption = 'Find MP3'
bExplo.Cursor = -21
bExplo.Name = 'bExplo'
bExit = createButton(Mform)
bExit.Width = 70
bExit.Left = Mform.Width - bExit.Width - 10
bExit.Top = MsLabel.Top + MsLabel.Height + 20
bExit.Height = 25
bExit.Caption = 'Exit'
bExit.Cursor = -21
bExit.Name = 'bExit'
function songStop()
local check = MsLabel.Caption
if check == 'Idle..' then
showMessage("No song playing...")
end
playSound('silence.mp3')
MsLabel.Caption = "Idle.."
SongBox.ItemIndex = 0
SongBox.Text = 'Pick a song..'
end
function GetFileName(f)
local str = f
local temp = ""
local result = ""
for i = str:len(), 1, -1 do
if str:sub(i,i) ~= "/" then
temp = temp..str:sub(i,i)
else
break
end
end
for j = temp:len(), 1, -1 do
result = result..temp:sub(j,j)
end
return result
end
function exploMP3()
load_dialog = createOpenDialog(self)
load_dialog.InitalDir = os.getenv('%USERPROFILE%')
load_dialog.execute()
file = load_dialog.FileName
a = GetFileName(file)
if a == nil then
return a
else
MsLabel.Caption = a
local ss = createMemoryStream()
ss.loadFromFile(file)
playSound(ss)
ss.destroy()
end
end
function exit()
closeCE()
return caFree
end
bExit.onClick = exit
bStop.onClick = songStop
bExplo.onClick = exploMP3
Mform.Show() |
plsound.lua -- add to table file
Code: | --- Music MP3 Function
-- 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 |
You can change plSound.lua with mciSendstring module.
Beside, I am not really understand what exactly you want to do.
_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sun May 17, 2020 8:07 am Post subject: |
|
|
Note; I will try the samples you provided, thanks.
What I am trying to say (Project);
Code: | function CEButton1_Click(sender) --Background music
playMP3(path1)
end
function CEButton2_Click(sender) --The lady who sings the song
playMP3(path2)
end
function CEButton3_Click(sender) --The man who sings the song
playMP3(path3)
end
function CEButton4_Click(sender) --optional, add or remove (Stop) a wind.
if playMP3(path4) then
stopMP3(path4)
else
playMP3(path4)
end
end |
When more than one button is active at the same time, it should play the songs.
He should play with him, without closing the current playing song.
_________________
|
|
Back to top |
|
|
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Sun May 17, 2020 8:35 am Post subject: |
|
|
Aylin wrote: | Note; I will try the samples you provided, thanks.
What I am trying to say (Project);
When more than one button is active at the same time, it should play the songs.
He should play with him, without closing the current playing song. |
Try the script I provided before:
Code: | function playMulti(song1, song2,...)
if not initializeMP3Player() then return end
local fileName
fileName = song1
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias FirstSound", 0, 0, 0)
MP3PlayerSendCommand("play FirstSound", 0, 0, 0)
fileName = song2
MP3PlayerSendCommand("open "..fileName.." type mpegvideo alias SecondSound", 0, 0, 0)
MP3PlayerSendCommand("play SecondSound",0, 0, 0)
end
----- Test, change song files with your own
s1 = "E:\\test1.mp3"
s2 = "E:\\test2.mp3"
playMulti(s1,s2) |
_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sun May 17, 2020 1:32 pm Post subject: |
|
|
And the final;
Run multiple mp3 files simultaneously;
Code: | function MP3PlayerSendCommand(command)
writeStringLocal(MP3PlayerCommandMS.Memory, command, true)
writeBytesLocal (MP3PlayerCommandMS.Memory+2*#command, 0, 0)
executeCodeLocal('SimpleMp3Player',MP3PlayerCommandMS.Memory)
return readStringLocal(MP3PlayerCommandMS.Memory+1024,512,true),
readStringLocal(MP3PlayerCommandMS.Memory+768,128,true)
end
function playMP3(path)
if not initializeMP3Player() then return end
MP3PlayerSendCommand('resume MediaFile')--('close MediaFile')
MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
MP3PlayerSendCommand('play MediaFile')
end
---------------------------------------------------
function MP3PlayerSendCommand1(command)
writeStringLocal(MP3PlayerCommandMS.Memory, command, true)
writeBytesLocal (MP3PlayerCommandMS.Memory+2*#command, 0, 0)
executeCodeLocal('SimpleMp3Player',MP3PlayerCommandMS.Memory)
return readStringLocal(MP3PlayerCommandMS.Memory+1024,512,true),
readStringLocal(MP3PlayerCommandMS.Memory+768,128,true)
end
function playMP31(path1)
if not initializeMP3Player() then return end
MP3PlayerSendCommand1('resume MediaFile1')--('close MediaFile1')
MP3PlayerSendCommand1( string.format('open "%s" type mpegvideo alias MediaFile1',path1) )
MP3PlayerSendCommand1('play MediaFile1')
end
function stopMP3()
if not initializeMP3Player() then return end
MP3PlayerSendCommand('close MediaFile')
MP3PlayerSendCommand1('close MediaFile1')
end |
Thanks @Corroder
Now it is left to add "findTableFile" to this code.
There are 17 audio files. I will duplicate this code up to 17.
_________________
|
|
Back to top |
|
|
Corroder Grandmaster Cheater Supreme Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1432
|
Posted: Sun May 17, 2020 2:04 pm Post subject: |
|
|
This is what I was trying to say.
Thanks for developing.
50% of my project was this code.
Now I need to get an idea for the remaining code. I have to open a forum question.
_________________
|
|
Back to top |
|
|
Xenocritus Cheater Reputation: 0
Joined: 27 Dec 2020 Posts: 25
|
Posted: Fri Jan 29, 2021 8:55 am Post subject: |
|
|
Hi,
Im using MP3 player to replace some game's music and it works. However I have an issue.
Working Workflow:
- Start CE
- initializeMP3Player()
- Attach the game
- Run the program logic to replace
- It works
Not Working (seems like in a loop once Lua executed)
- Start CE
- Attach the game
- initializeMP3Player()
- Just the CE not responding
Is somehow the memory allocation entering in clonflict? I just want to attach the game and run all the Lua Scripts.
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|