Software Archive
Read-only legacy content
17061 Discussions

Web Audio API and real current time when playing an audio file

Joan_A_
Beginner
3,225 Views

Hello,

I am having problems when I want to know the current time of a file playing using Web Audio API. My code plays the file nicely and current time returned by getCurrentTime() function is accurate enough when it comes to short files which load fast.

But when I try to load big files, sometimes the current time returned by the getCurrentTime() function is accurate and sometimes not. Sometimes, after waiting for example for 20 seconds to hear the file playing, when it starts playing it says that the current time is about 20 seconds (which is not true because it is just playing the beginning of the file). It happens with any audio format (OGG, MP3, WAV...) but only sometimes.

I am using a slow system (Asus EEE PC 901 with an Intel Atom 1.60 Ghz and 2 GB RAM with Windows XP Home Edition and SP3) and Firefox 41.0.1.

I am not sure, but it seems that source.start() method starts playing the sound way too late so the line after calling that method, where I set the value for the startTime variable, is not the real starting time.

Here is the code (simplified):
 

    var context;
    var buffer;
    function load(file, startAt)
    {
        //Here creates the AudioContext and loads the file through XHR (AJAX) and gets the buffer. All works fine.
        //When it gots the buffer through XHR (AJAX) and all is fine, it calls play(startAt) function immediately.
        //Note: normally, startAt is 0.
    }


    var startTime;
    var stopped = true;
    var source;
    function play(startAt)
    {
        source = context.createBufferSource(); //Context created before.
        source.buffer = buffer; //Buffer got before from XHR (AJAX).
    
        //Creates a gain node to be able to set the volume later:
        var gainNode = context.createGain();
        source.connect(gainNode);
        gainNode.connect(context.destination);

        //Plays the sound:
        source.loop = false;
        source.start(startAt, 0, buffer.duration - 3); //I don't want the last 3 seconds.

        //Stores the start time (useful for pause/resume):
        startTime = context.currentTime - startAt; //Here I store the startTime but maybe the file has still not begun to play.
        
        stopped = false;
    }


    function stop()
    {
        source.stop(0);
        stopped = true;
    }


    function getCurrentTime()
    {
        var currentTime;
    
        if (stopped)
        {
            currentTime = 0;
        }
        else
        {
            currentTime = context.currentTime - startTime;
        }

        return currentTime;
    }

How can I detect when exactly source.start() method starts playing the file? So I can set the variable of startTime value just in that moment and never before.

 

Thank you very much in advance. I would really appreciate any kind of help.

0 Kudos
5 Replies
PaulF_IntelCorp
Employee
3,225 Views

Precise timing of events in a JavaScript environment is difficult.

If your audio file is being streamed over the network, which appears to be the case, based on your comments in the load() function, you may experience network delays that will affect the start of your audio playback. Maybe you should download the file to the local filesystem first, and then play it directly from a local file?

I'm a bit confused by this statement:

I am using a slow system (Asus EEE PC 901 with an Intel Atom 1.60 Ghz and 2 GB RAM with Windows XP Home Edition and SP3) and Firefox 41.0.1.

Are you creating a Windows 8 app using the XDK? You won't be able to build for a Windows XP system. Or are you creating an app for Android using Crosswalk and using the XDK on the system above? If that is the case, I'm guessing that you are using the Emulate tab. In that case, a few comments:

  • The XDK is not guaranteed to work on Windows XP, it is not tested there and the underlying node-webkit typically does not work well when running Windows XP.
  • The Emulate tab is not a real device (see the Emulate tab documentation for more details). If you want to get an accurate picture of how your code will run, especially if you are trying to measure timing of your code, you need to run on a real device. Please use the Debug tab to debug this code.
0 Kudos
Joan_A_
Beginner
3,225 Views

Hello,

Thank you very much for yor reply.

I am running my JavaScript code locally and I also request the audio files from the same machine. All locally. My system with Windows XP has its own web server (Apache).

To export my code to other devices, I use Windows 7 with Intel XDK on another faster computer. But the JavaScript code is still the same one I tried in Windows XP.

Using a slow system lets me notice when something should be optimized. It also lets me find out some problems which would never happen with faster systems. That is important because not everyone has a fast device.

Effectively, it seems that the timing problem is caused by the delay for playing (although I am not completely sure yet). After calling the play method there is still a delay before the sound really starts playing and I need a way to find out when the sound really starts playing. But that is not just a problem with my system as it could also happen to any slow device that runs my code after exporting it with Intel XDK. My phone where I test the code is fast enough (Sony Xperia Z3) so I cannot notice any delay. But a slower device could face timing problems. This is what I am trying to prevent.

If there is no way to detect when the play method really starts playing the file, at least I would need to find another workaround to get the right timing or a more accurate one. It is important because the real code I am using is more powerful and, for example, the play method supports audio sprites (it can play just a part of an audio file) and can also loop. When the desired audio file (or a sprite) has finished playing and we want to loop, the code loops automatically calling again the play method. But there is no way to know when the audio file (or the sprite) has really finished playing completely if I cannot know when it really started playing.

I do not have this problem with other audio APIs or frameworks as for example HTML5 Audio API, SoundManager 2 and Apache Cordova plugin because the current time they provide is tied with the audio file being played. But I want my code to be also compatible with Web Audio API as it seems it provides a very low latency. The code I am doing is for a kind of free and open source game engine I am developing as a hobby. That engine will be able to run virtually everywhere, including modern and old browsers as old as Internet Explorer 5.5, it will be compatible with NW (Node-Webkit), browser extensions, etc. It will also be compatible with Cordova (also PhoneGap and Intel XDK), and will be able to be exported to modern devices as well.

Thank you.

Cheers,

 Joan

0 Kudos
PaulF_IntelCorp
Employee
3,225 Views

Sorry I can't help. Given that the XDK creates Cordova apps, and you've got an adequate solution for Cordova, I'm not sure what we can do to help. If you need help with other platforms this forum won't be of much help. We are concentrated on using the XDK to build Cordova apps.

0 Kudos
Joan_A_
Beginner
3,225 Views

I have got an adequate solution for Cordova apps using Cordova Media plugin. But the Cordova apps (built with Intel XDK) using Web Audio API will face problems with slow devices.

0 Kudos
PaulF_IntelCorp
Employee
3,225 Views

Joan, we build the same Cordova app that you get with Cordova CLI. Also, we HIGHLY recommend developers build against Crosswalk, since it provides much better API options and performance. Not much we can do about those who choose to use the standard Android webview in older Android devices (4.x devices) if they choose to not use Crosswalk.

0 Kudos
Reply