working on the music controls

This commit is contained in:
lone-cloud 2015-08-27 01:16:18 -07:00
parent eb518c4898
commit b2eb2ede21
22 changed files with 534 additions and 305 deletions

View file

@ -2,7 +2,8 @@
"predef": [ "predef": [
"document", "document",
"window", "window",
"-Promise" "-Promise",
"Dancer"
], ],
"browser": true, "browser": true,
"boss": true, "boss": true,

View file

@ -8,7 +8,8 @@ export default Em.Component.extend({
updateGroupsData: true, updateGroupsData: true,
groupsData: null, groupsData: null,
lightsData: null, lightsData: null,
activeLights: Em.A(),
activeLights: [],
apiURL: function(){ apiURL: function(){
return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername'); return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername');
@ -41,7 +42,7 @@ export default Em.Component.extend({
}, },
tabList: ["Lights", "Scenes", "Music"], tabList: ["Lights", "Scenes", "Music"],
selectedTab: 0, selectedTab: 2,
tabData: function(){ tabData: function(){
var tabData = [], selectedTab = this.get('selectedTab'); var tabData = [], selectedTab = this.get('selectedTab');
@ -73,16 +74,6 @@ export default Em.Component.extend({
Em.$.get(this.get('apiURL') + '/lights', function (result, status) { Em.$.get(this.get('apiURL') + '/lights', function (result, status) {
if (status === 'success' && JSON.stringify(self.get('lightsData')) !== JSON.stringify(result) ) { if (status === 'success' && JSON.stringify(self.get('lightsData')) !== JSON.stringify(result) ) {
if(self.get('activeLights').length === 0){
var ids = [];
for (let key in result) {
if(result.hasOwnProperty(key) && result[key].state.reachable){
ids.push(key);
}
}
self.set('activeLights', ids);
}
self.set('lightsData', result); self.set('lightsData', result);
} else if(status !== 'success') { } else if(status !== 'success') {
// something went terribly wrong ( user got unauthenticated? ) and we'll need to start all over // something went terribly wrong ( user got unauthenticated? ) and we'll need to start all over

View file

@ -5,7 +5,7 @@ export default Em.Component.extend({
tagName: null, tagName: null,
groupIdSelection: '0', groupIdSelection: null,
actions: { actions: {
selectGroup: function(selection){ selectGroup: function(selection){
@ -58,8 +58,20 @@ export default Em.Component.extend({
} }
}); });
if(!Em.isNone(groupIdSelection)){ localStorage.setItem('huegasm.selectedGroup', groupIdSelection);
if(!Em.isNone(groupIdSelection) && !Em.isEmpty(lights)){
this.set('activeLights', lights); this.set('activeLights', lights);
} }
}.observes('groupIdSelection') }.observes('groupIdSelection', 'groupsArrData'),
didInsertElement: function(){
var selectGroup = '0', storageItem = localStorage.getItem('huegasm.selectedGroup');
if(storageItem){
selectGroup = storageItem;
}
this.set('groupIdSelection', selectGroup);
}
}); });

View file

@ -4,13 +4,16 @@ export default Em.Component.extend({
classNames: ['innerControlFrame'], classNames: ['innerControlFrame'],
activeLights: [],
lightsData: null,
lightsDataIntervalHandle: null, lightsDataIntervalHandle: null,
modalData: null, modalData: null,
isShowingLightsModal: false, isShowingLightsModal: false,
isShowingAddGroupsModal: false, isShowingAddGroupsModal: false,
actions: { actions: {
selectLight: function(id, data){ clickLight: function(id, data){
if(this.get('isShowingLightsModal')){ if(this.get('isShowingLightsModal')){
this.set('modalData', {data:data, id:id}); this.set('modalData', {data:data, id:id});
} }

View file

@ -1,13 +1,54 @@
import Em from 'ember'; import Em from 'ember';
export default Em.Component.extend({ export default Em.Component.extend({
didInsertElement: function () {
var dancer = new Dancer(),
self = this,
briOff = function(i){
Em.$.ajax(self.get('apiURL') + '/lights/' + i + '/state', {
data: JSON.stringify({'on': 1, 'transitiontime': 0}),
contentType: 'application/json',
type: 'PUT'
});
},
kick = dancer.createKick({
threshold : 0.45,
frequency: [0, 3],
onKick: function ( mag ) {
apiURL: null, if(self.get('paused') === false){
for(let i=1; i <= 1; i++){
Em.$.ajax(self.get('apiURL') + '/lights/' + i + '/state', {
data: JSON.stringify({'bri': 254, 'transitiontime': 0}),
contentType: 'application/json',
type: 'PUT'
});
setTimeout(briOff, 50, i);
}
self.set('paused', true);
lightsData: null, setTimeout(function(){ self.set('paused', false); }, 150);
activeLights: null,
console.log('Kick at ' + mag);
}
}
}),
a = new Audio();
kick.on();
audio_file.onchange = function(){
var files = this.files;
var file = URL.createObjectURL(files[0]);
a.src = file;
dancer.load(a);
dancer.play();
};
},
paused: false
}); });

View file

@ -0,0 +1,27 @@
import Em from 'ember';
export default Em.Component.extend({
classNames: ['container-fluid'],
actions: {
play: function(){
},
next : function(){
},
previous: function(){
}
},
status: null,
playButton: function(){
if(this.get('status') === 'paused'){
return 'pause';
} else {
return 'play-arrow';
}
}.property('status')
});

View file

@ -7,6 +7,7 @@ export default Em.Component.extend({
init: function(){ init: function(){
this._super(); this._super();
if(localStorage.getItem('huegasm.bridgeIp')){ if(localStorage.getItem('huegasm.bridgeIp')){
this.set('bridgeIp', localStorage.getItem('huegasm.bridgeIp')); this.set('bridgeIp', localStorage.getItem('huegasm.bridgeIp'));
} }

View file

@ -40,7 +40,13 @@ export default Em.Component.extend({
selectedLights: [], selectedLights: [],
onIsShowingAddGroupsModalChange: function(){ onIsShowingAddGroupsModalChange: function(){
this.set('selectedLights', []); if(this.get('isShowingAddGroupsModal')){
}
this.setProperties({
selectedLights: [],
groupName: null
});
}.observes('isShowingAddGroupsModal'), }.observes('isShowingAddGroupsModal'),
saveDisabled: function(){ saveDisabled: function(){

View file

@ -6,7 +6,9 @@ export default Em.Component.extend({
this.sendAction(); this.sendAction();
}, },
delete: function(){ delete: function(){
Em.$.ajax(this.get('apiURL') + '/groups/' + this.get('groupId'), { var groupId = this.get('groupId');
Em.$.ajax(this.get('apiURL') + '/groups/' + groupId, {
contentType: 'application/json', contentType: 'application/json',
type: 'DELETE' type: 'DELETE'
}); });
@ -18,6 +20,10 @@ export default Em.Component.extend({
} }
} }
if(groupId === this.get('groupIdSelection')){
this.set('groupIdSelection', '0');
}
this.setProperties({ this.setProperties({
updateGroupsData: true, updateGroupsData: true,
groupsData: newGroupsData groupsData: newGroupsData

View file

@ -9,6 +9,9 @@
{{content-for 'head'}} {{content-for 'head'}}
<link href='http://fonts.googleapis.com/css?family=Slabo+27px' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="assets/images/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="assets/vendor.css"> <link rel="stylesheet" href="assets/vendor.css">

View file

@ -6,6 +6,7 @@ var Router = Ember.Router.extend({
}); });
Router.map(function() { Router.map(function() {
this.route('404', {path:'/*path'});
}); });
export default Router; export default Router;

View file

@ -3,10 +3,7 @@
@import 'ember-modal-dialog/ember-modal-structure'; @import 'ember-modal-dialog/ember-modal-structure';
@import 'ember-modal-dialog/ember-modal-appearance'; @import 'ember-modal-dialog/ember-modal-appearance';
body, html { // BRIDGE FINDER
height: 100%;
}
#pressButtonBridgeImg { #pressButtonBridgeImg {
width: 200px; width: 200px;
margin: 0 auto 0 auto; margin: 0 auto 0 auto;
@ -17,10 +14,43 @@ body, html {
text-decoration: none; text-decoration: none;
} }
md-list { md-content {
max-width: 800px; max-width: 800px;
} }
// BRIDGE CONTROLS
.navigation {
margin: 0 auto 0 auto;
padding: 30px 0 30px 0;
}
.navigationItem {
text-transform: uppercase;
cursor: pointer;
font-family: 'Slabo 27px', serif;
font-size: 18px;
padding: 0 10px 0 10px;
}
.navigationItem:hover{
text-decoration: underline;
}
.navigationItem.active {
font-weight: bold;
cursor: default;
}
.navigationItem.active:hover {
color: #000;
text-decoration: none;
}
// LIGHT GROUP
.lightGroup {
margin: 0 auto 0 auto;
}
.hueLight { .hueLight {
margin-right: 10px; margin-right: 10px;
border-radius: 20px; border-radius: 20px;
@ -54,7 +84,7 @@ md-icon {
} }
md-icon.menu { md-icon.menu {
margin: 10px 16px 0 0; margin: 30px 0 0 16px;
} }
.addButton { .addButton {
@ -70,6 +100,7 @@ md-icon.menu {
.sideNavTitle { .sideNavTitle {
margin-left: 16px; margin-left: 16px;
font-family: 'Slabo 27px', serif;
} }
md-toolbar { md-toolbar {
@ -77,20 +108,85 @@ md-toolbar {
} }
.innerControlFrame { .innerControlFrame {
background-color: mintcream;
height: 100vh; height: 100vh;
} }
.groupRow.selectedRow{ // GROUP CONTROL
background-color: lightgrey !important; .groupRow.selectedRow {
background-color: #7F7F7F !important;
color: white;
} }
.groupRow:hover { .groupRow:hover {
background-color: #E6E6E6; background-color: #c3c3c3;
}
.groupRow.selectedRow .groupSelect {
cursor: default;
} }
.groupSelect { .groupSelect {
padding: 10px 0 10px 0; padding: 10px 0 10px 0;
cursor: pointer; cursor: pointer;
width: 70%; width: 70%;
font-family: 'Open Sans', sans-serif;
}
.groupRow:hover * .close {
display: block;
}
.groupRow:hover * .close {
display: block;
}
.selectedRow * .close {
color: white !important;
}
.selectedRow.groupRow * .close:hover {
color: darken(white, 20%) !important;
}
.groupRow * .close:hover {
color: darken(#333333, 20%) !important;
}
.close:hover {
opacity: 1;
}
.close {
color: rgb(51, 51, 51);
display: none;
opacity: 1;
text-shadow: none;
}
// MUSIC CONTROL
#playListContainer {
height: 600px;
width: 200px;
color: red;
}
.playerControllIcon {
color: white !important;
cursor: pointer;
}
.playerControllIcon:hover {
color: darken(white, 20%) !important;
}
#playerArea {
height: 200px;
background-color: black;
display: inline-block;
}
#playlist {
height: 200px;
background-color: grey;
display: inline-block;
} }

View file

@ -1,30 +1,37 @@
{{#paper-nav-container open=drawerOpen class="ember-app"}} {{#liquid-if lightsData}}
{{#paper-content flex-layout="column" flex=true}}
<ul class="nav nav-tabs">
{{#each tabData as |tab|}}
<li role="presentation" class="{{if tab.selected "active" ""}}"><a
href="#" {{action "changeTab" tab.name}}>{{tab.name}}</a></li>
{{/each}}
</ul>
{{#liquid-if lightsTabSelected class="tabSwitch"}} {{#paper-nav-container open=drawerOpen class="ember-app"}}
{{controls/light-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{#liquid-if scenesTabSelected class="tabSwitch"}} {{#paper-sidenav class="md-sidenav-left md-whiteframe-z2" flex-layout="column" flex=true}}
{{controls/scene-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{#liquid-if musicTabSelected class="tabSwitch"}} {{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData}}
{{controls/music-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}} {{/paper-sidenav}}
{{/liquid-if}}
{{/paper-content}}
{{#paper-sidenav-toggle class="menu-sidenav-toggle"}} {{#paper-sidenav-toggle class="menu-sidenav-toggle"}}
{{paper-icon icon="menu" size="lg"}} {{paper-icon icon="menu" size="lg"}}
{{/paper-sidenav-toggle}} {{/paper-sidenav-toggle}}
{{#paper-sidenav class="md-sidenav-right md-whiteframe-z2" flex-layout="column" flex=true}} {{#paper-content flex-layout="column" flex=true}}
{{controls/group-control lightsData=lightsData groupsData=groupsData activeLights=activeLights apiURL=apiURL updateGroupsData=updateGroupsData}} <div class="navigation">
{{/paper-sidenav}} {{#each tabData as |tab|}}
{{/paper-nav-container}} <span class="navigationItem {{if tab.selected "active" ""}}" {{action "changeTab" tab.name}}>{{tab.name}}</span>
{{/each}}
</div>
{{#liquid-if lightsTabSelected class="tabSwitch"}}
{{controls/light-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{#liquid-if scenesTabSelected class="tabSwitch"}}
{{controls/scene-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{#liquid-if musicTabSelected class="tabSwitch"}}
{{controls/music-control apiURL=apiURL lightsData=lightsData activeLights=activeLights}}
{{/liquid-if}}
{{/paper-content}}
{{/paper-nav-container}}
{{/liquid-if}}

View file

@ -4,7 +4,7 @@
{{#paper-list}} {{#paper-list}}
{{#each groupsArrData as |group|}} {{#each groupsArrData as |group|}}
{{#paper-item class=group.rowClass}} {{#paper-item class=group.rowClass}}
<div class="groupSelect" {{action "selectGroup" group.data.key}}>{{group.name}}</div> {{#if group.deletable}}<span title="Remove Group" class="removeButton" {{action "toggleConfirmDeleteGroupsModal" group.name group.data.key}}>{{paper-icon icon="remove"}}</span>{{/if}} <div class="groupSelect" {{action "selectGroup" group.data.key}}>{{group.name}}</div> {{#if group.deletable}}<span title="Remove Group" class="removeButton" {{action "toggleConfirmDeleteGroupsModal" group.name group.data.key}}>{{paper-icon icon="close"}}</span>{{/if}}
{{/paper-item}} {{/paper-item}}
{{/each}} {{/each}}
{{/paper-list}} {{/paper-list}}
@ -13,4 +13,4 @@
{{modals/add-group-modal lightsData=lightsData groupsData=groupsData isShowingAddGroupsModal=isShowingAddGroupsModal apiURL=apiURL updateGroupsData=updateGroupsData {{modals/add-group-modal lightsData=lightsData groupsData=groupsData isShowingAddGroupsModal=isShowingAddGroupsModal apiURL=apiURL updateGroupsData=updateGroupsData
action="toggleAddGroupsModal"}} action="toggleAddGroupsModal"}}
{{modals/confirm-delete-modal groupName=deleteGroupName groupId=deleteGroupId groupsData=groupsData isShowingConfirmDeleteModal=isShowingConfirmDeleteModal apiURL=apiURL updateGroupsData=updateGroupsData action="toggleConfirmDeleteGroupsModal"}} {{modals/confirm-delete-modal groupName=deleteGroupName groupId=deleteGroupId groupsData=groupsData isShowingConfirmDeleteModal=isShowingConfirmDeleteModal apiURL=apiURL updateGroupsData=updateGroupsData groupIdSelection=groupIdSelection action="toggleConfirmDeleteGroupsModal"}}

View file

@ -22,6 +22,6 @@
{{#paper-switch checked=strobeOn}} {{strobeOnTxt}} {{/paper-switch}} {{#paper-switch checked=strobeOn}} {{strobeOnTxt}} {{/paper-switch}}
{{/paper-item}} {{/paper-item}}
{{modals/light-control-modal modalData=modalData apiURL=apiURL action="selectLight" isShowingLightsModal=isShowingLightsModal}} {{modals/light-control-modal modalData=modalData apiURL=apiURL action="clickLight" isShowingLightsModal=isShowingLightsModal}}
{{/paper-list}} {{/paper-list}}

View file

@ -1,9 +1 @@
{{#paper-list}} {{controls/music-control/music-player}}
{{#paper-item class="item"}}
{{paper-icon icon="music-note"}}
<p>Music</p>
{{#paper-button raised=true primary=true}}UPLOAD{{/paper-button}}
{{/paper-item}}
{{/paper-list}}

View file

@ -0,0 +1,14 @@
<div class="row">
<div id="playerArea" class="col-lg-8 col-xs-12">
<div id="playerControls">
{{paper-icon icon="skip-previous" action="previous" class="playerControllIcon"}}
{{paper-icon icon=playButton action="play" class="playerControllIcon"}}
{{paper-icon icon="skip-next" action="pause" class="playerControllIcon"}}
</div>
</div>
<div id="playlist" class="col-lg-4 col-xs-12">
<input id="audio_file" type="file" accept="audio/*" />
</div>
</div>

View file

@ -1,6 +1,5 @@
export default function(){ export default function(){
this.transition( this.transition(
this.hasClass('tabSwitch'),
this.use('crossFade') this.use('crossFade')
); );
} }

View file

@ -25,7 +25,7 @@ module.exports = function(environment) {
'connect-src': "'self' *", 'connect-src': "'self' *",
'img-src': "'self' data:", 'img-src': "'self' data:",
'media-src': "'self'", 'media-src': "'self'",
'style-src': "'self' 'unsafe-inline'", 'style-src': "'self' 'unsafe-inline' fonts.googleapis.com",
'object-src': "'self'", 'object-src': "'self'",
'frame-src': "'self'" 'frame-src': "'self'"
} }

View file

@ -6,8 +6,7 @@ module.exports = function(defaults) {
// Add options here // Add options here
}); });
app.import('bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js'); app.import('vendor/dancer.js');
// Use `app.import` to add additional libraries to the generated // Use `app.import` to add additional libraries to the generated
// output files. // output files.
// //

View file

@ -0,0 +1,26 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('controls/music-control/music-player', 'Integration | Component | controls/music control/music player', {
integration: true
});
test('it renders', function(assert) {
assert.expect(2);
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });
this.render(hbs`{{controls/music-control/music-player}}`);
assert.equal(this.$().text().trim(), '');
// Template block usage:
this.render(hbs`
{{#controls/music-control/music-player}}
template block text
{{/controls/music-control/music-player}}
`);
assert.equal(this.$().text().trim(), 'template block text');
});

468
vendor/dancer.js vendored
View file

@ -28,7 +28,7 @@
this.source = { src: Dancer._getMP3SrcFromAudio( source ) }; this.source = { src: Dancer._getMP3SrcFromAudio( source ) };
} }
// Loading an object with src, [codecs] // Loading an object with src, [codecs]
} else { } else {
this.source = window.Audio ? new Audio() : {}; this.source = window.Audio ? new Audio() : {};
this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); this.source.src = Dancer._makeSupportedPath( source.src, source.codecs );
@ -188,9 +188,9 @@
}; };
function update () { function update () {
for ( var i in this.sections ) { for (var i in this.sections) {
if ( this.sections[ i ].condition() ) if (this.sections[i].condition && this.sections[i].condition() )
this.sections[ i ].callback.call( this ); this.sections[i].callback.call(this);
} }
} }
@ -200,12 +200,12 @@
(function ( Dancer ) { (function ( Dancer ) {
var CODECS = { var CODECS = {
'mp3' : 'audio/mpeg;', 'mp3' : 'audio/mpeg;',
'ogg' : 'audio/ogg; codecs="vorbis"', 'ogg' : 'audio/ogg; codecs="vorbis"',
'wav' : 'audio/wav; codecs="1"', 'wav' : 'audio/wav; codecs="1"',
'aac' : 'audio/mp4; codecs="mp4a.40.2"' 'aac' : 'audio/mp4; codecs="mp4a.40.2"'
}, },
audioEl = document.createElement( 'audio' ); audioEl = document.createElement( 'audio' );
Dancer.options = {}; Dancer.options = {};
@ -235,9 +235,9 @@
var canPlay = audioEl.canPlayType; var canPlay = audioEl.canPlayType;
return !!( return !!(
Dancer.isSupported() === 'flash' ? Dancer.isSupported() === 'flash' ?
type.toLowerCase() === 'mp3' : type.toLowerCase() === 'mp3' :
audioEl.canPlayType && audioEl.canPlayType &&
audioEl.canPlayType( CODECS[ type.toLowerCase() ] ).replace( /no/, '')); audioEl.canPlayType( CODECS[ type.toLowerCase() ] ).replace( /no/, ''));
}; };
Dancer.addPlugin = function ( name, fn ) { Dancer.addPlugin = function ( name, fn ) {
@ -333,7 +333,7 @@
if ( !this.isOn ) { return; } if ( !this.isOn ) { return; }
var magnitude = this.maxAmplitude( this.frequency ); var magnitude = this.maxAmplitude( this.frequency );
if ( magnitude >= this.currentThreshold && if ( magnitude >= this.currentThreshold &&
magnitude >= this.threshold ) { magnitude >= this.threshold ) {
this.currentThreshold = magnitude; this.currentThreshold = magnitude;
this.onKick && this.onKick.call( this.dancer, magnitude ); this.onKick && this.onKick.call( this.dancer, magnitude );
} else { } else {
@ -342,9 +342,7 @@
} }
}, },
maxAmplitude : function ( frequency ) { maxAmplitude : function ( frequency ) {
var var max = 0, fft = this.dancer.getSpectrum();
max = 0,
fft = this.dancer.getSpectrum();
// Sloppy array check // Sloppy array check
if ( !frequency.length ) { if ( !frequency.length ) {
@ -369,11 +367,15 @@
SAMPLE_RATE = 44100; SAMPLE_RATE = 44100;
var adapter = function ( dancer ) { var adapter = function ( dancer ) {
var context = new AudioContext(), filter = context.createBiquadFilter();
filter.type = "lowpass";
filter.frequency.value = 440;
this.dancer = dancer; this.dancer = dancer;
this.audio = new Audio(); this.audio = new Audio();
this.context = window.AudioContext ? this.context = context;
new window.AudioContext() : this.filter = filter;
new window.webkitAudioContext();
}; };
adapter.prototype = { adapter.prototype = {
@ -464,7 +466,7 @@
for ( i = 0; i < resolution; i++ ) { for ( i = 0; i < resolution; i++ ) {
this.signal[ i ] = channels > 1 ? this.signal[ i ] = channels > 1 ?
buffers.reduce( sum ) / channels : buffers.reduce( sum ) / channels :
buffers[ 0 ][ i ]; buffers[ 0 ][ i ];
} }
@ -477,8 +479,10 @@
this.source = this.context.createMediaElementSource( this.audio ); this.source = this.context.createMediaElementSource( this.audio );
this.source.connect( this.proc ); this.source.connect( this.proc );
this.source.connect( this.gain ); this.source.connect( this.gain );
//this.source.connect( this.filter );
this.gain.connect( this.context.destination ); this.gain.connect( this.context.destination );
this.proc.connect( this.context.destination ); this.proc.connect( this.context.destination );
//this.filter.connect( this.context.destination );
this.isLoaded = true; this.isLoaded = true;
this.progress = 1; this.progress = 1;
@ -770,13 +774,13 @@ function FourierTransform(bufferSize, sampleRate) {
this.calculateSpectrum = function() { this.calculateSpectrum = function() {
var spectrum = this.spectrum, var spectrum = this.spectrum,
real = this.real, real = this.real,
imag = this.imag, imag = this.imag,
bSi = 2 / this.bufferSize, bSi = 2 / this.bufferSize,
sqrt = Math.sqrt, sqrt = Math.sqrt,
rval, rval,
ival, ival,
mag; mag;
for (var i = 0, N = bufferSize/2; i < N; i++) { for (var i = 0, N = bufferSize/2; i < N; i++) {
rval = real[i]; rval = real[i];
@ -841,12 +845,12 @@ function FFT(bufferSize, sampleRate) {
FFT.prototype.forward = function(buffer) { FFT.prototype.forward = function(buffer) {
// Locally scope variables for speed up // Locally scope variables for speed up
var bufferSize = this.bufferSize, var bufferSize = this.bufferSize,
cosTable = this.cosTable, cosTable = this.cosTable,
sinTable = this.sinTable, sinTable = this.sinTable,
reverseTable = this.reverseTable, reverseTable = this.reverseTable,
real = this.real, real = this.real,
imag = this.imag, imag = this.imag,
spectrum = this.spectrum; spectrum = this.spectrum;
var k = Math.floor(Math.log(bufferSize) / Math.LN2); var k = Math.floor(Math.log(bufferSize) / Math.LN2);
@ -854,15 +858,15 @@ FFT.prototype.forward = function(buffer) {
if (bufferSize !== buffer.length) { throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length; } if (bufferSize !== buffer.length) { throw "Supplied buffer is not the same size as defined FFT. FFT Size: " + bufferSize + " Buffer Size: " + buffer.length; }
var halfSize = 1, var halfSize = 1,
phaseShiftStepReal, phaseShiftStepReal,
phaseShiftStepImag, phaseShiftStepImag,
currentPhaseShiftReal, currentPhaseShiftReal,
currentPhaseShiftImag, currentPhaseShiftImag,
off, off,
tr, tr,
ti, ti,
tmpReal, tmpReal,
i; i;
for (i = 0; i < bufferSize; i++) { for (i = 0; i < bufferSize; i++) {
real[i] = buffer[reverseTable[i]]; real[i] = buffer[reverseTable[i]];
@ -906,202 +910,202 @@ FFT.prototype.forward = function(buffer) {
}; };
/* /*
Copyright (c) Copyright (c) 2007, Carl S. Yestrau All rights reserved. Copyright (c) Copyright (c) 2007, Carl S. Yestrau All rights reserved.
Code licensed under the BSD License: http://www.featureblend.com/license.txt Code licensed under the BSD License: http://www.featureblend.com/license.txt
Version: 1.0.4 Version: 1.0.4
*/ */
var FlashDetect = new function(){ var FlashDetect = new function(){
var self = this; var self = this;
self.installed = false; self.installed = false;
self.raw = ""; self.raw = "";
self.major = -1; self.major = -1;
self.minor = -1; self.minor = -1;
self.revision = -1; self.revision = -1;
self.revisionStr = ""; self.revisionStr = "";
var activeXDetectRules = [ var activeXDetectRules = [
{ {
"name":"ShockwaveFlash.ShockwaveFlash.7", "name":"ShockwaveFlash.ShockwaveFlash.7",
"version":function(obj){ "version":function(obj){
return getActiveXVersion(obj); return getActiveXVersion(obj);
} }
}, },
{ {
"name":"ShockwaveFlash.ShockwaveFlash.6", "name":"ShockwaveFlash.ShockwaveFlash.6",
"version":function(obj){ "version":function(obj){
var version = "6,0,21"; var version = "6,0,21";
try{
obj.AllowScriptAccess = "always";
version = getActiveXVersion(obj);
}catch(err){}
return version;
}
},
{
"name":"ShockwaveFlash.ShockwaveFlash",
"version":function(obj){
return getActiveXVersion(obj);
}
}
];
/**
* Extract the ActiveX version of the plugin.
*
* @param {Object} The flash ActiveX object.
* @type String
*/
var getActiveXVersion = function(activeXObj){
var version = -1;
try{ try{
obj.AllowScriptAccess = "always"; version = activeXObj.GetVariable("$version");
version = getActiveXVersion(obj);
}catch(err){} }catch(err){}
return version; return version;
}
},
{
"name":"ShockwaveFlash.ShockwaveFlash",
"version":function(obj){
return getActiveXVersion(obj);
}
}
];
/**
* Extract the ActiveX version of the plugin.
*
* @param {Object} The flash ActiveX object.
* @type String
*/
var getActiveXVersion = function(activeXObj){
var version = -1;
try{
version = activeXObj.GetVariable("$version");
}catch(err){}
return version;
};
/**
* Try and retrieve an ActiveX object having a specified name.
*
* @param {String} name The ActiveX object name lookup.
* @return One of ActiveX object or a simple object having an attribute of activeXError with a value of true.
* @type Object
*/
var getActiveXObject = function(name){
var obj = -1;
try{
obj = new ActiveXObject(name);
}catch(err){
obj = {activeXError:true};
}
return obj;
};
/**
* Parse an ActiveX $version string into an object.
*
* @param {String} str The ActiveX Object GetVariable($version) return value.
* @return An object having raw, major, minor, revision and revisionStr attributes.
* @type Object
*/
var parseActiveXVersion = function(str){
var versionArray = str.split(",");//replace with regex
return {
"raw":str,
"major":parseInt(versionArray[0].split(" ")[1], 10),
"minor":parseInt(versionArray[1], 10),
"revision":parseInt(versionArray[2], 10),
"revisionStr":versionArray[2]
}; };
}; /**
/** * Try and retrieve an ActiveX object having a specified name.
* Parse a standard enabledPlugin.description into an object. *
* * @param {String} name The ActiveX object name lookup.
* @param {String} str The enabledPlugin.description value. * @return One of ActiveX object or a simple object having an attribute of activeXError with a value of true.
* @return An object having raw, major, minor, revision and revisionStr attributes. * @type Object
* @type Object */
*/ var getActiveXObject = function(name){
var parseStandardVersion = function(str){ var obj = -1;
var descParts = str.split(/ +/); try{
var majorMinor = descParts[2].split(/\./); obj = new ActiveXObject(name);
var revisionStr = descParts[3]; }catch(err){
return { obj = {activeXError:true};
"raw":str, }
"major":parseInt(majorMinor[0], 10), return obj;
"minor":parseInt(majorMinor[1], 10),
"revisionStr":revisionStr,
"revision":parseRevisionStrToInt(revisionStr)
}; };
}; /**
/** * Parse an ActiveX $version string into an object.
* Parse the plugin revision string into an integer. *
* * @param {String} str The ActiveX Object GetVariable($version) return value.
* @param {String} The revision in string format. * @return An object having raw, major, minor, revision and revisionStr attributes.
* @type Number * @type Object
*/ */
var parseRevisionStrToInt = function(str){ var parseActiveXVersion = function(str){
return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || self.revision; var versionArray = str.split(",");//replace with regex
}; return {
/** "raw":str,
* Is the major version greater than or equal to a specified version. "major":parseInt(versionArray[0].split(" ")[1], 10),
* "minor":parseInt(versionArray[1], 10),
* @param {Number} version The minimum required major version. "revision":parseInt(versionArray[2], 10),
* @type Boolean "revisionStr":versionArray[2]
*/ };
self.majorAtLeast = function(version){ };
return self.major >= version; /**
}; * Parse a standard enabledPlugin.description into an object.
/** *
* Is the minor version greater than or equal to a specified version. * @param {String} str The enabledPlugin.description value.
* * @return An object having raw, major, minor, revision and revisionStr attributes.
* @param {Number} version The minimum required minor version. * @type Object
* @type Boolean */
*/ var parseStandardVersion = function(str){
self.minorAtLeast = function(version){ var descParts = str.split(/ +/);
return self.minor >= version; var majorMinor = descParts[2].split(/\./);
}; var revisionStr = descParts[3];
/** return {
* Is the revision version greater than or equal to a specified version. "raw":str,
* "major":parseInt(majorMinor[0], 10),
* @param {Number} version The minimum required revision version. "minor":parseInt(majorMinor[1], 10),
* @type Boolean "revisionStr":revisionStr,
*/ "revision":parseRevisionStrToInt(revisionStr)
self.revisionAtLeast = function(version){ };
return self.revision >= version; };
}; /**
/** * Parse the plugin revision string into an integer.
* Is the version greater than or equal to a specified major, minor and revision. *
* * @param {String} The revision in string format.
* @param {Number} major The minimum required major version. * @type Number
* @param {Number} (Optional) minor The minimum required minor version. */
* @param {Number} (Optional) revision The minimum required revision version. var parseRevisionStrToInt = function(str){
* @type Boolean return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || self.revision;
*/ };
self.versionAtLeast = function(major){ /**
var properties = [self.major, self.minor, self.revision]; * Is the major version greater than or equal to a specified version.
var len = Math.min(properties.length, arguments.length); *
for(i=0; i<len; i++){ * @param {Number} version The minimum required major version.
if(properties[i]>=arguments[i]){ * @type Boolean
if(i+1<len && properties[i]==arguments[i]){ */
continue; self.majorAtLeast = function(version){
}else{ return self.major >= version;
return true; };
/**
* Is the minor version greater than or equal to a specified version.
*
* @param {Number} version The minimum required minor version.
* @type Boolean
*/
self.minorAtLeast = function(version){
return self.minor >= version;
};
/**
* Is the revision version greater than or equal to a specified version.
*
* @param {Number} version The minimum required revision version.
* @type Boolean
*/
self.revisionAtLeast = function(version){
return self.revision >= version;
};
/**
* Is the version greater than or equal to a specified major, minor and revision.
*
* @param {Number} major The minimum required major version.
* @param {Number} (Optional) minor The minimum required minor version.
* @param {Number} (Optional) revision The minimum required revision version.
* @type Boolean
*/
self.versionAtLeast = function(major){
var properties = [self.major, self.minor, self.revision];
var len = Math.min(properties.length, arguments.length);
for(i=0; i<len; i++){
if(properties[i]>=arguments[i]){
if(i+1<len && properties[i]==arguments[i]){
continue;
}else{
return true;
}
}else{
return false;
}
} }
}else{ };
return false; /**
} * Constructor, sets raw, major, minor, revisionStr, revision and installed public properties.
} */
}; self.FlashDetect = function(){
/** if(navigator.plugins && navigator.plugins.length>0){
* Constructor, sets raw, major, minor, revisionStr, revision and installed public properties. var type = 'application/x-shockwave-flash';
*/ var mimeTypes = navigator.mimeTypes;
self.FlashDetect = function(){ if(mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description){
if(navigator.plugins && navigator.plugins.length>0){ var version = mimeTypes[type].enabledPlugin.description;
var type = 'application/x-shockwave-flash'; var versionObj = parseStandardVersion(version);
var mimeTypes = navigator.mimeTypes; self.raw = versionObj.raw;
if(mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description){ self.major = versionObj.major;
var version = mimeTypes[type].enabledPlugin.description; self.minor = versionObj.minor;
var versionObj = parseStandardVersion(version); self.revisionStr = versionObj.revisionStr;
self.raw = versionObj.raw; self.revision = versionObj.revision;
self.major = versionObj.major; self.installed = true;
self.minor = versionObj.minor; }
self.revisionStr = versionObj.revisionStr; }else if(navigator.appVersion.indexOf("Mac")==-1 && window.execScript){
self.revision = versionObj.revision; var version = -1;
self.installed = true; for(var i=0; i<activeXDetectRules.length && version==-1; i++){
} var obj = getActiveXObject(activeXDetectRules[i].name);
}else if(navigator.appVersion.indexOf("Mac")==-1 && window.execScript){ if(!obj.activeXError){
var version = -1; self.installed = true;
for(var i=0; i<activeXDetectRules.length && version==-1; i++){ version = activeXDetectRules[i].version(obj);
var obj = getActiveXObject(activeXDetectRules[i].name); if(version!=-1){
if(!obj.activeXError){ var versionObj = parseActiveXVersion(version);
self.installed = true; self.raw = versionObj.raw;
version = activeXDetectRules[i].version(obj); self.major = versionObj.major;
if(version!=-1){ self.minor = versionObj.minor;
var versionObj = parseActiveXVersion(version); self.revision = versionObj.revision;
self.raw = versionObj.raw; self.revisionStr = versionObj.revisionStr;
self.major = versionObj.major; }
self.minor = versionObj.minor; }
self.revision = versionObj.revision; }
self.revisionStr = versionObj.revisionStr;
}
} }
} }();
}
}();
}; };
FlashDetect.JS_RELEASE = "1.0.4"; FlashDetect.JS_RELEASE = "1.0.4";