<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
    <title>Cordova Audio Tests</title>
    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
    <script type="text/javascript" charset="utf-8" src="../cordova.js"></script>      

      
<script type="text/javascript" charset="utf-8">

	//var defaultaudio = "/android_asset/one.mp3"; //local file
	 var defaultaudio = "http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3";
       //var src = "http://neuga.s3.amazonaws.com/onclassical/strings-or gan.mp3";
 //      var src = "http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3";
        //var src = "/android_asset/www/Jet_Sledding.mp4"; // no work
        //var src = "http://vprbbc.streamguys.net/vprbbc24.mp3"; // mp3 streaming
    var deviceReady = false;

    //-------------------------------------------------------------------------
    // Audio player
    //-------------------------------------------------------------------------
    var media1 = null;
    var media1Timer = null;
    var audioSrc = null;
    var recordSrc = "myRecording.mp3";

    /**
     * Play audio
     */
    function playAudio(url) {
        console.log("playAudio()");
        console.log(" -- media="+media1);

	    var src = defaultaudio;
        
        if (url) {
            src = url;
        }

        // Stop playing if src is different from currently playing source
        if (src != audioSrc) {
            if (media1 != null) {
                stopAudio();
                media1 = null;
            }
        }

        if (media1 == null) {


            // TEST STREAMING AUDIO PLAYBACK
            //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3";   // works
            //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
            //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
            //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
            //var src = "MusicSearch/mp3/train.mp3";    // works
            //var src = "bryce.mp3";  // works
            //var src = "/android_asset/www/bryce.mp3"; // works

            media1 = new Media(src,
                function() {
                    console.log("playAudio():Audio Success");
                },
                function(err) {
                    console.log("playAudio():Audio Error: "+err.code);
                    setAudioStatus("Error: " + err.code);
                },
                function(status) {
                    console.log("playAudio():Audio Status: "+status);
                    setAudioStatus(Media.MEDIA_MSG[status]);

                    // If stopped, then stop getting current position
                    if (Media.MEDIA_STOPPED == status) {
                        clearInterval(media1Timer);
                        media1Timer = null;
                        setAudioPosition("0 sec");
                    }
                });
        }
        audioSrc = src;
        document.getElementById('audio_duration').innerHTML = "";
        // Play audio
        media1.play();
        if (media1Timer == null && media1.getCurrentPosition) {
            media1Timer = setInterval(
                function() {
                    media1.getCurrentPosition(
                        function(position) {
                            console.log("Pos="+position);
                            if (position >= 0.0) {
                                setAudioPosition(position+" sec");
                            }
                        },
                        function(e) {
                            console.log("Error getting pos="+e);
                            setAudioPosition("Error: "+e);
                        }
                    );
                },
                1000
            );
        }

        // Get duration
        var counter = 0;
        var timerDur = setInterval(
            function() {
                counter = counter + 100;
                if (counter > 2000) {
                    clearInterval(timerDur);
                }
                var dur = media1.getDuration();
                if (dur > 0) {
                    clearInterval(timerDur);
                    document.getElementById('audio_duration').innerHTML = dur + " sec";
                }
            }, 100);
    }

    /**
     * Pause audio playback
     */
    function pauseAudio() {
        console.log("pauseAudio()");
        if (media1) {
            media1.pause();
        }
    }

    /**
     * Stop audio
     */
    function stopAudio() {
        console.log("stopAudio()");
        if (media1) {
            media1.stop();
        }
        clearInterval(media1Timer);
        media1Timer = null;
    }
    
    /**
     * Release audio
     */
	function releaseAudio() {
	    console.log("releaseAudio()");
	    if (media1) {
	    	media1.stop(); //imlied stop of playback, resets timer
	    	media1.release();
	    }
	}
	
    /**
     * Set audio status
     */
    var setAudioStatus = function(status) {
        document.getElementById('audio_status').innerHTML = status;
    };

    /**
     * Set audio position
     */
    var setAudioPosition = function(position) {
        document.getElementById('audio_position').innerHTML = position;
    };

    //-------------------------------------------------------------------------
    // Audio recorder
    //-------------------------------------------------------------------------
    var mediaRec = null;
    var recTime = 0;

    /**
     * Record audio
     */
    function recordAudio() {
        console.log("recordAudio()");
        console.log(" -- media="+mediaRec);
        if (mediaRec == null) {

            var src = recordSrc;
            mediaRec = new Media(src,
                    function() {
                        console.log("recordAudio():Audio Success");
                    },
                    function(err) {
                        console.log("recordAudio():Audio Error: "+err.code);
                        setAudioStatus("Error: " + err.code);
                    },
                    function(status) {
                        console.log("recordAudio():Audio Status: "+status);
                        setAudioStatus(Media.MEDIA_MSG[status]);
                    }
                );
        }

        navigator.notification.beep(1);

        // Record audio
        mediaRec.startRecord();

        // Stop recording after 10 sec
        recTime = 0;
        var recInterval = setInterval(function() {
            recTime = recTime + 1;
            setAudioPosition(recTime+" sec");
            if (recTime >= 10) {
                clearInterval(recInterval);
                if (mediaRec.stopAudioRecord){
                    mediaRec.stopAudioRecord();
                } else {
                    mediaRec.stopRecord();
                }
                console.log("recordAudio(): stop");
                navigator.notification.beep(1);
            }
        }, 1000);
    }

    /**
     * Play back recorded audio
     */
    function playRecording() {
        playAudio(recordSrc);
    }
    
    /**
     * Function to create a file for iOS recording
     */
    function getRecordSrc() {
        var fsFail = function(error) {
            console.log("error creating file for iOS recording");
        };
        var gotFile = function(file) {
            recordSrc = file.fullPath;
            //console.log("recording Src: " + recordSrc);
        };
        var gotFS = function(fileSystem) {
            fileSystem.root.getFile("iOSRecording.wav", {create: true}, gotFile, fsFail);
        };
        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
    }
    
    /**
     * Function to create a file for BB recording
     */
    function getRecordSrcBB() {
        var fsFail = function(error) {
            console.log("error creating file for BB recording");
        };
        var gotFile = function(file) {
            recordSrc = file.fullPath;
        };
        var gotFS = function(fileSystem) {
            fileSystem.root.getFile("BBRecording.amr", {create: true}, gotFile, fsFail);
        };
        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
    }

    /**
     * Function called when page has finished loading.
     */
    function init() {
        document.addEventListener("deviceready", function() {
                deviceReady = true;
                if (device.platform.indexOf("iPhone") !=-1 || device.platform.indexOf("iPad") !=-1)
                {
                     getRecordSrc();
                } else if (typeof blackberry !== 'undefined') {
                    getRecordSrcBB();
                }
                console.log("Device="+device.platform+" "+device.version);
            }, false);
        window.setTimeout(function() {
        	if (!deviceReady) {
        		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
        	}
        },1000);
    }
    
    /**
     * for forced updates of position after a successful seek
     */
    function updatePosition() {
        media1.getCurrentPosition(
            function(position) {
                console.log("Pos="+position);
                if (position >= 0.0) {
                    setAudioPosition(position+" sec");
                }
            },
            function(e) {
                console.log("Error getting pos="+e);
                setAudioPosition("Error: "+e);
            });
    }

    /**
     *
     */
    function seekAudio(mode) {
        var time = document.getElementById("seekinput").value;
        if (time == "") {
            time = 5000;
        } else {
            time = time * 1000; //we expect the input to be in seconds
        }
        if (media1 == null) {
            console.log("seekTo requested while media1 is null");
            if (audioSrc == null) {
                audioSrc = defaultaudio;
            }
            media1 = new Media(audioSrc,
                function() {
                    console.log("seekToAudio():Audio Success");
                },
                function(err) {
                    console.log("seekAudio():Audio Error: "+err.code);
                    setAudioStatus("Error: " + err.code);
                },
                function(status) {
                    console.log("seekAudio():Audio Status: "+status);
                    setAudioStatus(Media.MEDIA_MSG[status]);

                    // If stopped, then stop getting current position
                    if (Media.MEDIA_STOPPED == status) {
                        clearInterval(media1Timer);
                        media1Timer = null;
                        setAudioPosition("0 sec");
                    }
                });
        }
        
        media1.getCurrentPosition(
            function (position) {
                var deltat = time;
                if (mode == "by") {
                    deltat = time + position * 1000;   
                }
                media1.seekTo(deltat,
                    function () {
                        console.log("seekAudioTo():Audio Success");
                        //force an update on the position display
                        updatePosition();
                    },
                    function (err) {
                        console.log("seekAudioTo():Audio Error: " + err.code);
                    });
            },
            function(e) {
                console.log("Error getting pos="+e);
                setAudioPosition("Error: "+e);
            });
    }
    
</script>

  </head>
  <body onload="init();" id="stage" class="theme">
  
    <h1>Audio</h1>  
    <div id="info">
        <table width="100%">
        <tr><td><b>Status:</b></td><td id="audio_status"> </td></tr>
        <tr><td><b>Duration:</b></td><td id="audio_duration"></td></tr>
        <tr><td><b>Position:</b></td><td id="audio_position"></td></tr>
        </table>
    </div>
    <h2>Action</h2>
    <table style="width:80%;">
        <tr>
            <th colspan=3>Play Sample Audio</th>
        </tr>
        <tr>
            <td><div class="btn wide" onclick="playAudio();">Play</div></td>
            <td><div class="btn wide" onclick="pauseAudio();">Pause</div></td>
        </tr>
        <tr>
            <td><div class="btn wide" onclick="stopAudio();">Stop</div></td>
            <td><div class="btn wide" onclick="releaseAudio();">Release</div></td>
        </tr>
    </table>
    
    <table style="width:80%;">
        <tr>
            <td><div class="btn wide" onclick="seekAudio('by');">Seek By</div></td>
            <td><div class="btn wide" onclick="seekAudio('to');">Seek To</div></td>
            <td>
                <div>
                    <input class="input numeric" type="number" id="seekinput" value="in seconds">
                </div>
            </td>
        </tr>
    </table>
    
    <table style="width:80%;">
        <tr>
            <th colspan=3><br><br>Record Audio</th>
        </tr>
        <tr>
            <td colspan=3><div class="btn wide" onclick="recordAudio();">Record Audio for 10 sec</a></td>
        </tr>
        <tr>
            <td><div class="btn wide" onclick="playRecording();">Play</div></td>
            <td><div class="btn wide" onclick="pauseAudio();">Pause</div></td>
            <td><div class="btn wide" onclick="stopAudio();">Stop</div></td>
        </tr>
    </table>
    
    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
    
  </body>
</html>      
