diff --git a/Gemfile b/Gemfile index 51ddc1db..8fd03a16 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'rails', '3.2.17' # gem 'rails', :git => 'git://github.com/rails/rails.git' gem 'devise' -gem 'redis' +gem 'redis', '2.2.2' gem 'pg' gem 'cancan' gem 'formula' diff --git a/Gemfile.lock b/Gemfile.lock index e4bbb146..b4efab8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -117,7 +117,7 @@ GEM rake (10.3.2) rdoc (3.12.2) json (~> 1.4) - redis (3.0.7) + redis (2.2.2) sass (3.3.7) sass-rails (3.2.6) railties (~> 3.2.0) @@ -160,6 +160,6 @@ DEPENDENCIES pg rails (= 3.2.17) rails3-jquery-autocomplete - redis + redis (= 2.2.2) sass-rails uglifier (>= 1.0.3) diff --git a/Gemfile~ b/Gemfile~ deleted file mode 100644 index 9e2acc35..00000000 --- a/Gemfile~ +++ /dev/null @@ -1,47 +0,0 @@ -source 'https://rubygems.org' - -gem 'rails', '3.2.17' - -# Bundle edge Rails instead: -# gem 'rails', :git => 'git://github.com/rails/rails.git' - -gem 'devise' -gem 'redis' -gem 'pg' -gem 'cancan' -gem 'formula' -gem 'formtastic' -gem 'json' -gem 'rails3-jquery-autocomplete' -gem 'best_in_place' -gem 'therubyracer' #optional -#gem 'rb-readline' - -# Gems used only for assets and not required -# in production environments by default. -group :assets do - gem 'sass-rails' - gem 'coffee-rails', '~> 3.2.1' - - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - # gem 'therubyracer' - - gem 'uglifier', '>= 1.0.3' -end - -gem 'jquery-rails', '2.1.2' - -# To use ActiveModel has_secure_password -# gem 'bcrypt-ruby', '~> 3.0.0' - -# To use Jbuilder templates for JSON - gem 'jbuilder', '0.8.2' - -# Use unicorn as the web server -# gem 'unicorn' - -# Deploy with Capistrano -# gem 'capistrano' - -# To use debugger -# gem 'ruby-debug19', :require => 'ruby-debug' diff --git a/app/assets/images/synapsevisualize.png b/app/assets/images/synapsevisualize.png new file mode 100644 index 00000000..a3f85f59 Binary files /dev/null and b/app/assets/images/synapsevisualize.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/README.rdoc b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/README.rdoc new file mode 100755 index 00000000..60f1529d --- /dev/null +++ b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/README.rdoc @@ -0,0 +1,71 @@ +== SoundManager 2: JavaScript Sound for the Web + +By wrapping and extending HTML5 and Flash Audio APIs, SoundManager 2 brings reliable cross-platform audio to JavaScript. + +== HTML5 Audio() Support + + * 100% Flash-free MP3 + MP4/AAC where supported + * Compatible with Apple iPad 3.2, iPhone/iOS 4 and newer + * Fallback to Flash for MP3/MP4 support, as needed + * SM2 API is transparent; HTML5/flash switching handled internally + * HTML5 API support approximates Flash 8 API features + * Some other formats (WAV/OGG) supported via HTML5, depending on browser + * See "useHTML5Audio" property for implementation details + +== Basic API Features (Flash 8) + + * Load, stop, play, pause, mute, seek, pan and volume control of sounds from Javascript + * Events: onload, whileloading, whileplaying, onfinish and more + * ID3V1 and ID3V2 tag support for MP3s (title, artist, genre etc.) + +== Shiny Flash 9 Features + + * RTMP / Flash Media Server streaming support (new, experimental) + * MPEG-4 (AAC, HE-AAC, H.264) audio support + * "MultiShot" play (layered/chorusing effects) + * Waveform/frequency spectrum data + * Peak (L/R channel volume) data + * Audio buffering state/event handling + +== General Tech Stuff + + * Full API Documentation with examples and notes + * console.log()-style debug output and troubleshooting tools + * Community-based discussion/support + +== As Heard On The Internets + +A few nifty sites that have implemented SM2 for driving audio: + + * SoundCloud / The Cloud Player + * last.fm + * Opera (media player component) + * 8tracks + * Discogs + * The Hype Machine + * nyan.cat + * turntable.fm + * AudioGalaxy + +== Project home, documentation, live demos etc.: + +http://www.schillmania.com/projects/soundmanager2/ + +== Compiling JS builds (-nodebug, -jsmin) and Flash components, AS2/AS3 to SWF + +An Ant build file defines the tasks for compiling JS and SWF components, useful if you make changes to the SM2 source and want to recompile. +Google's Closure Compiler is used for the JS. AS2 compilation is done by MTASC, and AS3 is handled by Adobe's Open Source Flex SDK (mxmlc) compiler. +Refer to the build.xml file for compiler downloads and path definitions. + +== Versioning / Development Notes + +Releases are versioned by date, e.g., V2.97a.20110424 and are tagged as such.* +The latest official release is always on trunk/master. +Post-release development builds may be available on the appropriate +DEV branch, eg., V2.97a.20110801+DEV + +== Forks and Pull Requests + +Firstly, thank you for wanting to contribute! Bug fixes and tweaks are welcomed, particularly if they follow the general coding style of the project. +If making a pull request, use the project's current +DEV development branch as the merge target instead of "master", if possible (please and thank-you.) + +* SoundManager 2 has been at "version" 2.97 for a long time, because 2.97 was arguably the best llama-ass-whipping version of WinAmp. (WinAmp 3 was not as good, and WinAmp 5 was "the best of 2 and 3 combined.") This MP3 player was my favourite Windows app during the 90's, and is missed as there's nothing quite like it on OS X where I spend most of my time these days. diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button - large.psd b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button - large.psd new file mode 100755 index 00000000..930b41e0 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button - large.psd differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button.psd b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button.psd new file mode 100755 index 00000000..afd04980 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360 button.psd differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.gif new file mode 100755 index 00000000..a7efb1da Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.png new file mode 100755 index 00000000..21860abb Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause-light.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.gif new file mode 100755 index 00000000..5317ded4 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.png new file mode 100755 index 00000000..b22bf93f Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-pause.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.gif new file mode 100755 index 00000000..22be94f8 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.png new file mode 100755 index 00000000..fc30c5f4 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play-light.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.gif new file mode 100755 index 00000000..d150c0d6 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.png new file mode 100755 index 00000000..8fd7c4c6 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-play.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.gif new file mode 100755 index 00000000..68bf149f Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.png new file mode 100755 index 00000000..a4a0a5ed Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause-light.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.gif new file mode 100755 index 00000000..4bd23332 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.png new file mode 100755 index 00000000..3627f67a Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-pause.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.gif new file mode 100755 index 00000000..7ce69321 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.png new file mode 100755 index 00000000..599b0c67 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play-light.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.gif b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.gif new file mode 100755 index 00000000..4837776a Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.gif differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.png b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.png new file mode 100755 index 00000000..a36478d8 Binary files /dev/null and b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360-button-vis-play.png differ diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player-visualization.css b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player-visualization.css new file mode 100755 index 00000000..6bef9969 --- /dev/null +++ b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player-visualization.css @@ -0,0 +1,156 @@ +/* larger canvas, spectrum + EQ visualization and other items */ + +.ui360-vis, +.ui360-vis .sm2-360ui, +.sm2-inline-list .ui360-vis { + /* size of the container for the circle, etc. */ + width:256px; + height:256px; +} + +.ui360-vis { + position:relative; + /* a little extra spacing */ + padding-top:1px; + padding-bottom:1px; + margin-bottom:-18px; /* approximate "line height" we want */ + padding-left:248px; + margin-left:0px; + background-position:22.6% 50%; /* (~109px) initial play button position */ +} + +.sm2-inline-list .ui360-vis { + cursor:pointer +} + +.ui360-vis a { + font:14px "helvetica neue",helvetica,monaco,lucida,terminal,monospace; + white-space:nowrap; + text-indent:0px; /* undo inline style */ + top:46%; /* ehh. */ +} + +.sm2-inline-list .ui360-vis a { + line-height:256px; + top:auto; +} + +.ui360-vis .sm2-360ui { + margin-left:-256px; +} + +.ui360-vis .sm2-timing { + font:bold 24px "helvetica neue",helvetica,monaco,lucida,terminal,monospace; + color:#333; + text-align:center; + line-height:256px; + text-indent:0px; +} + +.sm2-inline-list .ui360-vis, +.sm2-inline-list .ui360-vis .sm2-360ui { + margin-left:0px; +} + +.sm2-inline-list .ui360-vis { + margin:8px 13px 7px 0px; + padding-left:0px; + background-position:50% 50%; /* initial play button position */ +} + +.sm2-inline-list .ui360-vis .sm2-360ui { + border:1px solid #eee; + /* offset the border */ + margin-left:-1px; + margin-top:-1px; +} + +.sm2-inline-list .ui360-vis a { + position:absolute; + display:inline; + left:0px; + bottom:0px; + top:1px; + width:100%; /* 2px padding in box */ + height:99%; /* dumb vertical hack */ + *height:256px; /* IE is dumb. */ + overflow:hidden; + font-size:small; + font-weight:300; + color:#333; + margin:0px; + padding:0px; + line-height:488px; /* bottom vertical alignment for text */ + *line-height:480px; /* IE again */ + text-align:center; + border-radius:0px; +} + +.sm2-inline-list .ui360 a:hover { + background-color:transparent; /* reset */ +} + +.sm2-inline-list .ui360-vis:hover .sm2-360ui, +.sm2-inline-list .ui360-vis a.sm2_link:hover, +.sm2-inline-list .ui360-vis a.sm2_link:active, +.sm2-inline-list .ui360-vis a.sm2_link:focus { + background-color:transparent; +} + +.sm2-inline-list .ui360-vis:hover a.sm2_link { + background-color:#fafafa; + *background-color:transparent; /* eh, screw IE. */ +} + +/* Use a bigger loading image for this layout */ + +.ui360-vis .sm2-360btn, +.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn, +.ui360-vis .sm2-360ui.sm2_playing .sm2-360btn { + width:48px; + height:48px; + margin-left:-24px; + margin-top:-24px; + border-radius: none; +} + +.ui360-vis, +.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn, +.ui360-vis .sm2-360btn-default { + background:transparent url(360-button-vis-play.png) no-repeat 50% 50%; + background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABuVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADv7++lpaXr6+uAgIDk5OQzMzPt7e1tbW3n5+dgYGDW1tZNTU10dHQ5OTnw8PCvr6/e3t6JiYlAQEDb29vo6OgrKyuqqqrq6uq4uLjf399AQEDGxsbq6uqAgIDY2Nje3t61tbXp6enU1NTu7u7r6+vl5eXt7e2fn5/n5+fDw8Ph4eHv7+/t7e3CwsLW1tbu7u7b29vw8PDm5uYgICDp6enY2Nji4uLo6Ojm5uakpKTS0tLPz8/h4eHw8PDs7Ozj4+Pa2trg4ODx8fHT09Pk5OTPz8/S0tLBwcGmpqawsLCOjo7h4eHn5+fo6OgAAADY2NjNzc3n5+cAAADd3d3Gxsbu7u7t7e0AAADX19fl5eXi4uLf39/Hx8fn5+fs7Ozg4ODR0dHX19e4uLjv7+/z8/P09PTy8vL19fXv7+/n5+fx8fH29vbs7Ozq6urm5ubo6Ojw8PDu7u7p6enr6+sAAAB/f3/Z2dn39/fh4eGOjo4ODg7t7e3l5eWWlpba2tqjo6NVVVXk5OTe3t65ubnMzMzExMTf39/GxsampqZiYmJNcTiZAAAAbXRSTlMAAQIEAwcFCAb5EdAImAXpB6oIUAoLCfsgZQ0EVrsGEr4ZYQgbsgpUYxikNd/aatQQli+R7rlUUdas6+8I+VaFruoOOV/S8Nq5sWL8UqmKUFsuHyTcrtsJm0z7C49V3NMKkdKXuk7S7oVeVSv7tAAEVwAAAu5JREFUeF6llmVz3DwURmNLsr1pmJmZmZmxzMwsybS8gXJfhl9cKXbHEK+TmZ4P/nDnOXN1NbalHD8CQ7QRGDmhnIQhBDYQnkhheRECSVIQQrLMHookAciUkHhBw1zVwuLShcJIpPDC0uJC1VxDQTaFx1srSvM3DUxU1TRVlWBjM7+0opUrQaupLSnrLK7ELIepwaCYmbiyuLOspJY38eeLykdGxzDhYQfKCmOjI+VFPkMQYF7NZD0l2DgFJrR+siYPegxBzBvqeoQxpgGw8qOuoTz3HGw9udUPCaFZIORhdS5blZOHjXWDBIdABusanb0S4MpqEw4XcNPqCrQFQQTN+XwPQ8CY5jcDUbB3KLdlg6hnQDZacqEgWA3a2rF6Jri9zWohwI6dXXK2QHZ3OqBw0qC7B6vnAPd0sxZMkHr7VNPD34YZgNrXK3EBSgPU9HJ4eIQDDDogQS4ow4QJxy4+MmKs4oYJZFhhggjQuMoKHoHzn3bsQx1HQOTClOkXLP6lviZTtjCjmn7B5g/izqszliBHTB+HDhl3PSJbwnxSS3n45HDkVLXkvCWg5Uws7eHgJ98/uKqxzLI9w3o6oXuwhd+OPNVEet0WtnU9/sWNJfz1u6cY1/VtLghQuRgk/PmBmT7hogJPXo3L8YQed3Nw8PWfuB89Eb8scUGUrl33DfH/N93BGeH6NUnkArh1O5FOuNETp2GR27cAE/iaJu6mz8HdCQnan+i96XQmdgaZ9PQ9+xMVoPJgNhrNhBKNzj5Q+E/AavH4SSz6OZRo7Mlj3oDDp7jyPJoKJfr8CpvAOUrQi6eppJaVZOrpCwTdP1cgr93UjKxoN9dka2KX8ealZtBADO3lG2+e7xRAd7Y0igOg2tYdBKD/CBIBenf/lYGJD2y8uv8OgaBDDkry3v57SlQXhL7f35OlwJOXGUBBl571JykmzCIE02T/s0tIASyf/R6Arr59fcM62G+8fnsVhdwFwq4Ov345Of/15wd0RYY81HHUTQAAAABJRU5ErkJggg==); + *background-image:url(360-button-vis-play.png); + _background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%; + cursor:pointer; +} + +.ui360-vis:hover .sm2-360btn, +.ui360-vis .sm2-360btn-default:hover, +.ui360-vis .sm2-360ui.sm2_paused .sm2-360btn:hover { + background:transparent url(360-button-vis-play-light.png) no-repeat 50% 50%; + _background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%; + cursor:pointer; +} + + +.ui360-vis .sm2-360ui.sm2_playing .sm2-360btn:hover, +.ui360-vis .sm2-360btn-playing:hover { + background:transparent url(360-button-vis-pause-light.png) no-repeat 50% 50%; + _background:transparent url(360-button-vis-pause-light.gif) no-repeat 50% 50%; + cursor:pointer; +} + +.ui360-vis { + /* non-JS / before-loaded state */ + background-position: 21% 50%; + _background:transparent url(360-button-vis-play.gif) no-repeat 21% 50%; /* IE 6-only: special crap GIF */ +} + +.ui360-vis .sm2-360btn-default { + /* real button, post-loaded state */ + _background:transparent url(360-button-vis-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */ +} + +.ui360-vis .sm2-360ui.sm2_dragging .sm2-360btn { + visibility: hidden; +} \ No newline at end of file diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player.css b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player.css new file mode 100755 index 00000000..b74df11c --- /dev/null +++ b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/360player.css @@ -0,0 +1,271 @@ +/* General warning: Beta-ish. Code could be a bit cleaner. */ + +.ui360, /* entire UI */ +.sm2-360ui { /* canvas container */ + position:relative; +} + +.ui360, +.sm2-360ui { + min-width:50px; /* should always be at least this. */ + min-height:50px; +} + +.sm2-360ui { + width:50px; + height:50px; +} + +.ui360, +.ui360 * { + vertical-align:middle; +} + +.sm2-360ui { + position:relative; + display:inline-block; /* firefox 3 et al */ + float:left; /* IE 6+7, firefox 2 needs this, inline-block would work with fx3 and others */ + *display:inline; +/* + clear:left; +*/ +} + +.sm2-360ui.sm2_playing, +.sm2-360ui.sm2_paused { + /* bump on top when active */ + z-index:10; +} + +.ui360 a { /* .sm2_link class added to playable links by SM2 */ + float:left; + display:inline; + position:relative; + color:#000; + text-decoration:none; + left:3px; /* slight spacing on left UI */ + top:18px; /* vertical align */ + text-indent:50px; /* make room for UI at left */ +} + +.ui360 a.sm2_link { /* SM2 has now started */ + text-indent:0px; /* UI now in place. */ +} + +.ui360 a, +.ui360 a:hover, +.ui360 a:focus { + padding:2px; + margin-left:-2px; + margin-top:-2px; +} + +.ui360 a:hover, +.ui360 a:focus { + background:#eee; + border-radius:3px; + outline:none; +} + +.ui360 .sm2-canvas { + position:absolute; + left:0px; + top:0px; +} + +.ui360 .sm2-timing { + position:absolute; + display:block; + left:0px; + top:0px; + width:100%; + height:100%; + margin:0px; + font:11px "helvetica neue",helvetica,monaco,lucida,terminal,monospace; + color:#666; + text-align:center; + line-height:50px; +} + +.ui360 .sm2-timing.alignTweak { + text-indent:1px; /* devious center-alignment tweak for Safari (might break things for others.) */ +} + +.ui360 .sm2-cover { + position:absolute; + left:0px; + top:0px; + width:100%; + height:100%; + z-index:2; + display:none; + background-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==); /* old-skool bug: IE 9 won't catch mouse events otherwise. /smash */ +} + +.ui360 .sm2-360btn { + position:absolute; + display:block; + top:50%; + left:50%; +/* + width:22px; + height:22px; + margin-left:-11px; + margin-top:-11px; +*/ + /* by default, cover whole space. make smaller when playing. */ + width:50px; + height:50px; + margin-left:-25px; + margin-top:-25px; + border-radius: 25px; + cursor:pointer; + z-index:3; +} + +.ui360 .sm2-360data { + display:inline-block; + font-family:helvetica; +} + +.sm2-inline-block .ui360 .sm2-360btn, +.ui360 .sm2-360ui.sm2_playing .sm2-360btn, +.ui360 .sm2-360ui.sm2_paused .sm2-360btn { + /* smaller clickable button, in center */ + width:22px; + height:22px; + margin-left:-11px; + margin-top:-11px; +} + +.ui360 .sm2-360ui.sm2_playing .sm2-cover, +.ui360 .sm2-360ui.sm2_paused .sm2-cover { + display:block; +} + +/* this could be optimized a fair bit. */ + +.ui360, +.ui360 .sm2-360btn-default, +.ui360 .sm2-360ui.sm2_paused .sm2-360btn { + background:transparent url(360-button-play.png) no-reoeat; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAABoUlEQVR42sWVu2oCQRhGU/s8gpVYJeQJNkZSbiH4QNuLlQZS21sJayGYaOEFVFDxNiremj9zig2uzk5YQpKFg8PMd75ZZle9E5Ff4e+Ll8tlQuNoPI2vUcCYOdbIxCmm9F5T0YgNMmS/LebSwWdNa7VayXq9ls1mI9vtVna7nQBj5lgjQxYHN7KY3QkiUbDf7+V4PMrpdArBHGtkyOJc3/n1mVaUUl+F5/PZSrABDi4dpmKH3QkixQEHlw5TsccZmsRCoSD1et1ajkuHqdg/HA5GKZPJCOTzeanVasYMLh2mYsXDIGAoDuG6rlSr1WCdBxrcsTIWazgrQiHS6bSRYJ3XDzeq2O/3+9Ltdm9IpVIhstmslEqlUAY36ii8ZrMpjUbjhmQyKeA4jhSLRWMGN+rhOZ1Oh8ANuVxOyuUy40hwo163RK/XeyPQbrdjgYNr/ILAYDB41Gf1wZnFAQfX+iM0HA5fxuPx+2g0Ej22QoYsDq61mGsymTxMp9NX/Sk2yJDFsRZfXpzXbDZ7WiwW3nw+9zUKGDPHGpkL5V//mn7OJyJZApyzeUS5AAAAAElFTkSuQmCC); + *background-image: url(360-button-play.png); + background-repeat: no-repeat; +} + +.ui360 { + /* + "fake" button shown before SM2 has started, non-JS/non-SM2 case etc. + background image will be removed via JS, in threeSixyPlayer.init() + */ + background-position: 14px 50%; + _background:transparent url(360-button-play.gif) no-repeat 14px 50%; /* IE 6-only: special crap GIF */ +} + +.ui360 .sm2-360btn-default, +.ui360 .sm2-360ui.sm2_paused .sm2-360btn { + background-position:50% 50%; + _background:transparent url(360-button-play.gif) no-repeat 50% 50%; /* IE 6-only: special crap GIF */ +} + +.ui360 .sm2-360btn-default, +.ui360 .sm2-360ui.sm2_paused .sm2-360btn { + cursor:pointer; +} + +.ui360 .sm2-360btn-default:hover, +.ui360 .sm2-360ui.sm2_paused .sm2-360btn:hover { + background:transparent url(360-button-play-light.png) no-repeat 50% 50%; + _background:transparent url(360-button-play.gif) no-repeat 50% 50%; + cursor:pointer; +} + +.ui360 .sm2-360ui.sm2_playing .sm2-360btn:hover, +.ui360 .sm2-360btn-playing:hover { + background:transparent url(360-button-pause-light.png) no-repeat 50% 50%; + _background:transparent url(360-button-pause-light.gif) no-repeat 50% 50%; + cursor:pointer; +} + +.ui360 .sm2-360ui.sm2_playing .sm2-timing { + visibility:visible; +} + +.ui360 .sm2-360ui.sm2_buffering .sm2-timing { + visibility:hidden; +} + +.ui360 .sm2-360ui .sm2-timing, +.ui360 .sm2-360ui .sm2-360btn:hover + .sm2-timing, +.ui360 .sm2-360ui.sm2_paused .sm2-timing { + visibility:hidden; +} + +.ui360 .sm2-360ui.sm2_dragging .sm2-timing, +.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover + .sm2-timing { + /* paused + dragging */ + visibility:visible; +} + +.ui360 .sm2-360ui.sm2_playing .sm2-360btn, +.ui360 .sm2-360ui.sm2_dragging .sm2-360btn, +.ui360 .sm2-360ui.sm2_dragging .sm2-360btn:hover, +.ui360 .sm2-360ui.sm2_dragging .sm2-360btn-playing:hover { + /* don't let pause button show on hover when dragging (or paused and dragging) */ + background:transparent; + cursor:auto; +} + +.ui360 .sm2-360ui.sm2_buffering .sm2-360btn, +.ui360 .sm2-360ui.sm2_buffering .sm2-360btn:hover { + background:transparent url(icon_loading_spinner.gif) no-repeat 50% 50%; + opacity:0.5; + visibility:visible; +} + +/* inline list style */ + +.sm2-inline-list .ui360, +.sm2-inline-block .ui360 { + position:relative; + display:inline-block; + float:left; + _display:inline; + margin-bottom:-15px; +} + +.sm2-inline-list .ui360 { + /* inline player: minor tweak, tighten spacing */ + margin-right:-2px; +} + +.sm2-inline-block .ui360 { + margin-right:8px; +} + +.sm2-inline-list .ui360 a { + display:none; +} + +/* annotations */ + +ul.ui360playlist { + list-style-type:none; +} + +ul.ui360playlist, +ul.ui360playlist li { + margin:0px; + padding:0px; +} + +div.ui360 div.metadata { + display:none; +} + +div.ui360 a span.metadata, +div.ui360 a span.metadata * { + /* name of track, note etc. */ + vertical-align:baseline; +} \ No newline at end of file diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization-basic.html b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization-basic.html new file mode 100755 index 00000000..352856b4 --- /dev/null +++ b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization-basic.html @@ -0,0 +1,132 @@ + + +
+Canvas-based UI with visualization options. Note: No EQ/spectrum support for IE < 9 (too slow.) Data not implemented in HTML5.
+ + + ++ SoundManager 2 project page (not an MP3 link) +
+ + + + + diff --git a/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization.html b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization.html new file mode 100755 index 00000000..1f3d6e2c --- /dev/null +++ b/app/assets/javascripts/librariesForAllPages/soundmanagerv297a-20131201/demo/360-player/canvas-visualization.html @@ -0,0 +1,359 @@ + + + +Canvas-based UI with visualization options. Note: Spectrum/EQ visualizations disabled for IE < 9 (too slow.) Data is not implemented under HTML5.
+You can also show FPS or customize the UI, or see the hi-fi version. Check the basic template for a minimal code example; also see the default 360° UI.
+ + + + + + + +Artist thank-yous: "Graffiti Sex" courtesy of The Fugitives. "Blue Belle Lament" courtesy of Adrian Glynn. "I Tried" and "People Asking" courtesy of SonReal.
+ +56K Modem sound (Creative Commons license) via dialup.mp3, from freesound.org user Jlew.
+ + ++ SoundManager 2 project page (not an MP3 link) +
+ + + +Canvas-based UI. Load progress, seek, play/pause etc. Also see 360° UI visualization demo.
+ +Alternate style: inline
+ + + +The script looks for a container element matching div.ui360
, and then the first link inside of it.
<div class="ui360">
+ <a href="/path/to/an.mp3">play "an.mp3"</a>
+</div>
+
+ When the 360 player script loads, it adds a UI
template to the block, prepending it in front of the MP3 link:
<div class="ui360">
+ <-- dynamically-inserted block -->
+ <div class="ui">
+ <canvas class="sm2-canvas"></canvas>
+ <span class="sm2-360btn"></span>
+ <div class="sm2-timing"></div>
+ <div class="sm2-cover"></div>
+ </div>
+ <-- /UI -->
+ <a href="/path/to/an.mp3">
+</div>
+
+The player's default 50x50-pixel canvas is defined both within JavaScript and CSS. For an example with different values, see this larger version.
+ +threeSixtyPlayer.config = {
+ playNext: false, // stop after one sound, or play through list until end
+ autoPlay: false, // start playing the first sound right away
+ allowMultiple: true, // let many sounds play at once (false = one at a time)
+ loadRingColor: '#ccc', // amount of sound which has loaded
+ playRingColor: '#000', // amount of sound which has played
+ backgroundRingColor: '#eee', // "default" color shown underneath everything else
+ animDuration: 500,
+ animTransition: Animator.tx.bouncy // http://www.berniecode.com/writing/animator.html
+}
+
+The CSS for the canvas UI block is a bit ugly, but JavaScript reads the width of the .sm2-360ui
element in the DOM as set by CSS and uses that to later draw and update the canvas element while playing.
.ui360,
+.sm2-360ui {
+ /* size of the container for the circle, etc. */
+ width:50px;
+ height:50px;
+}
+
+
+This demo includes use of Bernie's Better Animation Class (Apache licensed) for some animation effects.
+Also, some loader/spinner icons from ajaxload.info are used for showing loading/buffering states.
+ ++ SoundManager 2 project page (not an MP3 link) +
+ + ++ Click + drag for fun. +
+ +SoundManager 2 now incorporates a "high performance" mode, which has been shown to noticeably improve timing and frequency of flash callbacks. This is important for timing, reducing delay between a JS call and the sound being played, etc.
+ +To reduce audio delay and timing issues from slow JS/Flash communication, SM2 will try to ensure that the flash movie is visible on screen at all times. If hidden or otherwise off-screen, Flash will be given lower priority and thus JS/flash "lag" (ie., delay) will be introduced when trying to play audio "in sync."
+ +Generally, positioning the flash movie using position:fixed and bottom/left or bottom/right 0px is the less-intrusive option.
+ ++ Throw from mouse +
++ + +
+ + +Sound source: "Acclivity", freesound.org
+ +Click and drag to draw.. Noisily.
+ + +Click and drag for fun.
+ +External demo: A Noisy DOM - part of a Yahoo! User Interface blog post, Enhancing YUI-based Apps with Audio.
+ + + +Wondering where to start? This page has inline executable code examples using the SoundManager 2 API.
+ +If you're wondering how to include SM2 in your page, the basic template will get you started.
+ +SM2's API features and behaviour can vary somewhat depending on client support, so it can be helpful to test under different configurations. The following are different configuration defaults for SoundManager 2. Clicking will change URL parameters and reload the page, causing SM2 to start up with the new options applied. Look at JS console output for details.
+ +HTML5 options: HTML5-only mode (API default, where supported) | HTML5 + fast polling | HTML5 + prefer flash for MP3/MP4 formats | disable HTML5
+ +Flash options: Flash 8 | Flash 9 (normal) | Flash 9 + highPerformance + fastPolling modes (higher JS callback frequency)
+ +soundManager.setup()
methodIn order to configure SoundManager 2 for use, you must first call the setup()
method. The url
property and an onready
function callback are commonly used together here.
soundManager.setup({
+
+ // where to find the SWF files, if needed
+ url: '/path/to/swf-directory/',
+
+ onready: function() {
+ // SM2 has loaded, API ready to use e.g., createSound() etc.
+ },
+
+ ontimeout: function() {
+ // Uh-oh. No HTML5 support, SWF missing, Flash blocked or other issue
+ }
+
+});
+
+
+SoundManager processes the onready
and ontimeout
queue in the order items were added. You can also add callbacks via soundManager.onready()
and soundManager.ontimeout()
, respectively. If you add listeners for these events after SM2 has loaded, your callback will be fired immediately.
Keep in mind SoundManager's core methods (createSound, etc.) will not be available until soundManager's onready()
event fires. The initialization time for SM2 can vary across browsers/platforms, and should effectively be assumed to be "asynchronous." Because of this, it is recommended you write your code to handle onready
being fired either before or after window.onload().
If you wish to have SM2 always wait for window.onload() before calling onready()
or ontimeout()
, you can pass waitForWindowLoad: true
to soundManager.setup()
.
SoundManager 2 has debug mode enabled by default and will write to agents supporting console.log-style debugging, and/or a custom <div> element in the absence of a console.
+To disable debug output, pass debugMode: false
to soundManager.setup()
.
Alternately, you may use the no-debug, minified version of the SM2 javascript library (which has internal debug code removed, and will silently return false.)
+ +var mySound = soundManager.createSound({
+ url: '../mpc/audio/CHINA_1.mp3'
+});
+mySound.play();
+
+ Creates a new sound object with a url
, and calls its play()
method.
Note: It is recommended you make one sound object per url
, generally speaking, that you wish to play. Expressed another way: "Reduce, reuse, recycle."
id
soundManager.createSound({
+ id: 'mySound2',
+ url: '../mpc/audio/CHINA_1.mp3'
+});
+soundManager.play('mySound2');
+
+
+ Creates a new sound object with the given id
, and then calls soundManager.play()
, specifying the id
of the desired sound.
If omitted, an id
will be automatically generated. If a sound object with the provided id
already exists, the existing object will be returned.
Cases for providing your own id
The id
parameter is optional, but makes sound objects easier to look up. It's also helpful when the object returned from createSound()
wasn't stored, or isn't in scope. Calling soundManager.getSoundById('mySound2')
will return the matching sound object, or null
if none is found.
soundManager.play()
and related convenience methods take an id
string, and call the method on the given sound object. Thus, soundManager.play('foo')
is functionally equivalent to soundManager.getSoundById('foo').play()
Reduce, reuse, recycle
+ +Unless you need to track separate instances of a sound playing simultaneously, it's best to create and re-use one sound object for each unique sound resource (URL) you have. If you want to play a single sound multiple times, layered on top of itself in an overlapping/chorus style, look at the multiShot
sound option (Flash 9 + HTML5 only).
onfinish
event handler + play with volume argumentvar demo2Sound = soundManager.createSound({
+ url: '../mpc/audio/CHINA_1.mp3',
+ onfinish: function() {
+ soundManager._writeDebug(this.id + ' finished playing');
+ }
+});
+demo2Sound.play({
+ volume: 50
+});
+
+
+ (creates, then plays a new sound - a function is called when the sound finishes playing)
+ +onload
event handlersoundManager.createSound({
+ url: '../mpc/audio/CHINA_1.mp3',
+ // callback for when the sound has loaded
+ onload: function() {
+ soundManager._writeDebug(this.id + ' loaded');
+ this.play();
+ }
+}).load();
+
+ This creates and loads a sound, using the onload
event callback to begin playback once the sound has loaded.
whileloading
event handlersoundManager.createSound({
+ url: 'http://freshly-ground.com/data/audio/mpc/20060826%20-%20Armstrong.mp3?rnd=' + Math.random(),
+ // begin loading right away
+ autoLoad: true,
+ whileloading: function() {
+ soundManager._writeDebug(this.id + ': loading ' + this.bytesLoaded + ' / ' + this.bytesTotal);
+ }
+});
+
+ This creates and auto-loads a sound, showing load progress where applicable.
+ +id
soundManager.play('aDrumSound');
+
+ This plays an existing sound made earlier using soundManager.createSound()
, specifying an id
parameter of aDrumSound
.
Alternately, you can reference a sound by id
and call methods directly on the object itself - for example, soundManager.getSoundById('aDrumSound').play();
onfinish
, with multiShot
(Flash 9 + HTML5 only)soundManager.play('aDrumSound', {
+ // allow onfinish() to fire for each "shot", instead of only last shot
+ multiShotEvents: true,
+ onfinish: function() {
+ soundManager.play('aCymbalSound');
+ }
+});
+
+ This will play an existing sound (created in-page), and uses the onfinish()
callback to play a second, pre-existing sound.
Also note that the button can be clicked multiple times, and the sound will be "layered" as multiShot is enabled for both of these sounds when using Flash 9 or HTML5. An onfinish event will also fire as each sound finishes.
+Bug/behaviour note: Whenever "play" is called on a SMSound object, any parameters passed in will apply to all currently-playing instances of the sound if multiShot is allowed. For example, the onfinish handler from demo 4a will apply to demo 3 if 4a is started while 3 is still playing.
+* Multishot is Flash 9+ and HTML5 only.
+ +onfinish()
soundManager.createSound({
+ id: 'aBassDrum',
+ url: '../mpc/audio/AMB_BD_1.mp3',
+ multiShot: false,
+ // when the first sound finishes...
+ onfinish: function() {
+ // create and play the second.
+ soundManager.createSound({
+ id: 'aRimSound',
+ url: '../mpc/audio/AMB_RIM1.mp3'
+ }).play();
+ }
+});
+soundManager.play('aBassDrum');
+
+ This will create and play a new sound, using the onfinish()
callback to create and play a second, new sound.
Note that createSound()
will return an existing sound object if one already exists with the given id
. You can test this by running the demo more than once.
onfinish()
-based)var s = soundManager.createSound({
+ id: 'hhCymbal',
+ url: '../mpc/audio/AMB_HHOP.mp3'
+});
+
+function loopSound(sound) {
+ sound.play({
+ onfinish: function() {
+ loopSound(sound);
+ }
+ });
+}
+
+loopSound(s);
+
+
+ |
+Note that there are issues with seamlessly-looping sounds, it is "close, but not perfect" with Flash 8/9 at this point.
+ +loops
parameter method)var s = soundManager.createSound({
+ id: 'hhCymbal',
+ url: '../mpc/audio/AMB_HHOP.mp3'
+});
+
+s.play({
+ loops: 3
+});
+
+
+ |
+Looping is possible as shown above using Flash 9. With flash 8, the sound must be preloaded before looping can begin - eg. autoLoad: true, onload: function() { this.play{loops: 3} }
. For tighter looping, see See Seamless Looping MP3 in Flash for further details.
HTML5 support note: Native HTML5 looping is infinite when enabled, and does not support arbitrary loop counts. For now, consider using your own function with onfinish()
-> play()
if you want to loop a sound a certain number of times. Refer to the above onfinish()
example for a basic idea.
onPosition()
var s = soundManager.getSoundById('aCymbalSound'); // existing sound object
+
+// register some listeners (only do this once, they will work for subsequent plays)
+
+if (typeof addedListeners === 'undefined') {
+ addedListeners = true;
+
+ s.onPosition(500, function(eventPosition) { // fire at 0.5 seconds
+ soundManager._writeDebug('Sound ' + this.id + ' has reached position ' + eventPosition);
+ });
+
+ s.onPosition(1000, function(eventPosition) { // fire at 1 second
+ soundManager._writeDebug('Sound ' + this.id + ' has reached position ' + eventPosition);
+ });
+}
+
+s.play({
+ multiShot: false,
+ whileplaying: function() {
+ // demo only: show sound position while playing, for context
+ soundManager._writeDebug('position = ' + this.position);
+ }
+});
+
+
+
+onPosition()
allows you to add an event listener for a given time (in miliseconds, watching the position property); the event fires when that time has been reached while a sound is playing.
Note that for multiShot cases, the listeners will only fire for the original (first) shot because its position is the only one that is tracked within Flash.
+ +onPosition()
and clearOnPosition()
var s = soundManager.getSoundById('aCymbalSound'); // existing sound object
+
+// clear listeners from prior demo, if they were assigned...
+
+if (typeof addedListeners !== 'undefined') {
+
+ soundManager._writeDebug('Removing previous demo listeners...');
+ s.clearOnPosition(500); // remove 500 msec listener
+ s.clearOnPosition(1000); // remove 1000 msec listener
+
+}
+
+s.onPosition(750, function(eventPosition) { // fire at 0.75 seconds
+
+ soundManager._writeDebug('Sound ' + this.id + ' has reached position ' + eventPosition);
+ // and now, remove the listener using the eventPosition specified in this callback
+ // so next time the sound plays, this listener will not fire
+ this.clearOnPosition(eventPosition);
+
+});
+
+s.play({
+ whileplaying: function() {
+ // demo only: show sound position while playing, for context
+ soundManager._writeDebug('position = ' + this.position);
+ },
+ onfinish: function() {
+ // when the sound finishes, play it once more to show that the listener does not fire.
+ soundManager._writeDebug('Playing once more, onPosition() should not fire');
+ this.play({
+ onfinish: function() {
+ soundManager._writeDebug('"' + this.id + '" finished.');
+ }
+ });
+ }
+});
+
+
+
+When onPosition()
is used, a listener is added and a callback is fired when the sound reaches the desired position. To remove the listener, clearOnPosition()
is called using the same position value.
from:
and to:
parametersvar spliceDemo = soundManager.createSound({
+ id: 'spliceSound',
+ url: '../mpc/audio/AMB_HHOP.mp3'
+});
+
+// optional: stop before re-starting sound (covers overlapping play attempts)
+spliceDemo.stop();
+
+spliceDemo.play({
+ // start position
+ from: 500,
+ // end position
+ to: 1200,
+ onstop: function() {
+ soundManager._writeDebug('sound stopped at position ' + this.position);
+ // note that the "to" target may be over-shot by 200+ msec, depending on polling and other factors.
+ }
+});
+
+
+ |
+By specifying "from" and "to" parameters to methods like play() and createSound(), you may play a sample (or segment) of audio from a larger file. An audio "sprite" of one file with many sounds is one way to think of this. Given timing accuracy of the "to" target may vary a lot, it is safest to have perhaps 500-msec gaps of silence between distinct sounds to ensure that no accidental overlaps occur.
+To tighten the accuracy of the "to" timing, try using soundManager.useHighPerformance.
+If HTML5 audio is being used, the sound should begin playing once a "canplay" event fires (after a connection has established), and the sound will then seek to the correct start position. When using flash, the whole audio file will be loaded before playback can begin.
+Given limitations, Flash 9's multiShot (chorusing) mode does not apply here. If you wish to trigger a sound numerous times, call stop() before play() to reset the sound each time, or make multiple sound objects that reuse the same sprite.
+ +from:
and to:
parameters+ +
+ +Portions of a sound can be played by specifying from and to when calling play()
. This can be useful for performance, i.e., having an "audio sprite" that loads in a single HTTP request.
var fhDemo = soundManager.createSound({
+ url: 'http://freshly-ground.com/data/audio/sm2/fitter-happier-64kbps.mp3'
+});
+
+function playFromTo(nFrom, nTo) {
+ fhDemo.stop(); // optional: stop before re-starting sound (covers overlapping play attempts)
+ fhDemo.play({
+ from: nFrom,
+ to: nTo,
+ onstop: function() {
+ soundManager._writeDebug('sound stopped at position ' + this.position);
+ // note that the "to" target may be over-shot by 200+ msec, depending on polling and other factors.
+ }
+ });
+}
+
+function fitterHappier() {
+ playFromTo(128, 2100);
+}
+
+function moreProductive() {
+ playFromTo(2500, 3850);
+}
+
+function comfortable() {
+ playFromTo(4275, 5200);
+}
+
+function notDrinkingTooMuch() {
+ playFromTo(5500, 7250);
+}
+
+function regularExerciseAtTheGymThreeDaysAWeek() {
+ playFromTo(7500, 11500);
+}
+
+function atEase() {
+ // interesting edge case: flash may cut off sound near end.
+ // workarounds: use play({position:x}), or specify "to" time > duration eg. 99999.
+ playFromTo(11600, 99999);
+}
+
+// demo-specific hack: assign to the window object, so demo buttons work
+window.fitterHappier = fitterHappier;
+window.moreProductive = moreProductive;
+window.comfortable = comfortable;
+window.notDrinkingTooMuch = notDrinkingTooMuch;
+window.regularExerciseAtTheGymThreeDaysAWeek = regularExerciseAtTheGymThreeDaysAWeek;
+window.atEase = atEase;
+
+
+
+
+ | | | | |
+
+// predefined/preloaded sound
+var sound = soundManager.getSoundById('chinaCymbal');
+
+// volume at 85%
+sound.setVolume(85);
+
+// 0.25 seconds into sound
+sound.setPosition(250);
+
+// pan 75% to the left
+sound.setPan(-75);
+
+// begin playback with new settings
+sound.play();
+
+
+This will set the position and pan of an existing, pre-loaded sound, then play it. Where applicable, these settings become the new defaults for the sound.
+ +play()
with sound optionsvar sound = soundManager.getSoundById('chinaCymbal');
+sound.play({
+ volume: 100,
+ position: 0,
+ pan: 75
+});
+This is an elegant way of playing a sound with specific parameters "just one time", overriding the defaults applied when the sound was created.
+ +Note that if planning to layer sounds with multiShot (Flash 9 only), this variant method will give best results as each new "channel" is started with parameters.
+ +If not passed a sound ID, soundManager.mute() will mute all existing and newly-created sounds. soundManager.unmute() can also be passed a sound ID, and performs the inverse either on a single sound or all sounds.
+In this demo, all sounds are globally muted and unmuted a few times. Different parameters are used to help audibly separate the sounds.
+soundManager.mute(); // mute all sounds
+
+soundManager.createSound({
+ id: '880hz',
+ url: '../_mp3/880hz.mp3',
+ autoLoad: true,
+ onload: function() {
+ // soundManager.mute(); // mute all sounds
+ // play (muted) cymbal sound..
+ this.play({
+ volume: 75, // volume for when un-muted
+ pan: -75, // mostly on left channel
+ // .. and clean-up afterwards
+ onfinish: function() {
+ this.destruct();
+ }
+ });
+
+ this.setVolume(25); // new volume for when un-muted..
+
+ soundManager.play('s440hz', {
+ pan: 75,
+ onfinish: function() {
+ document.getElementById('btn-d5b').disabled = false;
+ }
+ });
+
+ // once playing, toggle all sounds some more
+ setTimeout(soundManager.unmute, 500);
+ setTimeout(soundManager.mute, 1000);
+ setTimeout(soundManager.unmute, 1500);
+ setTimeout(soundManager.mute, 2000);
+ setTimeout(soundManager.unmute, 2500);
+ }
+});
+
+
+
+soundManager.createSound({
+ id: '880hz',
+ url: '../_mp3/880hz.mp3',
+ autoLoad: true,
+ onload: function() {
+ soundManager.mute('880hz'); // mute this - alternately, this.mute() would work here
+ soundManager.play('s440hz', { // play another sound to demo muting
+ onfinish: function() {
+ document.getElementById('btn-d5c').disabled = false;
+ }
+ });
+
+ // play 880hz (muted)..
+ this.play({
+ volume: 75,
+ // .. and clean-up afterwards
+ onfinish: function() {
+ this.destruct();
+ }
+ });
+
+ this.setVolume(50); // still muted, however..
+
+ // mute/unmute china cymbal some more
+ // mute sound calls: soundManager.mute('880hz'), or soundManager.getSoundById('880hz').mute();
+ setTimeout(this.unmute, 250);
+ setTimeout(this.mute, 500);
+ setTimeout(this.unmute, 750);
+ setTimeout(this.mute, 1000);
+ setTimeout(this.unmute, 1250);
+ }
+});
+
+
+
+var foo = soundManager.createSound({
+ id: 'fooSound',
+ url: '../mpc/audio/AMB_BD_1.mp3'
+});
+
+// soundManager.play('fooSound');
+
+// (Some time later on...)
+// soundManager.unload('fooSound'); - release the loaded MP3
+// soundManager.destroySound('fooSound'); - destroy the sound, freeing up memory etc. Also calls unload().
+
+// Alternate (demo) approach, call methods directly on sound object itself:
+foo.play({
+ onfinish: function() {
+ // once sound has loaded and played, unload and destroy it.
+ this.destruct(); // will also try to unload before destroying.
+ }
+});
+
+
+
+var preload = soundManager.createSound({
+ id: 'preloadSound',
+ url: '../mpc/audio/AMB_HHOP.mp3'
+});
+
+// load the sound ahead of time
+preload.load({
+ // and start playing it at onload
+ onload: function() {
+ this.play();
+ }
+});
+
+
+
+var bad = soundManager.createSound({
+ id: 'badSound',
+ url: 'badurl.mp3',
+ onload: function(bSuccess) {
+ soundManager._writeDebug('sound '+(bSuccess?'loaded!': 'did NOT load.'));
+ }
+});
+bad.play();
+
+
+
+var s = soundManager.createSound({
+ url: '../mpc/audio/AMB_HHOP.mp3'
+});
+s.play();
+s.destruct();
+
+
+
+The Flash 9 version seems to resume the sound 1 msec earlier than it should, perhaps related to the timing/delay issue most noticeable on Windows.
+var count = 0;
+var pos = -1;
+var s = soundManager.createSound({
+ url: '../mpc/audio/CHINA_1.mp3',
+ whileplaying: function() {
+ if (count == 0) {
+ if (this.position > 1000) {
+ this.pause();
+ pos = this.position;
+ count++;
+ this.resume();
+ }
+ } else if (count == 1) {
+ soundManager._writeDebug('old position: ' + pos);
+ soundManager._writeDebug('new position: ' + this.position);
+ // See that this.position is less than pos!
+ count++;
+ }
+ },
+ onfinish: function() {
+ this.destruct();
+ }
+});
+s.play();
+
+
+whileplaying()
event assignmentNote that when using the Flash 9 version of SM2 with Flash 9 and 10 plugins, flash/OS-related delay conditions may result in the position
property being less than the duration
property, even by the end of the sound.
var foo = soundManager.createSound({
+ url: '../mpc/audio/CRASH_1.mp3'
+});
+foo.options.whileplaying = function() {
+ soundManager._writeDebug('whileplaying(): '+this.position+' / '+this.duration);
+}
+foo.play();
+
+// note: assign .options before calling .play(), as that "bakes" the options into a play instance object.
+// the below "late" event handler assignment will have no effect on the already-playing instance.
+foo.options.onfinish = function() { soundManager._writeDebug(this.id + ' stopped.'); }
+
+
+
+To work around a known "chipmunk" sampling rate issue with 48 KHz MP3s in Flash, one can apparently load a sound using Flash 9 with stream = false, and then call play() once the sound has fully-loaded. Exactly why this works is not known.
+var fortyeight = soundManager.createSound({
+ url: 'http://freshly-ground.com/data/audio/48khz-test.mp3'
+});
+
+if (!fortyeight.loaded) {
+ // first time loading/playing
+ fortyeight.load({
+ stream: false,
+ onload: function() {
+ // sound has fully-loaded
+ this.play();
+ }
+ });
+} else {
+ // sound has already loaded
+ fortyeight.play();
+}
+
+
+
+autoLoad:true
+ play()
testcaseBug testcase (Flash 8 version-specific): creating a sound with autoLoad:true and immediately calling play() does not work.
+var autoLoadTest = soundManager.createSound({
+ id: 'autoLoadTest',
+ url: getRandomMP3URL(),
+ onload: function() {
+ soundManager._writeDebug(this.id + ' loaded.');
+ },
+ onplay: function() {
+ soundManager._writeDebug('Starting sound: '+this.id);
+ },
+ autoPlay: false,
+ autoLoad: true,
+ stream: true
+ });
+ // autoLoadTest.play(); // sound will not start
+ setTimeout(autoLoadTest.play,1000); // may work with a delay?
+
+Under Flash 8, this case does not work as expected. Even with the delay, the sound does not begin playing as soon as expected - sometimes it fires after the sound loads, in fact. For this reason, avoid using autoLoad:true
if you intend to play the sound shortly after creating it when using Flash 8.
autoPlay
+ onfinish()
testcaseBug testcase (Flash 8 version-specific): onfinish() does not fire with autoPlay:true
+var sound = soundManager.createSound({
+ id: 'demo14',
+ url: '../mpc/audio/AMB_SN13.mp3',
+ onfinish: function() {
+ soundManager._writeDebug(this.id + ' finished (now destroying)');
+ // destroy this sound
+ this.destruct();
+ },
+ autoPlay: true,
+ multiShot: false
+});
+
+
+
+onstop()
-> unload()
testcaseBug testcase: unload() from onstop() does not work
+var sound16 = soundManager.createSound({
+ id: 'demo15',
+ url: getRandomMP3URL(),
+ onstop: function() {
+ soundManager.unload(this.id);
+ },
+ onload: function() {
+ soundManager._writeDebug('loaded');
+ }
+});
+sound15.play();
+setTimeout(sound15.stop, 1500);
+
+
+
+Reporting the isBuffering property of a SMSound object
+if (soundManager.flashVersion != 8) {
+ var sound16 = soundManager.createSound({
+ id: 'demo16',
+ url: getRandomMP3URL(),
+ onbufferchange: function() {
+ soundManager._writeDebug('Buffering '+(this.isBuffering?'started': 'stopped')+'.');
+ },
+ onload: function() {
+ soundManager._writeDebug(this.id + ' loaded.');
+ }
+ });
+ sound16.play();
+}
+
+
+
+Subject to browser support, a data: URI should work when provided to a native HTML5 Audio()
instance.
You should not use this unless you know what you're doing and are willing to rely only on HTML5 support.
+Additionally, data: URIs appear not to work on mobile devices (iOS: iPad, iPhone in particular.)
+IE 9 + 10 do not support WAV under HTML5 Audio()
. In addition to being the only major browser lacking .WAV support, irony is not lost on the fact that MSFT co-created the WAV/RIFF spec with IBM. (See yonder.)
if (soundManager.html5) {
+ soundManager.createSound({
+ // explicit type, SM2 doesn't detect MIME type in data: URIs yet
+ type: 'audio/wav',
+ // view source (or console) for the full URI.
+ url: getWaveDataURI()
+ }).play();
+}
+See your JS console for live debug/log output.
+ +soundManager.setup()
(url, onready etc.)soundManager.play()
play()
with sound optionsonload()
eventwhileloading()
eventonfinish()
onfinish()
CreateSound()
and play()
with eventsmultiShotEvents
loops
onbufferchange()
, isBuffering
onPosition()
onPosition()
+ clearOnPosition()
from
+ to
from
and to