Announcement

Collapse
No announcement yet.

Two playSounds playing at the same time

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Two playSounds playing at the same time

    If I call playSound("2secondWavFile.wav") from one chart and another chart calls a playSound at the same time, it appears as though the 2nd playSound doesn't play (at least I can't hear it). To address this problem I'm trying to constuct some type of crude thread syncronization lock using a global variable and a while loop such that if one wav file is playing, any other calls to playSound will block till the first wav file completes and I will hear both wav files completely. I'm thinking something like the following should work:

    //globals
    var vThreadLock=0;

    main()
    {
    .
    .
    .
    vThreadLock = getGlobalValue( "threadLock" );

    while (vThreadLock != 0)
    {
    printDebugln("waiting");
    }
    setGlobalValue("threadLock", 1);
    playSound("myAlert.wav");
    setGlobalValue("threadLock", 0);
    }


    Is this a good/safe way to aproach this problem? Are there any potential thread syncronization problems such as a potential race condition or deadlock? Do all the EFS scripts run on a single thread? If so, I would assume there would be no threading issues however I would also assume if two different scripts called playSound at the same time, the 2nd playSound would block till the first playSound completed unless perhaps the playSound function runs on its own thread.

    Any help along these lines would be apreciated.

  • #2
    Alternate...

    This seems like a solid solution...

    But... If your sound files are all a specific length, you can simply "timestamp" your sound initiation time and wait for the proper time to pass before sending the request for the next sound file...

    You might choose to build an array of sound instances. This would allow you to have a "que" of waiting sounds to be played.

    Let's say three sounds are set to go off at the same time.. You would place then in the "que" (array), then create a routine that checks to see if anything (sound) is currently playing. If so, then wait the proper amount of time, then play the next.

    In esignal, using a while loop can present problems (as your code may loop while tick data is streaming through. The benefit to this is that if you use a while loop, your "time" issue will not be linked to (waiting for) new ticks to arrive before running the EFS again.

    So, there are benefits and draw-backs to both.

    I would think that you could create the ARRAY, with a function specifically linked to RTtime that will accomplish what you want. Testing it with/without the WHILE loop would be the next option. If this is linked to a trading system - I would suggest NOT using the WHILE loop.

    Here is some help (code) to assist you...

    //Defining your array...
    var mySoundQue = new Object;
    mySoundQue.FileName = "";
    mySoundQue.Length = 0;
    //This creates an array of objects to handle your sound que.
    var SoundQueArray = new Array();


    // Control Variables
    var SoundArrayCount = 0;
    var LastSoundTS = 0;
    var LastSoundLength = 0;
    var vHour;
    var vMin;
    var vSec;
    var vDay;
    var vMonth;


    function main() {

    //-- this code retrieves the current RT time - or computers clock time.
    var vTime = new Date();
    //---------------------------------------------------
    // Get Time Variables
    // vTime = getValue("Time", 0); Uncomment to get the BAR TIME
    vHour = vTime.getHours();
    vMin = vTime.getMinutes();
    vSec = vTime.getSeconds();
    vDay = vTime.getDate();
    vMonth = vTime.getMonth() +1;

    //Now, all you would need to do is add sounds to your QUE.
    if (BUYSIGNAL) {
    QUEAddSound("new.wav", 1);
    }

    // Play your sounds (if the que has anything in it).
    RunSoundQue();


    }

    //-- this is an example of a sound time-stamp and a conditional testing of the sound que. You would put this into your main().

    function RunSoundQue () {
    if (SoundArrayCount > 0) {

    if ( ((vHour*3600)+(vMin*60)+vSec) > (LastSoundTS+LastSoundLength) ) {
    // Pull new sound request from array.
    with (SoundQueArray) {
    LastSoundLength = SoundQueArray[SoundArrayCount-1].length;
    LastSoundTS = ((vHour*3600)+(vMin*60)+vSec);
    Alert.playSound(SoundQueArray[SoundArrayCount-1].filename);
    // re-structure array (re-order) - only needed it two or more sounds in que. Arrays start with 0.
    for (x=2; x< SoundArrayCount; x++) {
    SoundQueArray[x-2].filename = SoundQueArray[x-1].filename;
    SoundQueArray[x-2].length = SoundQueArray[x-1].length;
    }
    }
    SoundArrayCount -= 1;
    }
    }
    }

    //Now, all you would need to do is add sounds to your QUE.

    function QUEAddSound(filename, length) {
    SoundArrayCount += 1;
    mySoundQue.FileName = filename;
    mySoundQue.Length = length; // in total seconds
    SoundQueArray[SoundArrayCount-1] = mySoundQue;
    }

    There may be a few minor bugs in this example code. I created it on the fly. If you need help, let me know.

    B
    Brad Matheny
    eSignal Solution Provider since 2000

    Comment


    • #3
      Thanks Brad,

      I was hoping there would be a simpler solution than timing the wav files. Upon futher investigation, the playSound function acts like it is theaded, which in general, is a very good thing but sure complicates mutiple calls to playSound. If you just place 2 consecutive playSound() calls one after the other in a single formula the first one never plays unless some sort of delay is placed between them.

      I think I'll take another route and just check for both conditions and record a single wav that has both messages in it and thus only make a single playSound call.

      Comment

      Working...
      X