Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


[Solved] Loop MP3 from specific point? (mciSendString)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
Xenocritus
Cheater
Reputation: 0

Joined: 27 Dec 2020
Posts: 25

PostPosted: Thu Feb 11, 2021 3:57 pm    Post subject: [Solved] Loop MP3 from specific point? (mciSendString) Reply with quote

Hi,

I'm using quite simple code to play MP3. However, i wanted to do a common video game loop. So, starting normally and after reaching the end, I want it to loop from certain point. How can I do it?

This is my current code:

Code:

function initializeMP3Player()
  if initializeMP3Player_done then return true end
  if autoAssemble([[loadlibrary(winmm.dll)
alloc(SimpleMp3Player,4096)
registersymbol(SimpleMp3Player)
SimpleMp3Player:
lea rsp,[rsp-28]
lea rsi,[rcx+400]
mov rdx,0
mov r8,0
mov r9,0
call mciSendStringA
mov rcx,rax
mov rdx,rsi
mov r8,400
call mciGetErrorStringA
lea rsp,[rsp+28]
ret]],true)
  then
    initializeMP3Player_done = true
    MP3PlayerCommandMS = createMemoryStream()
    MP3PlayerCommandMS.Size = 2048
    return true
  else
    return false
  end
end

function MP3PlayerSendCommand(command)
  writeStringLocal(MP3PlayerCommandMS.Memory          , command)
  writeBytesLocal (MP3PlayerCommandMS.Memory+#command , 0)
  executeCodeLocal('SimpleMp3Player',MP3PlayerCommandMS.Memory)
  return readStringLocal(MP3PlayerCommandMS.Memory+1024,100)
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 repeat')
end



Last edited by Xenocritus on Sat Feb 13, 2021 3:32 am; edited 1 time in total
Back to top
View user's profile Send private message
Corroder
Grandmaster Cheater Supreme
Reputation: 75

Joined: 10 Apr 2015
Posts: 1668

PostPosted: Thu Feb 11, 2021 9:08 pm    Post subject: This post has 1 review(s) Reply with quote

Here some functions you can use:

Code:
function positionMP3()
 if not initializeMP3Player() then return end
 local a,b=MP3PlayerSendCommand('status MediaFile position')
 return tonumber(b) or 0
end

function lengthMP3()
 if not initializeMP3Player() then return end
 local a,b=MP3PlayerSendCommand('status MediaFile length')
 return tonumber(b) or 0
end

function durationMP3()
 if not initializeMP3Player() then return end
 local a,b=MP3PlayerSendCommand('status MediaFile length')
 return tonumber(b) or 0
end

function playFromSecondMP3(path, secFrom, secTo)
 if not initializeMP3Player() then return end
 secFrom = secFrom * 10
 secTo = secTo * 10
 MP3PlayerSendCommand('close MediaFile')
 MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
 MP3PlayerSendCommand("set MediaFile time format ms")
 MP3PlayerSendCommand('play MediaFile from '..secFrom..' to '..secTo..'  wait')
end


According to your question, example:

Code:
local mysong = 'D:\\example.mp3'
playFromSecondMP3(mysong, 4000, 9000)


The last code will play your song from fourth seconds to ninth seconds and then stop

_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL
Back to top
View user's profile Send private message
Xenocritus
Cheater
Reputation: 0

Joined: 27 Dec 2020
Posts: 25

PostPosted: Fri Feb 12, 2021 1:15 am    Post subject: Reply with quote

But... That is just a "from" "to", isn't it?

What I need is playing the songs normally first time and once it reach the end, it loops from some point. Here and example:

Song duration 1:30.
It has 30 secs of instrumental intro, and the other 1 minute is loopable.
So I want to play the full song and once it reaches the 1:30, just go back to second 30 and loop from here all time.

I've tryied with positionMP3() ir order to set if > x then "play from"... but it always returns 0 when I check it with a print.
Back to top
View user's profile Send private message
Corroder
Grandmaster Cheater Supreme
Reputation: 75

Joined: 10 Apr 2015
Posts: 1668

PostPosted: Fri Feb 12, 2021 4:52 am    Post subject: Reply with quote

All MCI functions were there, use your logic:

example:

Code:
function playOnceAndLoopFromSecondMP3(path, secFrom, secTo)
 if not initializeMP3Player() then return end
 secFrom = secFrom * 10
 secTo = secTo * 10
 MP3PlayerSendCommand('close MediaFile')
 MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
 MP3PlayerSendCommand("set MediaFile time format ms")
 MP3PlayerSendCommand('play MediaFile wait')
 MP3PlayerSendCommand('play MediaFile from '..secFrom..' to '..secTo..'  wait')
end



or

Code:
MP3PlayerSendCommand('play MediaFile wait')  -- play the song completely once
MP3PlayerSendCommand('play MediaFile from '..secFrom,.'  repeat') -- loop from specific position


ref : https://docs.microsoft.com/en-us/windows/win32/multimedia/mci-command-strings

_________________
Stealing Code From Stolen Code...
And Admit It.. Hmmm....Typically LOL
Back to top
View user's profile Send private message
Xenocritus
Cheater
Reputation: 0

Joined: 27 Dec 2020
Posts: 25

PostPosted: Fri Feb 12, 2021 7:18 am    Post subject: Reply with quote

So, problem there seems to be "wait" command.

As long as I've tested, I cannot do anything while "waiting". I would need to be able to stop the song at a "random" moment. As this is for videogames, the song can change at any time, so I have to check where am I.

Thanks again in advance.
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 37

Joined: 16 Feb 2017
Posts: 1516

PostPosted: Fri Feb 12, 2021 2:16 pm    Post subject: Reply with quote

@Corroder is a doyen of this. In the CE Lua and Gui coding, his valuable work is evident.

I've always been interested in this topic and the answer to the question is in the code below;

Code:
function lengthMP3()
  if not initializeMP3Player() then return end

  local a,b=MP3PlayerSendCommand('status MediaFile length')
  return tonumber(b) or 0
end

function positionMP3()
  if not initializeMP3Player() then return end

  local a,b=MP3PlayerSendCommand('status MediaFile position')
  return tonumber(b) or 0
end

function PlayLoop(path, start1, finish1)
start1=tonumber(start1) * 1000
finish1=tonumber(finish1)
 if not initializeMP3Player() then return end
 MP3PlayerSendCommand('close MediaFile')
 MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
 MP3PlayerSendCommand('play MediaFile from '..start1..' to '..finish1..' notify')


I will do 2 types of coding for use, take whatever suits you;
1) Only Start (Will stop when finished)
( I set 1 minute to 60 seconds. so you give 1 for every second.
The start you wanted was from the 30th second to the last 1 minute.
Here is the set run code; )

Code:
snglength = tonumber(lengthMP3())
PlayLoop(path, 30, snglength)


2) Tie it in the loop; ("repeat" command can be used, but the timestamp will be ineffective. So let's connect the loop to a timer)

Code:
if repTimer then repTimer.destroy() repTimer=nil end
repTimer = createTimer()
repTimer.Interval = 100

repTimer.OnTimer = function ()
sglength = tonumber(lengthMP3())
postime = (tonumber(positionMP3())

if postime==sglength then
snglength = tonumber(lengthMP3())
PlayLoop(path, 30, snglength)
end
end
repTimer.Enabled=true

UDF1.CEButton1.OnClick=function()
if repTimer.Enabled==true then
repTimer.Enabled=false
else
repTimer.Enabled=true
end
end


For this matter, respect @mgr.inz.Player and @Corroder also with a +1 each. Wink

Enjoy it. Cool

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Xenocritus
Cheater
Reputation: 0

Joined: 27 Dec 2020
Posts: 25

PostPosted: Fri Feb 12, 2021 3:02 pm    Post subject: Reply with quote

Lol yep, I see all of you in a lot of this. Thanks for helping (is it possible to give a real +1? I see the reputation there, but Im new here)

However, Im not able to do it.
1) Just remember I want to play full song first and start looping at some point when it finished for first time (like in videogames).

2) Code not working for me. For example, I have entered the code in the OP. Then I have include just the lengthMP3() function, but it always returns the "0". Or it returns -1 if I try "or -1" in the return. I have tryed doing it before Play or after it, always 0 returned. Like this, always get 0.
print(lengthMP3())
playMP3(examplePath)
print(lengthMP3())


It would be appreciated if you can share a CT, but tips are also very welcome so I can achieve this Smile
Back to top
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 37

Joined: 16 Feb 2017
Posts: 1516

PostPosted: Fri Feb 12, 2021 5:53 pm    Post subject: Reply with quote

Here is an example.
I haven't formatted for time, you don't seem to need it.
Type a starting number in the "StartPosition" box after the first start. (For example, 30th. This means that it will keep playing again and starts at the 30th second.
If you give an MP3 file path to the Path box, it will play it, otherwise you must give a path to "pth" in the code.

Arrange as you wish.


Code:
if form11 then form11.destroy() form11 = nil end
form11 = createForm()
form11.Position = poDesktopCenter
form11.Width=320
form11.Height=150

local pb1=createProgressBar(form11)
pb1.Width=290 pb1.Height=15 pb1.Left=15 pb1.Top=15
pb1.Position=0

local btn1=createButton(form11)
btn1.Left=15 btn1.Top=45 btn1.caption="Play"

local lbl1=createLabel(form11)
lbl1.AutoSize=false lbl1.Height=16 lbl1.Width=110
lbl1.Left=110 lbl1.Top=50 lbl1.caption="0 / 0" lbl1.Alignment="taCenter"

local edt1=createEdit(form11) --80
edt1.Left=230 edt1.Top=45 edt1.Width=75 edt1.ShowHint=true
edt1.TextHint="StartPosition"

local btn2=createButton(form11)
btn2.Left=15 btn2.Top=80 btn2.caption="Pause"

local btn3=createButton(form11)
btn3.Left=230 btn3.Top=80 btn3.caption="Stop"

local tb1=createTrackBar(form11)
tb1.Left=100 tb1.Top=80 tb1.Width=130 tb1.LineSize=1
tb1.Max=100 tb1.Position=50

local edt2=createEdit(form11) --80
edt2.Left=15 edt2.Top=115 edt2.Width=290 edt2.ShowHint=true
edt2.TextHint=[[MP3 Path Example= C:\myFolder\myMp3File.mp3]]

--############################################################################--
--############################################################################--
function initializeMP3Player()
  if initializeMP3Player_done then return true end

local script64bit=[[loadlibrary(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(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 pauseMP3()
  if not initializeMP3Player() then return end

  if not MP3PlayerPaused then
    MP3PlayerSendCommand('pause MediaFile')
    MP3PlayerPaused=true
  else
    MP3PlayerSendCommand('resume MediaFile')
    MP3PlayerPaused=false
  end
end

function stopMP3()
  if not initializeMP3Player() then return end

  MP3PlayerSendCommand('stop MediaFile')
end

function volumeMP3(vol)
  if not initializeMP3Player() then return end

  MP3PlayerSendCommand('setaudio MediaFile volume to '..vol)
end

function lengthMP3()
  if not initializeMP3Player() then return end

  local a,b=MP3PlayerSendCommand('status MediaFile length')
  return tonumber(b) or 0
end

function positionMP3()
  if not initializeMP3Player() then return end

  local a,b=MP3PlayerSendCommand('status MediaFile position')
  return tonumber(b) or 0
end

function PlayLoop(path, start1, finish1)
start1=tonumber(start1) * 1000
finish1=tonumber(finish1)
 if not initializeMP3Player() then return end
 MP3PlayerSendCommand('close MediaFile')
 MP3PlayerSendCommand( string.format('open "%s" type mpegvideo alias MediaFile',path) )
 MP3PlayerSendCommand('play MediaFile from '..start1..' to '..finish1..' notify')
end
--############################################################################--
--############################################################################--

local pth=[[C:\Users\??\Music\??.mp3]] --MP3 file path?
local path1
if progressTimer then progressTimer.destroy() progressTimer=nil end

progressTimer = createTimer(nil,false)
progressTimer.Interval = 100

function startMp3()
if edt2.Text=="" then
path1=pth
else
path1=edt2.Text
end
end


progressTimer.OnTimer = function ()
--  UDF1.CEProgressbar1.Position = positionMP3()
--  UDF1.CEProgressbar1.Max = lengthMP3()
pb1.Max = lengthMP3()
pb1.Position = positionMP3()
sglength = tonumber(lengthMP3())
 postime = tonumber(positionMP3())
lbl1.caption=tonumber(postime).." / "..tonumber(sglength)
if edt1.Text~="" then
if postime==sglength then
startMp3()
sngposition=tonumber(edt1.Text)
snglength = tonumber(lengthMP3())
PlayLoop(path1, sngposition, snglength)
progressTimer.Enabled=true
end
end
end

btn1.OnClick=function()
startMp3()
playMP3(path1)
progressTimer.Enabled=true
end

btn2.OnClick=function()
pauseMP3()
end

btn3.OnClick=function()
stopMP3()
progressTimer.Enabled=false
lbl1.caption="0 / 0"
pb1.Position = 0
end

--function CETrackBar1Change(sender)
tb1.OnChange=function()
 -- volumeMP3(UDF1.CETrackBar1.Position*10)
 volumeMP3(tb1.Position*10)
end

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Xenocritus
Cheater
Reputation: 0

Joined: 27 Dec 2020
Posts: 25

PostPosted: Sat Feb 13, 2021 3:31 am    Post subject: Reply with quote

Thanks!! Yep, that is exactly what I was looking for! It works perfectly!

Now I have to check also my code to check what was wrong... as all your indications were quite clear.

If I see something interesting to share with others with my same problem as me I will post here. Anyway, I will set this as Solved. Thanks again, I'm really enjoying CE, but just starting...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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 can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites