Send in time and variable instances

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
trevix
Posts: 958
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Send in time and variable instances

Post by trevix » Thu Feb 27, 2020 11:52 am

Hi all.
I am trying to build an algorithm for handling sounds in my project, but I am having difficulties conceptualising the sequence.
These are my requirements:
- sound playing should be some sort of "last in, last out", in a queue
- every sound should play to its end, without replacing the one currently playing and without being cut off
- sound firing could implying more then 1 sound in a row, to be played in the same input order
- the user should be able freely do other actions, without interrupting the playing sound and eventually starting other sounds to be put in the queue

In order to do this, I got together something like this (simplified from my real code):

Code: Select all

local sSoundIsPlaying = ""
On SoundPlay tSoundName
  --get path to the sound(s) and put it(them) after tSouldList
  -----
  --tSoundList is now 1 or more lines, each with a (different) sound path
  Send "SoundPlayLater tSoundList" to me in 0 seconds
end SoundPlay

on SoundPlayLater pSoundList
   wait until not sSoundIsPlaying 
   put true into sSoundIsPlaying
   put pSoundList into tNewSoundList
   repeat until tNewSoundList is empty
         put line 1 of tNewSoundList into tPath
         play tPath
         wait until the sound is "done" with messages
        delete line 1 of tNewSoundList
   end repeat
   put false into sSoundIsPlaying
end SoundPlayLater
The code seems to work on OSX but I am not sure if this is the correct way to do it.
For Android I will have to use "mobilePlaySoundOnChannel" and "soundFinishedOnChannel", but I guess it will be more or less the same.
What I am having trouble to understand is if the command receiving a "send", handles each variable as a different instance of it or not.
Thanks
Trevix
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Send in time and variable instances

Post by Klaus » Thu Feb 27, 2020 6:58 pm

Buonasera Trevix,

Code: Select all

... if the command receiving a "send", handles each variable as a different instance of it or not.
sorry, no idea what you mean here? No capisce!? :D


Best

Klaus

trevix
Posts: 958
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Send in time and variable instances

Post by trevix » Thu Feb 27, 2020 7:29 pm

I have hard time on grabbing this:

Code: Select all

on mouseUp pButtonNumber
     send "DoAction A" to me in 0 seconds
     send "DoAction B" to me in 0 seconds
     send "DoAction C" to me in 0 seconds
     send "DoAction D" to me in 0 seconds
end mouseUp

on DoAction pValue
     put pValue into tValue
     wait 1 seconds 
     put tValue & space after msg
end DoAction
msg retuns "A B C D" after 4 seconds

Code: Select all

on mouseUp pButtonNumber
     send "DoAction A" to me in 0 seconds
     send "DoAction B" to me in 0 seconds
     send "DoAction C" to me in 0 seconds
     send "DoAction D" to me in 0 seconds
end mouseUp

on DoAction pValue
     put pValue into tValue
     wait 1 seconds with messages --note the change
     put tValue & space after msg
end DoAction
msg retuns "D C B A" after 1 second.
So, I assume this last answers to my question: tValue assumes different context for each send. Like if I was sending to 4 different processes.
Beside the etheric meaning of this, I am trying to understand how to use the "soundFinishedOnChannel" for playing subsequent sounds on mobile (that don't overlap each other).
This does not seem to work very well (simplified version):

Code: Select all

local sSoundIsDone
on PlaySound
     ...
     repeat until tSoundList is empty
        put line 1 of tSoundList into tPath
        put false into sSoundIsDone
        mobilePlaySoundOnChannel tPath, "Ch1", "now"
        wait until sSoundIsDone --with messages or without messages?
        delete line 1 of tSoundList
     end loop
end PlaySound
on soundFinishedOnChannel pChannel, pSound
     put true into sSoundIsDone
end soundFinishedOnChannel
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1206
Joined: Thu Apr 11, 2013 11:27 am

Re: Send in time and variable instances

Post by LCMark » Thu Feb 27, 2020 7:48 pm

@trevix The arguments you specify to send/call in the message string are evaluated when 'send' is executed. Internally, the engine creates a record which contains the name of the message and the sequence of evaluated arguments (e.g. if you do send "DoAction tVar1" to me in 0 seconds, then the record will contain "DoAction" as the message, and the *value* of tVar1 as the first argument).

The reason your two loops show a different order is because of the 'with messages'.

In the first case, (no with messages) the engine will pause the handler for 1 second, and not dispatch any pending messages; so each DoAction handler completes fully before the next one is dispatched.

In the second case, (with messages) the engine will pause the handler for 1 second but *will* dispatch any pending messages (and events) during that second. So what happens is:

Code: Select all

  DoAction -- first queued message "DoAction A"
    wait 1 second with messages
      DoAction -- second queued message "DoAction B"
          wait 1 second with messages
          DoAction -- second queued message "DoAction C"
              wait 1 second with messages
              DoAction -- second queued message "DoAction D"
                  wait 1 second with messages -- no more messages
                  put "D" after msg
              put "C" after msg
          put "B" after msg
      put "A" after msg
In terms of the mobile side of things - what 'doesn't work very well'?

Note: The mobile sound commands allow to queue a 'next' sound - which prepares it for playback as soon as the current one finishes (might be worth a look).

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Send in time and variable instances

Post by Klaus » Thu Feb 27, 2020 7:50 pm

Hi Trevix,

OK, this:

Code: Select all

on mouseUp pButtonNumber
     send "DoAction A" to me in 0 seconds
     send "DoAction B" to me in 0 seconds
     send "DoAction C" to me in 0 seconds
     send "DoAction D" to me in 0 seconds
end mouseUp
is not a great example of SEND, since this also reads like:

Code: Select all

on mouseUp
    DoAction "A"
    DoAction "B"
    DoAction "C"
    DoAction "D"
end mouseUp
SEND makes sense with a "real" delay. And I cannot explain the difference WITH and WITOUT messages, sorry.

WAIT UNTIL is never a good idea!
You should check if the sound is still playing every maybe 500 millsecs and start the next sound if not, like this:

Code: Select all

local tSoundList

## Fill tSoundList here...
## ...

on PlaySound
   put line 1 of tSoundList into tPath
   delete line 1 of tSoundList
   mobilePlaySoundOnChannel tPath, "Ch1", "now"
   send "check4NextSound" to me in 500 millisecs
end PlaySound

command check4NextSound
   
   ## All sounds have been played:
   if tSoundList = EMPTY then
      exit to top
   end if
   
   ## No sound playing = last sound has finished
   if mobileSoundChannelStatus("Ch1") <> "playing" then
      put line 1 of tSoundList into tPath
      delete line 1 of tSoundList
      mobilePlaySoundOnChannel tPath, "Ch1", "now"
   end if
   send "check4NextSound" to me in 500 millisecs
end check4NextSound
Out of my head, I do not own a cellphone of tablet, but that should do the trick. :-)
You may need to adjust the TIME to send in to fit your needs.


Best

Klaus

trevix
Posts: 958
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Send in time and variable instances

Post by trevix » Fri Feb 28, 2020 10:29 am

is not a great example of SEND
Off course. it was just an example to make myself more clear.

#Klaus. Thanks for your example.
I did not use this approach because I needed to absolutely remove any pause in between subsequent sounds and because it was going to add complexity, but I will give it a try, since it could be the only way.
In my solution (a score keeper), at the change of the score I already have 3 events firing with "send to" (in order not to lock the user UI):
- the match timer (every seconds)
- flashing of the score (win a game)
- sound play

In your way I have to add another "send to" inside the sound play and I feel uncomfortable of all these "loose" commands firing.
Just to explain better: since TextToSpeech in Android and iOS is not available (but recently Simon created an external), my "Say the score loud" approach was to play sound files in a row (like this: "3" & "games to" & "1")

#Mark Thanks for the explanation. Very clear.
The "end of play" sound approach on desktop and mobile (let us divide the two: "Play" or "mobilePlaySoundOnChannel") are different enough for me (trying to do a double platform code) that mixing the two give me headache.
While it is very clear the desktop approach of "wait until sound is done", I don't understand why this doen't seem to work on mobile:

Code: Select all

on PlayTheSound
   ...
   wait until tSoundEnded
   ...
On soundFinishedOnChannel
   put true into tSoundEnded
   ...
   
As for the "now" and "next", I tried but it is not clear to me and I miss a good example:
"next" -The sound is queued to play immediately after the current sound. If no sound is playing the sound is prepared to play now, but the channel is immediately paused. This allows the sound to be prepared in advance of it being needed.
I am confused about but the channel is immediately paused.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

Post Reply

Return to “Multimedia”