Permalink
Browse files

added LowLatencyAudio plugins for iOS and Android, with usage examples

  • Loading branch information...
1 parent b2a0769 commit 113123d138e361872c0d06ceb54d09b9bff08fa6 @triceam committed Jan 25, 2012
Showing with 1,784 additions and 0 deletions.
  1. +84 −0 Android/LowLatencyAudio/README.txt
  2. BIN Android/LowLatencyAudio/examples/basic/assets/cymbal.mp3
  3. BIN Android/LowLatencyAudio/examples/basic/assets/drum.mp3
  4. +79 −0 Android/LowLatencyAudio/examples/basic/index.html
  5. +4 −0 Android/LowLatencyAudio/examples/drum machine/assets/README.txt
  6. BIN Android/LowLatencyAudio/examples/drum machine/assets/bass drum.mp3
  7. BIN Android/LowLatencyAudio/examples/drum machine/assets/bongo.mp3
  8. BIN Android/LowLatencyAudio/examples/drum machine/assets/carbonFiber.png
  9. BIN Android/LowLatencyAudio/examples/drum machine/assets/high hat closed.mp3
  10. BIN Android/LowLatencyAudio/examples/drum machine/assets/snare drum.mp3
  11. +110 −0 Android/LowLatencyAudio/examples/drum machine/index.html
  12. +27 −0 Android/LowLatencyAudio/examples/game simulator/assets/README.txt
  13. BIN Android/LowLatencyAudio/examples/game simulator/assets/background.mp3
  14. +109 −0 Android/LowLatencyAudio/examples/game simulator/index.html
  15. +28 −0 Android/LowLatencyAudio/src/PGLowLatencyAudio.js
  16. +221 −0 Android/LowLatencyAudio/src/com/phonegap/PGLowLatencyAudio.java
  17. +76 −0 Android/LowLatencyAudio/src/com/phonegap/PGLowLatencyAudioAsset.java
  18. +131 −0 Android/LowLatencyAudio/src/com/phonegap/PGPolyphonicVoice.java
  19. +89 −0 iPhone/LowLatencyAudio/README.txt
  20. BIN iPhone/LowLatencyAudio/examples/basic/assets/cymbal.mp3
  21. BIN iPhone/LowLatencyAudio/examples/basic/assets/drum.mp3
  22. +79 −0 iPhone/LowLatencyAudio/examples/basic/index.html
  23. +4 −0 iPhone/LowLatencyAudio/examples/drum machine/assets/README.txt
  24. BIN iPhone/LowLatencyAudio/examples/drum machine/assets/bass drum.mp3
  25. BIN iPhone/LowLatencyAudio/examples/drum machine/assets/bongo.mp3
  26. BIN iPhone/LowLatencyAudio/examples/drum machine/assets/carbonFiber.png
  27. BIN iPhone/LowLatencyAudio/examples/drum machine/assets/high hat closed.mp3
  28. BIN iPhone/LowLatencyAudio/examples/drum machine/assets/snare drum.mp3
  29. +110 −0 iPhone/LowLatencyAudio/examples/drum machine/index.html
  30. +27 −0 iPhone/LowLatencyAudio/examples/game simulator/assets/README.txt
  31. BIN iPhone/LowLatencyAudio/examples/game simulator/assets/background.mp3
  32. +109 −0 iPhone/LowLatencyAudio/examples/game simulator/index.html
  33. +41 −0 iPhone/LowLatencyAudio/src/PGLowLatencyAudio.h
  34. +28 −0 iPhone/LowLatencyAudio/src/PGLowLatencyAudio.js
  35. +304 −0 iPhone/LowLatencyAudio/src/PGLowLatencyAudio.m
  36. +34 −0 iPhone/LowLatencyAudio/src/PGLowLatencyAudioAsset.h
  37. +90 −0 iPhone/LowLatencyAudio/src/PGLowLatencyAudioAsset.m
@@ -0,0 +1,84 @@
+PGLowLatencyAudio plugin for PhoneGap/Apache Cordova
+Developed by Andrew Trice - http://tricedesigns.com
+
+THIS SOFTWARE IS PROVIDED BY ANDREW TRICE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ANDREW TRICE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+You can read more about this plugin at:
+http://www.tricedesigns.com/2012/01/25/low-latency-polyphonic-audio-in-phonegap/
+
+The low latency audio plugin is designed to enable low latency and polyphonic audio from PhoneGap applications, using a very simple and basic API.
+
+Getting started:
+Add the following files to your JAVA project, keeping the folder structure:
+com/phonegap/PGLowLatencyAudio.java
+com/phonegap/PGLowLatencyAudioAsset.java
+com/phonegap/PGPolyphonicVoice.java
+
+Add the following file to your www directory, and add to index.html:
+PGLowLatencyAudio.js
+
+Add the following to your phonegap plugins.xml file:
+<plugin name="PGLowLatencyAudio" value="com.phonegap.PGLowLatencyAudio" />
+
+Usage:
+1) Preload the audio asset
+2) Play the audio asset
+3) When done, unload the audio asset
+
+API methods:
+preloadFX: function ( id, assetPath, success, fail)
+ params: ID - string unique ID for the audio file
+ assetPath - the relative path to the audio asset within the www directory
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ The preloadFX function loads an audio file into memory. Assets that are loaded using preloadFX are managed/played using the Android SoundPool class. These are very low-level audio methods and have minimal overhead. These assets should be short. Sound files longer than 5 seconds may have errors including (not playing, clipped content, not looping) - all will fail silently on the device (debug output will be visible if connected to debugger). These assets are fully concurrent and polyphonic.
+
+preloadAudio: function ( id, assetPath, voices, success, fail)
+ params: ID - string unique ID for the audio file
+ assetPath - the relative path to the audio asset within the www directory
+ voices - the number of polyphonic voices available
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ The preloadAudio function loads an audio file into memory. Assets that are loaded using preloadAudio are managed/played using the Android MediaPlayer. These have more overhead than assets laoded via preloadFX, and can be looped/stopped. By default, there is a single "voice" - only one instance that will be stopped & restarted when you hit play. If there are multiple voices (number greater than 0), it will cycle through voices to play overlapping audio.
+
+play: function (id, success, fail)
+ params: ID - string unique ID for the audio file
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ Plays an audio asset
+
+loop: function (id, success, fail)
+ params: ID - string unique ID for the audio file
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ Loops an audio asset infinitely - this only works for assets loaded via preloadAudio
+
+stop: function (id, success, fail)
+ params: ID - string unique ID for the audio file
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ Stops an audio file - this only works for assets loaded via preloadAudio
+
+unload: function (id, success, fail)
+ params: ID - string unique ID for the audio file
+ success - success callback function
+ fail - error/fail callback function
+ detail:
+ Unloads an audio file from memory
+
+
+
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title></title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
+ <meta charset="utf-8">
+
+
+ <script type="text/javascript" charset="utf-8" src="phonegap-1.3.0.js"></script>
+ <script type="text/javascript" charset="utf-8" src="PGLowLatencyAudio.js"></script>
+ <script type="text/javascript">
+
+
+ function onBodyLoad()
+ {
+ document.addEventListener("deviceready", onDeviceReady, false);
+ }
+
+ function onDeviceReady()
+ {
+ // do your thing!
+ }
+
+ function overlap()
+ {
+ setTimeout( function() {PGLowLatencyAudio.play('cymbal');}, 300 );
+ setTimeout( function() {PGLowLatencyAudio.play('drum');}, 600 );
+ setTimeout( function() {PGLowLatencyAudio.play('cymbal');}, 900 );
+ setTimeout( function() {PGLowLatencyAudio.play('drum');}, 900 );
+ setTimeout( function() {PGLowLatencyAudio.play('drum');}, 950 );
+ setTimeout( function() {PGLowLatencyAudio.play('drum');}, 2000 );
+ setTimeout( function() {PGLowLatencyAudio.play('cymbal');}, 2000 );
+ }
+
+ function successHandler (result) {
+ alert( result );
+ }
+
+ function errorHandler (error) {
+ alert( error );
+ }
+
+ </script>
+
+ <style>
+
+ * {
+ -webkit-overflow-scrolling: none;
+ }
+
+ body {
+ background-color:#FFF;
+ background-image: url('assets/carbonFiber.png');
+ font-size: 40px;
+ }
+ </style>
+ </head>
+ <body onload="onBodyLoad()">
+ <h1>Hey, it's PhoneGap!</h1>
+
+ <br />
+ <ol>
+ <li><a href="javascript:PGLowLatencyAudio.preloadAudio('cymbal', 'assets/cymbal.mp3', 3, successHandler, errorHandler);">preload cymbal</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.preloadFX('drum', 'assets/drum.mp3', successHandler, errorHandler);">preload drum</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.play('cymbal', successHandler, errorHandler);">play cymbal</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.play('drum', successHandler, errorHandler);">play drum</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.unload('cymbal', successHandler, errorHandler);">unload cymbal</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.unload('drum', successHandler, errorHandler);">unload drum</a></li>
+ <li><a href="javascript:overlap();">overlap</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.loop('cymbal', successHandler, errorHandler);">loop</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.stop('cymbal', successHandler, errorHandler);">stop cymbal</a></li>
+ </ol>
+ <ol>
+ <li><a href="javascript:PGLowLatencyAudio.preloadAudio('cymbal123', 'assets/cymbal123.mp3', 3, successHandler, errorHandler);">error - missing Audio asset</a></li>
+ <li><a href="javascript:PGLowLatencyAudio.preloadFX('drum123', 'assets/drum123.mp3', successHandler, errorHandler);">error - missing Fx asset</a></li>
+ </ol>
+ </body>
+</html>
@@ -0,0 +1,4 @@
+YOU MAY DO WHAT YOU WISH WITH THESE RECORDINGS.
+I RECORDED THEM MYSELF FROM A SYNTH.
+
+-Andrew Trice
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title></title>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
+ <meta charset="utf-8">
+
+ <script type="text/javascript" charset="utf-8" src="phonegap-1.3.0.js"></script>
+ <script type="text/javascript" charset="utf-8" src="PGLowLatencyAudio.js"></script>
+ <link href="http://fonts.googleapis.com/css?family=Monoton" rel="stylesheet" type="text/css">
+
+ <style>
+
+ * {
+ -webkit-overflow-scrolling: none;
+ }
+
+ body {
+ background-color:#222;
+ background-image: url('assets/carbonFiber.png');
+ }
+
+ div {
+ position:absolute;
+ width: 46%;
+ height: 44%;
+ border-radius: 20px;
+ border: 5px solid rgba(50,50,50,.5);
+ background-color:rgba(255,140,0,.8);
+ font-family: 'Monoton', cursive;
+ font-size: 50pt;
+ }
+
+ #bassDiv {
+ left:20px;
+ bottom:20px;
+ }
+ #snareDiv {
+ right:20px;
+ bottom:20px;
+ }
+ #hhDiv {
+ right:20px;
+ top:20px;
+ }
+ #bongoDiv {
+ left:20px;
+ top:20px;
+ }
+
+ .touched {
+ background-color:rgba(255,140,0,.6);
+ border: 5px solid rgba(50,50,50,.8);
+ }
+ </style>
+ <script type="text/javascript">
+
+ function onBodyLoad()
+ {
+ document.addEventListener("deviceready", onDeviceReady, false);
+ document.addEventListener("touchmove", function (e) { e.preventDefault(); return false; }, false);
+ document.addEventListener("touchstart", function (e) { e.preventDefault(); return false; }, false);
+ }
+
+ function onDeviceReady()
+ {
+ PGLowLatencyAudio.preloadFX('bass', 'assets/bass drum.mp3');
+ PGLowLatencyAudio.preloadFX('snare', 'assets/snare drum.mp3');
+ PGLowLatencyAudio.preloadFX('highhat', 'assets/high hat closed.mp3');
+ PGLowLatencyAudio.preloadFX('bongo', 'assets/bongo.mp3');
+ }
+
+ function bass() {
+ document.getElementById("bassDiv").className = "touched";
+ PGLowLatencyAudio.play('bass');
+ }
+
+ function snare() {
+ document.getElementById("snareDiv").className = "touched";
+ PGLowLatencyAudio.play('snare');
+ }
+
+ function highhat() {
+ document.getElementById("hhDiv").className = "touched";
+ PGLowLatencyAudio.play('highhat');
+ }
+
+ function bongo() {
+ document.getElementById("bongoDiv").className = "touched";
+ PGLowLatencyAudio.play('bongo');
+ }
+
+ function touchend( event ) {
+ event.target.className = "";
+ }
+ </script>
+
+
+
+ </head>
+ <body onload="onBodyLoad()">
+
+ <div id="bassDiv" ontouchstart="bass()" ontouchend="touchend(event)">Bass</div>
+ <div id="hhDiv" ontouchstart="highhat();" ontouchend="touchend(event)">High Hat</div>
+ <div id="snareDiv" ontouchstart="snare();" ontouchend="touchend(event)">Snare</div>
+ <div id="bongoDiv" ontouchstart="bongo();" ontouchend="touchend(event)">bongo</div>
+
+ </body>
+</html>
@@ -0,0 +1,27 @@
+YOU CAN FIND THE FOLLOWING FILES AT THESE LOCATIONS:
+I did not include them b/c of licensing.
+
+air raid.mp3:
+http://www.freesound.org/people/guitarguy1985/sounds/57808/
+
+war2.mp3:
+http://www.freesound.org/people/Omar%20Alvarado/sounds/96533/
+
+war.mp3:
+http://www.freesound.org/people/Syna-Max/sounds/56900/
+
+thunder.mp3:
+http://www.freesound.org/people/RHumphries/sounds/2523/
+
+missile strike.mp3:
+http://www.freesound.org/people/digifishmusic/sounds/42024/
+
+machine gun.mp3:
+http://www.freesound.org/people/Matt_G/sounds/30749/
+
+hirosima-radio.mp3:
+http://www.freesound.org/people/ERH/sounds/31644/
+
+explision.mp3:
+http://www.freesound.org/people/ljudman/sounds/33245/
+
Oops, something went wrong.

0 comments on commit 113123d

Please sign in to comment.