Does anyone have experience making audio alerts? (alert needs to play once) - page 2

 
phade: The alert plays at least 12 times, so this logic isn't necessarily working. Should I do something else 

You are (likely) looking at a signal. Act on a change of signal.
          Too many orders - MQL4 programming forum #1 (2017)

 

I guess there are a few different ways to approach this.

I should be more clear about what my goal is at this point - I want the alert to play for the first second of the bar. I don't mind if the alert plays on every new minute that elapses. I just don't want it to play in an annoying irregular way. 


I'm using Dominiks logic now:

         if(Audio_Alert_On_Signals){        
                  
                      last_playsound_time = time[i] - (time[i] % PeriodSeconds());
                      
                      if (last_playsound_time < time[i]){ 
                      
                           PlaySound(audioFilePath);
                         //  last_playsound_time = time[i];
                      }
                      else{
                           PlaySound(NULL);
                      }
                   }

although I'm noticing very different behavior if I do:

if (last_playsound_time < time[i]){ 

instead of this:

if (last_playsound_time <= time[i]){ 

or this:

if (last_playsound_time == time[i]){ 


something weird is going on, but I'm going to try to get this working with the time buffer

 
phade #:

I guess there are a few different ways to approach this.

I should be more clear about what my goal is at this point - I want the alert to play for the first second of the bar. I don't mind if the alert plays on every new minute that elapses. I just don't want it to play in an annoying irregular way. 


I'm using Dominiks logic now:

although I'm noticing very different behavior if I do:

instead of this:

or this:


something weird is going on, but I'm going to try to get this working with the time buffer

you have the wrong ordering.

First do the if()

Then do the update to the value of last_played....


Edit:

Check my version, the order is relevant. Also the if() statement. You check it for "<" because you update after the check.

Edit2:

The idea is to know if the current time value has a greater value than the time value from the former call on OnCalculate.

It gets updated in the last call, then OnCalculate is called again, with a new value in time[]

It is greater than the last value, because it was updated in the last call.

Now you check and it is greater.

Then you update again the last value, and have it for the next call.

And so on...
 

ok, I was thinking about it another way.  but I understand now. It is actually working now ,small change:

static datetime last_playsound_time = TimeCurrent();

if(Audio_Alert_On_Signals){                

        if (last_playsound_time < time[i]){

         PlaySound(audioFilePath);    

         // Update last_playsound_time to the start of the next minute
         last_playsound_time = time[i] - (time[i] % PeriodSeconds()) + PeriodSeconds();

        }       
}

first takes away the remainder of seconds and then adds another period of 60 seconds to make the variable point to the next minute (it would work for optimization)


I will go with this as it seems to play the alert sound gracefully (and once) without any strange stuff going on. Great

 
phade #:

ok, I was thinking about it another way.  but I understand now. It is actually working now ,small change:

first takes away the remainder of seconds and then adds another period of 60 seconds to make the variable point to the next minute (it would work for optimization)


I will go with this as it seems to play the alert sound gracefully (and once) without any strange stuff going on. Great

If I am not wrong, your version will skip at least 2 minutes before triggering again.

That is because you add another PeriodsSconds to it and you require it to be smaller. "<".

If that is the intention, then good.


 
Dominik Christian Egert #:
If I am not wrong, your version will skip at least 2 minutes before triggering again.

That is because you add another PeriodsSconds to it and you require it to be smaller. "<".

If that is the intention, then good.

I can try without the addition of final 60 seconds again. I wasn't sure if it worked the other way but it it could have been something I did wrong. I don't mind to add another minute to force it to be true
 
phade #:
I can try without the addition of final 60 seconds again. I wasn't sure if it worked the other way but it it could have been something I did wrong. I don't mind to add another minute to force it to be true
I would say it depends on what you want.

Maybe that was intentional, I don't know.

But given your answer, I would speculate not so.

You should update the last_played variable every tick, after checking it. This way you keep the most current data and state.
 

 Just for posterity, it does indeed work fine like so:


if (Audio_Alert_On_Signals) {        
        
    if (last_playsound_time < time[i]) {
        PlaySound(audioFilePath);
                
        // Update last_playsound_time to the start of the current minute
        last_playsound_time = time[i] - (time[i] % PeriodSeconds());
    }
}
 
phade #:

 Just for posterity, it does indeed work fine like so:


I was thinking though there might be (on rare occasion) no audio signal if the time of alert happens to occur on the 0 second for example 13:22:00, because then last_playsound_time < time[i] would not be satisfied (as it would be equal on such an occasion), although I guess it's rare to have an alert occur on the zero second 

No. That is as far as I can see mutual exclusive.
 
 I confused myself, yes that solution is fine. I overlooked the fact that the variable is constantly changing, as it is just a datetime (not a buffer), so there is no need to add another PeriodSeconds() at the end like I did