Random Sound Delay

I’m trying to get an audio file to play in a loop, but at random intervals while a button is “toggled” on, and stop when the button is off. I was able to get it to play one time at a random interval, but every way I can think to make it repeat correctly seems to break the functionality all together. Any assistance would be appreciated!!

Capture

I think I see what the problem may be.

(By the way, those blocks appear very much X Thunkable, but this was posted in the Thunkable Classic category)

The way I understand the current logic, is that you click Start, which will wait between 0.6 and 5 second, then start playing music. When the music ENDS, then the logic of the timer will call for an ENDING to the music.
Isn’t that an issue?

When “YeeYee call stop” is issued, the music has already stopped, so asking it again is pointless. But the button caption and more importantly the timer is not reset.
What you need is for the timer to deactivate itself (so as to not fire again and re-trigger a second instance to play while it is already playing). Moreover, your “Stop” function sets Delay LOOPS to false; but nowhere is Delay Loops ever set to true. I think that perhaps it is Delay ENABLED that should be set to false in function “Stop”.
It looks like Delay Fires should call your “Stop” function, instead of calling the YeeYee call Stop.

By the way, you are making use of what is nearly reserved words to name you own function.
The music component is already using the word Stop, spelled like this, which is the same name used in your Stop function, While you have 29 blocks, you can get around with this, but if you start getting a few hundred blocks with complex logic, you are going to paint yourself in a corner. Consider giving your own functions a name that sets them apart from the built-in elements (like calling that Stop function “MyStop” for instance).

@CBVG thanks for looking it over. While I understand many of the concepts from working beside them for years, I am not a programmer by trade. I appreciate you helping me trim the fat from my horribly inept attempt, but now I have a much leaner version of an app that still doesn’t work as intended. Do you happen to have any ideas on how to reset the timer without having to click the button again? Here is what I whittled it down to based on your feedback.

Capture

okay, i played with it a bit more and seem to have gotten it working. I had to add a “if” block to the end of the timer because short interval repeats were preventing me from toggling the button off and sometimes going into an unending loop that didn’t stop, even when toggled off. This seems to have fixed it, though i’m sure there’s a more elegant way. The final issue i’m having is that the audio stops when the screen sleeps. Is there a way to prevent the screen from sleeping, or keep the audio loop going even though the screen is slept?

Capture

A few quick remarks.

In the “When Delay Fires” block, I think that the statement to disable the delay should be the first one, before the call to play YeeYee. As it stands now, the system would play in full before the timer stops, so it may be called several times. I think this is the reason while you were stuck in a fast repeat loop that did not listen. If the random value is close to the minimum (say 0.7 second) this is how fast the timer would be calling the When Delay Fires block. So first thing is to stop any risk of further call.

The other thing that seems strange is that you are calling On (which will re-enable the timer, right after it got disabled) and just before disabling it again (there is no need for the if statement, you just called On, which just set On_Off Test to “Off”, so it is 100% sure to be going that way.)

What you need is your “When Delay Fires” to be
1- from Delay set Enabled to false
2- in YeeYee call Play
(with output error)
then do
Off

That’s it.

Calling Off then would reset the button for another go, if the user clicks the button.

As for the sleeping, I do not think that this is up to the Thunkable program to control. The sleep command comes form the OS, which is the boss of everything that is running, and is not going to take orders from apps. If you want the device to remain awake, the app permission has to be set to “keep device awake” (see this short video to learn how to do it on Android: https://www.youtube.com/watch?v=BUvaFNcyEk0 )

Now, if you want an additional bit of streamlining, here is something that can be done.

Create a variable (it could be named “activated” for instance) and set it to ‘false’.

Then, when you click the button On_Off, the logic there could be:

set activated to NOT activated

Then you can do a simple test

if activated do On
else Off

The interest is that you are not checking strings, which is more time consuming than checking a logical (the comparison is returning a logical anyway. OK, we’re talking millisecond here, but think of all those electrons that would be able to take a rest. One day, when you have much more complicated and demanding apps, you may need those milliseconds, so it would not hurt to think optimisation from the get go).