/*---------------------------- ew mixer styles -----------------------------*/ .mixer-section { background-color: #323232; } .mixer .interface * { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; -ms-user-select: none; user-select: none; font-family: Arial, "sans-serif"; box-sizing: unset; } .mixer { width: 100%; max-width: 1053px; margin: 0 auto; overflow-y: hidden; color: #9e9e9e; } .mixer .mobile-overlay { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; background-color: #000000; opacity: 0.8; z-index: 99999; } .mixer .overlay-container { display: table; width: 100%; height: 100%; } .mixer .mobile-overlay p { display: table-cell; color: #FFFFFF; text-align: center; vertical-align: middle; padding: 10px; } .mixer-wrapper { padding: 0px 100px; } .mixer .interface .interface-container img { display: block; width: 100%; } .mixer .interface .interface-container img.mixer-interface { position: absolute; } .mixer .interface { position: relative; width: 100%; height: 100%; } .mixer .interface .mixer-demo, .mixer .interface input[type="range"] { display: none; } .mixer .interface .channels { width: 79.5%; height: 100%; position: absolute; top: 0px; left: .5%; } .mixer .interface .channel { float: left; position: relative; width: 12.45%; height: 100%; overflow: hidden; } .mixer .interface .channel .channel-container { position: relative; width: 100%; height: 60%; top: 28%; } .mixer .interface .channel:not(:last-child) .channel-container:after { display: block; content: ""; position: absolute; width: 1px; border-radius: 1; top: 2%; right: 0px; height: 96%; background-color: #454646; } /* .mixer .interface .master-controls { position: absolute; top: 27%; right: 3%; width: 15%; height: 57%; } */ .mixer .interface .master-gain { position: absolute; bottom: 4%; right: 3%; width: 15%; height: 40%; z-index: 100; user-select: none; -webkit-touch-callout: none; -webkit-user-select: none; } .mixer .interface .master-gain-container { position: relative; width: 100%; height: 100%; user-select: none; -webkit-touch-callout: none; -webkit-user-select: none; } .mixer .interface .master-gain-inner { position: absolute; min-width: 135px; height: 135px; width: 100%; left: 50%; top: 50%; background: url('https://media.soundsonline.com/mixer/images/mixer_master-gain_sprite_1@2x.png') center no-repeat; background-size: 135px auto; background-position-x: center; transform-origin: left top; user-select: none; -webkit-touch-callout: none; -webkit-user-select: none; } .mixer .interface .knob { position: relative; -webkit-touch-callout: none; -webkit-user-select: none; cursor: grab; } .mixer .interface .knob .top { position: absolute; width: 100%; height: 100%; z-index: 10; cursor: default !important; } .mixer .interface .mixer-button { position: absolute; margin: 0px; padding: 0px; top: 38%; width: 54%; height: 9%; max-width: 58px; max-height: 58px; background: url('https://media.soundsonline.com/mixer/images/mixer_button_1@2x.png') center no-repeat; background-size: 110% auto; cursor: pointer; } .mixer .interface .mixer-button.solo { left: -3%; } .mixer .interface .mixer-button.mute { right: -2%; } .mixer .interface .mixer-button.active { background: url('https://media.soundsonline.com/mixer/images/mixer_button_on_1@2x.png') center no-repeat; background-size: 110% auto; } .mixer .interface .mixer-button.active:after { display: block; position: absolute; width: 5px; height: 5px; content: ""; bottom: 12%; left: 50%; transform: translate(-50%); } .mixer .interface .mixer-button.solo.active:after { background: url('https://media.soundsonline.com/mixer/images/mixer_solo_on_1@2x.png') no-repeat; background-size: 5px 5px; } .mixer .interface .mixer-button.mute.active:after { background: url('https://media.soundsonline.com/mixer/images/mixer_cut_on_1@2x.png') no-repeat; background-size: 5px 5px; } .mixer .interface .pan { position: absolute; min-width: 63px; min-height: 63px; height: 12%; top: 26%; left: 50%; background: url('https://media.soundsonline.com/mixer/images/mixer_pan_sprite_1@2x.png') no-repeat; background-size: 63px auto; background-position-x: center; transform: scale(0.7) translate(-50%); transform-origin: top left; } .mixer .interface .knob { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 55%; height: 55%; } .mixer .interface .master-gain .knob { width: 60%; height: 60%; } .mixer .interface .knob [draggable] { -moz-user-select: none; -webkit-user-select: none; user-select: none; } .mixer .interface .volume { position: absolute; width: 70%; height: 40%; top: 45%; left: 15%; background: url('https://media.soundsonline.com/mixer/images/mixer_channel-labels_1@2x.png') left center no-repeat; background-size: auto 75%; } .mixer .interface .volume .rangeslider { display: block; position: relative; } .mixer .interface .volume .rangeslider--vertical { width: 20px; min-height: 100%; height: 100%; } .mixer .interface .volume .rangeslider--vertical .rangeslider__handle { left: -10px; touch-action: pan-x; -ms-touch-action: pan-x; } .mixer .interface .slider-container { position: relative; height: 100%; width: 25px; margin: 0 auto; } .mixer .interface .channel .slider-container .rangeslider__handle { display: inline-block; position: absolute; left: 2px; width: 100%; height: 46px; border: none; outline: none; cursor: pointer; } .mixer .interface .channel .slider-container .rangeslider__handle .handle-inner { position: absolute; left: -30px; width: 90px; height: 90px; background-color: transparent; background: url('https://media.soundsonline.com/mixer/images/mixer_fader_1@2x.png') no-repeat; background-size: 100px auto; background-position: 9px 2px; margin-top: -5px; } .mixer .interface .channel h6.track-title { position: absolute; bottom: 9%; font-size: 10px; font-weight: 500; color: #4e4d4e; text-align: center; width: 90%; padding: 0% 5%; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .mixer .meters { display: block; position: absolute; top: 4%; left: 25%; width: 52%; height: 18%; } .mixer .interface .meter-container { position: relative; width: 100%; height: 100%; background: url('https://media.soundsonline.com/mixer/images/mixer_channel-meter-labels_1@2x.png') center no-repeat; background-size: auto 95%; } .mixer .interface .meters .meter { position: absolute; background: url('https://media.soundsonline.com/mixer/images/mixer_channel-meter_1@2x.png') bottom center no-repeat; background-size: 100% auto; width: 4px; height: 100%; } .mixer .interface .meters .meter-right { right: 0px; } .mixer .interface .meters .meter-fill { display: none; position: absolute; width: 100%; height: 100%; max-height: 100%; bottom: 0px; background: url('https://media.soundsonline.com/mixer/images/mixer_channel-meter-fill_1@2x.png') bottom center no-repeat; background-size: 4px auto; } .mixer .interface .meter-fill.meter-right { left: 34px; } .mixer .interface .master-controls .meters { width: 5%; height: 28%; top: 34%; left: auto; right: 7.9%; } .mixer .interface .master-controls .meters .meter-container { background: url('https://media.soundsonline.com/mixer/images/mixer_master-meter-labels_1@2x.png') center no-repeat; background-size: auto 95%; } .mixer .interface .master-controls .meters .meter { background: url('https://media.soundsonline.com/mixer/images/mixer_master-meter_1@2x.png') bottom center no-repeat; background-size: 100% auto; } .mixer .interface .master-controls .meters .meter-fill { background: url('https://media.soundsonline.com/mixer/images/mixer_master-meter-fill_1@2x.png') bottom center no-repeat; background-size: 4px auto; } .mixer .interface .master-controls .meters .meter-fill.meter-right { left: 40.5px; } .mixer .interface .channel:not(.loaded) .meters .meter-fill { height: 0px !important; } .mixer .interface .master-controls .meters .meter-fill, .mixer .interface .channel.loaded .meters .meter-fill { min-height: 2px; } .mixer .interface .media { position: absolute; width: 19.5%; height: 26%; top: 0px; right: .5%; } .mixer .interface .media p { font-size: 9px; } .mixer .interface .media .media-container { position: relative; padding: 10%; height: 80%; display: none; } .mixer .interface .media .duration-container { position: absolute; top: 45%; width: 80%; } .mixer .interface .media .duration-container p.duration-current { float: left; } .mixer .interface .media .duration-container p.duration-total { float: right; } .mixer .interface .media .media-play { display: block; width: 13px; height: 15px; background: url('https://media.soundsonline.com/mixer/images/mixer_play_1@2x.png') top center no-repeat; background-size: 13px auto; } .mixer .interface .media .media-controls { position: absolute; top: 67%; width: 80%; margin: 0 auto; } .mixer .interface .media .media-controls .media-controls-container { position: relative; padding: 5%; width: 90%; height: 100%; min-height: 24px; } .mixer .interface .media .media-play { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); cursor: pointer; } .mixer .interface .media .media-play.is-playing { width: 17px; height: 16px; background: url('https://media.soundsonline.com/mixer/images/mixer_pause_1@2x.png') top center no-repeat; background-size: 12px auto; } .mixer .interface.loading .media .media-play { width: 25px; height: 25px; background: url('https://media.soundsonline.com/mixer/images/mixer_loading@2x.gif') center no-repeat; background-size: 40px auto; } .mixer .interface.loading .chosen-container a { visibility: visible; } .mixer .interface .chosen-container-active.chosen-with-drop .chosen-single { border: none; } .mixer .interface .media .media-rewind, .mixer .interface .media .media-forward { display: block; position: absolute; width: 14px; height: 14px; top: 50%; transform: translate(0%,-50%); cursor: pointer; } .mixer .interface .media .media-rewind { left: 5%; background: url('https://media.soundsonline.com/mixer/images/mixer_rewind_1@2x.png') top center no-repeat; background-size: 14px auto; } .mixer .interface .media .media-forward { right: 5%; background: url('https://media.soundsonline.com/mixer/images/mixer_forward_1@2x.png') top center no-repeat; background-size: 14px auto; } .mixer .interface .media .media-title { position: absolute; text-align: center; top: 10%; width: 80%; } .mixer .interface .media .media-title h5 { font-weight: normal; margin-bottom: 5px; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .interface .media .chosen-single { height: 20px; line-height: 20px; padding: 0px; } .mixer .interface .media .chosen-single span { font-size: 12px; color: #FFFFFF; margin: 0px; } .mixer .interface .media .media-title h5 { font-size: 10px; color: #9e9e9e; margin: 0px; } .mixer .interface .media .chosen-container .chosen-drop ul li { font-size: 12px; } .mixer .interface .progress-bar-container, .mixer .interface .progress-marker-container { position: relative; } .mixer .interface .progress-bar-container { padding-top: 18px; height: 5px; cursor: pointer; width: 100%; } .mixer .interface .progress-track, .mixer .interface .progress-bar { position: absolute; background-color: #5c5b5b; top: 75%; width: 100%; height: 1px; } .mixer .interface .progress-bar { background-color: #FFFFFF; width: 0px; min-width: 8px; max-with: 100%; } .mixer .interface .progress-marker { display: block; position: absolute; right: 0px; top: -3.5px; width: 8px; height: 8px; background-color: #FFFFFF; border-radius: 4px; } .mixer .interface .media select { background: none; color: #FFFFFF; border: none; outline: none; width: 90%; padding: 5px 5% 5px 5%; font-size: 11px; } /* === SMALL === */ .mixer.small .interface .pan { top: 27%; } /* === MEDIUM === */ .mixer.medium .mobile-overlay { display: none; } .mixer.medium .interface .media .media-container { display: block; } .mixer.medium .interface .channel h6.track-title { font-size: 12px; } .mixer.medium .interface .media .duration-container { top: 45%; } .mixer.medium .interface .media p { font-size: 10px; } .mixer.medium .interface .pan { transform: scale(0.85) translate(-50%); } .mixer.medium .interface .mixer-button { top: 38%; } .mixer.medium .interface .media .chosen-single span { font-size: 13px; } .mixer.medium .interface .media .media-title h5 { font-size: 12px; } .mixer.medium .interface .media .media-title h5 { font-size: 10px; color: #9e9e9e; margin: 0px; } .mixer.medium .interface .media .chosen-container .chosen-drop ul li { font-size: 13px; } /* === LARGE === */ .mixer.large .interface .media .chosen-single { height: 30px; line-height: 30px; } .mixer.large .interface .media .chosen-single span { margin-bottom: 5px; font-size: 14px; } .mixer.large .interface .media .media-title h5 { font-size: 12px; } .mixer.large .interface .media .chosen-container .chosen-drop ul li { font-size: 14px; } .mixer.large .interface .channel h6.track-title { font-size: 14px; margin: 0px; bottom: 12.5%; } .mixer.large .interface .progress-bar-container { padding-top: 23px; } .mixer.large .interface .media .media-play { width: 19px; height: 22px; background-size: 19px auto; } .mixer.large .interface .media p { font-size: 11px; margin: 0px; } .mixer.large .interface.loading .media .media-play { width: 50px; height: 50px; background-size: 50px auto; } .mixer.large .interface .media .media-play.is-playing { height: 22px; } .mixer.large .interface .meters .meter { width: 6px; } .mixer.large .interface .meters .meter-fill { background-size: 6px auto; } .mixer.large .interface .pan { top: 28%; width: 63px; height: 63px; transform: scale(1) translate(-50%); } .mixer.large .interface .master-gain { margin: 0px; bottom: 4%; } .mixer.large .interface .volume { height: 39%; top: 47%; background-size: auto 85%; } .mixer.large .interface .channel .slider-container .rangeslider__handle .handle-inner { width: 90px; height: 100px; background-size: 135px auto; background-position: -2px -8px; } .mixer.large .interface .mixer-button { top: 39%; height: 8%; } .mixer.large .interface .media select { padding: 10px 5% 10px 5%; font-size: 13px; } /* === LARGEST === */ .mixer.largest .interface .media .chosen-single { height: 35px; line-height: 35px; } .mixer.largest .interface .media .chosen-single span { margin-bottom: 5px; font-size: 15px; } .mixer.largest .interface .media .media-title h5 { font-size: 13px; } .mixer.largest .interface .media select { font-size: 14px; } .mixer.largest .interface .channel .pan { top: 28.7% } .mixer.largest .interface .mixer-button { top: 39%; height: 8%; } .mixer.largest .interface .mixer-button:after { transform: scale(1.1); transform-origin: 23px 0px; } /* preload images */ body::after{ position:absolute; width:0; height:0; overflow:hidden; z-index:-1; content:url('https://media.soundsonline.com/mixer/images/mixer_loading@2x.gif') url('https://media.soundsonline.com/mixer/images/mixer_fader_1@2x.png') url('https://media.soundsonline.com/mixer/images/mixer_fader_1@2x.png') url('https://media.soundsonline.com/mixer/images/mixer_button_1@2x.png') url('https://media.soundsonline.com/mixer/images/mixer_button_on_1@2x.png'); } .mixer .chosen-container { background: none; border: none; } .mixer .chosen-container:after { display: none; } .mixer .chosen-container { -webkit-tap-highlight-color: transparent; clear: both; cursor: pointer; display: block; color: #FFFFFF; font-family: inherit; font-size: 13px; font-weight: normal; height: auto; line-height: 36px; outline: none; position: relative; text-align: center !important; -webkit-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; white-space: nowrap; max-width: 238px; z-index: 9999; } .mixer .chosen-container span { display: inline-block; font-size: 13px; overflow: hidden; white-space: nowrap; text-align: center; position: relative; padding-right: 12%; max-width: 100%; width: 88%; } .mixer.large .chosen-container span { padding-right: 10%; max-width: 90%; } .mixer.largest .chosen-container span { padding-right: 17px; max-width: calc(100%-17px); } .mixer .chosen-container .chosen-single { border: none; box-shadow: none; } .mixer .chosen-container:hover { border-color: #dbdbdb; } .mixer .chosen-container:active, .nice-select.open, .nice-select:focus { border-color: #999; } .mixer .chosen-container span:after { /* border-bottom: 2px solid #9e9e9e; border-right: 2px solid #9e9e9e; */ content: ''; display: block; height: 5px; margin-top: -3px; pointer-events: none; position: absolute; right: 0px; top: 50%; /* -webkit-transform-origin: 66% 66%; -ms-transform-origin: 66% 66%; transform-origin: 66% 66%; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); */ -webkit-transition: all 0.15s ease-in-out; transition: all 0.15s ease-in-out; width: 5px; display: block; width: 0; height: 0; border-style: solid; border-width: 7px 5px 0 5px; border-color: #9e9e9e transparent transparent transparent; } .mixer .chosen-container.chosen-with-drop span:after { -webkit-transform: rotate(-180deg); -ms-transform: rotate(-180deg); transform: rotate(-180deg); } .mixer .chosen-container .chosen-results { opacity: 1; background: none; max-height: none; pointer-events: auto; -webkit-transform: scale(1) translateY(0); -ms-transform: scale(1) translateY(0); transform: scale(1) translateY(0); } .mixer .nice-select.disabled { border-color: #ccc; color: #999; pointer-events: none; } .mixer .nice-select.disabled:after { border-color: #cccccc; } .mixer .nice-select.wide { width: 100%; } .mixer .nice-select.wide .list { left: 0 !important; right: 0 !important; } .mixer .nice-select.right { float: right; } .mixer .nice-select.right .list { left: auto; right: 0; } .mixer .nice-select.small { font-size: 12px; height: 36px; line-height: 34px; } .mixer .nice-select.small:after { height: 4px; width: 4px; } .mixer .nice-select.small .option { line-height: 34px; min-height: 34px; } .mixer .chosen-container .chosen-drop { color: #FFFFFF; background-color: #222222; border-radius: 2px; border: none; box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11); box-sizing: border-box; overflow-y: auto; overflow: visible; max-height: none; width: 100%; max-width: 100%; padding: 0; pointer-events: none; -webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out; transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out; } .mixer .nice-select .list:hover .option:not(:hover) { background-color: transparent !important; } .mixer .chosen-container .chosen-drop ul li { cursor: pointer; font-size: 14px; font-weight: 400; list-style: none; outline: none; padding-left: 12px; padding-right: 12px; margin-bottom: 0px; text-align: left; overflow: hidden; text-overflow: ellipsis; -webkit-transition: all 0.2s; transition: all 0.2s; } .mixer .chosen-container .chosen-drop ul li:hover { background-color: #373737; } .mixer .nice-select .option.selected { font-weight: bold; } .mixer .nice-select .option.disabled { background-color: transparent; color: #999; cursor: default; } .mixer.medium .nice-select .option { font-size: 13px; } .mixer.large .nice-select .option { font-size: 14px; } .mixer .no-csspointerevents .nice-select .list { display: none; } .mixer .no-csspointerevents .nice-select.open .list { display: block; } /*! rangeslider.js - v2.3.2 | (c) 2018 @andreruffert | MIT license | https://github.com/andreruffert/rangeslider.js */ (function(factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // CommonJS module.exports = factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function($) { 'use strict'; // Polyfill Number.isNaN(value) // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN Number.isNaN = Number.isNaN || function(value) { return typeof value === 'number' && value !== value; }; /** * Range feature detection * @return {Boolean} */ function supportsRange() { var input = document.createElement('input'); input.setAttribute('type', 'range'); return input.type !== 'text'; } var pluginName = 'rangeslider', pluginIdentifier = 0, hasInputRangeSupport = supportsRange(), defaults = { polyfill: true, orientation: 'horizontal', rangeClass: 'rangeslider', disabledClass: 'rangeslider--disabled', activeClass: 'rangeslider--active', horizontalClass: 'rangeslider--horizontal', verticalClass: 'rangeslider--vertical', fillClass: 'rangeslider__fill', handleClass: 'rangeslider__handle', startEvent: ['mousedown', 'touchstart', 'pointerdown'], moveEvent: ['mousemove', 'touchmove', 'pointermove'], endEvent: ['mouseup', 'touchend', 'pointerup'] }, constants = { orientation: { horizontal: { dimension: 'width', direction: 'left', directionStyle: 'left', coordinate: 'x' }, vertical: { dimension: 'height', direction: 'top', directionStyle: 'bottom', coordinate: 'y' } } }; /** * Delays a function for the given number of milliseconds, and then calls * it with the arguments supplied. * * @param {Function} fn [description] * @param {Number} wait [description] * @return {Function} */ function delay(fn, wait) { var args = Array.prototype.slice.call(arguments, 2); return setTimeout(function(){ return fn.apply(null, args); }, wait); } /** * Returns a debounced function that will make sure the given * function is not triggered too much. * * @param {Function} fn Function to debounce. * @param {Number} debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the function. (defaults to 100ms) * @return {Function} */ function debounce(fn, debounceDuration) { debounceDuration = debounceDuration || 100; return function() { if (!fn.debouncing) { var args = Array.prototype.slice.apply(arguments); fn.lastReturnVal = fn.apply(window, args); fn.debouncing = true; } clearTimeout(fn.debounceTimeout); fn.debounceTimeout = setTimeout(function(){ fn.debouncing = false; }, debounceDuration); return fn.lastReturnVal; }; } /** * Check if a `element` is visible in the DOM * * @param {Element} element * @return {Boolean} */ function isHidden(element) { return ( element && ( element.offsetWidth === 0 || element.offsetHeight === 0 || // Also Consider native `
` elements. element.open === false ) ); } /** * Get hidden parentNodes of an `element` * * @param {Element} element * @return {[type]} */ function getHiddenParentNodes(element) { var parents = [], node = element.parentNode; while (isHidden(node)) { parents.push(node); node = node.parentNode; } return parents; } /** * Returns dimensions for an element even if it is not visible in the DOM. * * @param {Element} element * @param {String} key (e.g. offsetWidth …) * @return {Number} */ function getDimension(element, key) { var hiddenParentNodes = getHiddenParentNodes(element), hiddenParentNodesLength = hiddenParentNodes.length, inlineStyle = [], dimension = element[key]; // Used for native `
` elements function toggleOpenProperty(element) { if (typeof element.open !== 'undefined') { element.open = (element.open) ? false : true; } } if (hiddenParentNodesLength) { for (var i = 0; i < hiddenParentNodesLength; i++) { // Cache style attribute to restore it later. inlineStyle[i] = hiddenParentNodes[i].style.cssText; // visually hide if (hiddenParentNodes[i].style.setProperty) { hiddenParentNodes[i].style.setProperty('display', 'block', 'important'); } else { hiddenParentNodes[i].style.cssText += ';display: block !important'; } hiddenParentNodes[i].style.height = '0'; hiddenParentNodes[i].style.overflow = 'hidden'; hiddenParentNodes[i].style.visibility = 'hidden'; toggleOpenProperty(hiddenParentNodes[i]); } // Update dimension dimension = element[key]; for (var j = 0; j < hiddenParentNodesLength; j++) { // Restore the style attribute hiddenParentNodes[j].style.cssText = inlineStyle[j]; toggleOpenProperty(hiddenParentNodes[j]); } } return dimension; } /** * Returns the parsed float or the default if it failed. * * @param {String} str * @param {Number} defaultValue * @return {Number} */ function tryParseFloat(str, defaultValue) { var value = parseFloat(str); return Number.isNaN(value) ? defaultValue : value; } /** * Capitalize the first letter of string * * @param {String} str * @return {String} */ function ucfirst(str) { return str.charAt(0).toUpperCase() + str.substr(1); } /** * Plugin * @param {String} element * @param {Object} options */ function Plugin(element, options) { this.$window = $(window); this.$document = $(document); this.$element = $(element); this.options = $.extend( {}, defaults, options ); this.polyfill = this.options.polyfill; this.orientation = this.$element[0].getAttribute('data-orientation') || this.options.orientation; this.onInit = this.options.onInit; this.onSlide = this.options.onSlide; this.onSlideEnd = this.options.onSlideEnd; this.DIMENSION = constants.orientation[this.orientation].dimension; this.DIRECTION = constants.orientation[this.orientation].direction; this.DIRECTION_STYLE = constants.orientation[this.orientation].directionStyle; this.COORDINATE = constants.orientation[this.orientation].coordinate; // Plugin should only be used as a polyfill if (this.polyfill) { // Input range support? if (hasInputRangeSupport) { return false; } } this.identifier = 'js-' + pluginName + '-' +(pluginIdentifier++); this.startEvent = this.options.startEvent.join('.' + this.identifier + ' ') + '.' + this.identifier; this.moveEvent = this.options.moveEvent.join('.' + this.identifier + ' ') + '.' + this.identifier; this.endEvent = this.options.endEvent.join('.' + this.identifier + ' ') + '.' + this.identifier; this.toFixed = (this.step + '').replace('.', '').length - 1; this.$fill = $('
'); this.$handle = $('
'); this.$range = $('
').insertAfter(this.$element).prepend(this.$fill, this.$handle); // visually hide the input this.$element.css({ 'position': 'absolute', 'width': '1px', 'height': '1px', 'overflow': 'hidden', 'opacity': '0' }); // Store context this.handleDown = $.proxy(this.handleDown, this); this.handleMove = $.proxy(this.handleMove, this); this.handleEnd = $.proxy(this.handleEnd, this); this.init(); // Attach Events var _this = this; this.$window.on('resize.' + this.identifier, debounce(function() { // Simulate resizeEnd event. delay(function() { _this.update(false, false); }, 300); }, 20)); this.$document.on(this.startEvent, '#' + this.identifier + ':not(.' + this.options.disabledClass + ')', this.handleDown); // Listen to programmatic value changes this.$element.on('change.' + this.identifier, function(e, data) { if (data && data.origin === _this.identifier) { return; } var value = e.target.value, pos = _this.getPositionFromValue(value); _this.setPosition(pos); }); } Plugin.prototype.init = function() { this.update(true, false); if (this.onInit && typeof this.onInit === 'function') { this.onInit(); } }; Plugin.prototype.update = function(updateAttributes, triggerSlide) { updateAttributes = updateAttributes || false; if (updateAttributes) { this.min = tryParseFloat(this.$element[0].getAttribute('min'), 0); this.max = tryParseFloat(this.$element[0].getAttribute('max'), 100); this.value = tryParseFloat(this.$element[0].value, Math.round(this.min + (this.max-this.min)/2)); this.step = tryParseFloat(this.$element[0].getAttribute('step'), 1); } this.handleDimension = getDimension(this.$handle[0], 'offset' + ucfirst(this.DIMENSION)); // this.handleDimension = 1; this.rangeDimension = getDimension(this.$range[0], 'offset' + ucfirst(this.DIMENSION)); this.maxHandlePos = this.rangeDimension - this.handleDimension; this.grabPos = this.handleDimension / 2; this.position = this.getPositionFromValue(this.value); // Consider disabled state if (this.$element[0].disabled) { this.$range.addClass(this.options.disabledClass); } else { this.$range.removeClass(this.options.disabledClass); } this.setPosition(this.position, triggerSlide); }; Plugin.prototype.handleDown = function(e) { e.preventDefault(); // Only respond to mouse main button clicks (usually the left button) if (e.button && e.button !== 0) { return; } this.$document.on(this.moveEvent, this.handleMove); this.$document.on(this.endEvent, this.handleEnd); // add active class because Firefox is ignoring // the handle:active pseudo selector because of `e.preventDefault();` this.$range.addClass(this.options.activeClass); // If we click on the handle don't set the new position if ((' ' + e.target.className + ' ').replace(/[\n\t]/g, ' ').indexOf(this.options.handleClass) > -1) { return; } var pos = this.getRelativePosition(e), rangePos = this.$range[0].getBoundingClientRect()[this.DIRECTION], handlePos = this.getPositionFromNode(this.$handle[0]) + rangePos, setPos = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos); this.setPosition(setPos); if (pos >= handlePos && pos < handlePos) { this.grabPos = pos - handlePos; } }; Plugin.prototype.handleMove = function(e) { e.preventDefault(); var pos = this.getRelativePosition(e); var setPos = (this.orientation === 'vertical') ? (this.maxHandlePos - (pos - this.grabPos)) : (pos - this.grabPos); this.setPosition(setPos); }; Plugin.prototype.handleEnd = function(e) { e.preventDefault(); this.$document.off(this.moveEvent, this.handleMove); this.$document.off(this.endEvent, this.handleEnd); this.$range.removeClass(this.options.activeClass); // Ok we're done fire the change event this.$element.trigger('change', { origin: this.identifier }); if (this.onSlideEnd && typeof this.onSlideEnd === 'function') { this.onSlideEnd(this.position, this.value); } }; Plugin.prototype.cap = function(pos, min, max) { if (pos < min) { return min; } if (pos > max) { return max; } return pos; }; Plugin.prototype.setPosition = function(pos, triggerSlide) { var value, newPos; if (triggerSlide === undefined) { triggerSlide = true; } // Snapping steps value = this.getValueFromPosition(this.cap(pos, 0, this.maxHandlePos)); newPos = this.getPositionFromValue(value); // Update ui this.$fill[0].style[this.DIMENSION] = (newPos + this.grabPos) + 'px'; this.$handle[0].style[this.DIRECTION_STYLE] = newPos + 'px'; this.setValue(value); // Update globals this.position = newPos; this.value = value; if (triggerSlide && this.onSlide && typeof this.onSlide === 'function') { this.onSlide(newPos, value); } }; // Returns element position relative to the parent Plugin.prototype.getPositionFromNode = function(node) { var i = 0; while (node !== null) { i += node.offsetLeft; node = node.offsetParent; } return i; }; Plugin.prototype.getRelativePosition = function(e) { // Get the offset DIRECTION relative to the viewport var ucCoordinate = ucfirst(this.COORDINATE), rangePos = this.$range[0].getBoundingClientRect()[this.DIRECTION], pageCoordinate = 0; if (typeof e.originalEvent['client' + ucCoordinate] !== 'undefined') { pageCoordinate = e.originalEvent['client' + ucCoordinate]; } else if ( e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0]['client' + ucCoordinate] !== 'undefined' ) { pageCoordinate = e.originalEvent.touches[0]['client' + ucCoordinate]; } else if(e.currentPoint && typeof e.currentPoint[this.COORDINATE] !== 'undefined') { pageCoordinate = e.currentPoint[this.COORDINATE]; } return pageCoordinate - rangePos; }; Plugin.prototype.getPositionFromValue = function(value) { var percentage, pos; percentage = (value - this.min)/(this.max - this.min); pos = (!Number.isNaN(percentage)) ? percentage * this.maxHandlePos : 0; return pos; }; Plugin.prototype.getValueFromPosition = function(pos) { var percentage, value; percentage = ((pos) / (this.maxHandlePos || 1)); value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min; return Number((value).toFixed(this.toFixed)); }; Plugin.prototype.setValue = function(value) { if (value === this.value && this.$element[0].value !== '') { return; } // Set the new value and fire the `input` event this.$element .val(value) .trigger('input', { origin: this.identifier }); }; Plugin.prototype.destroy = function() { this.$document.off('.' + this.identifier); this.$window.off('.' + this.identifier); this.$element .off('.' + this.identifier) .removeAttr('style') .removeData('plugin_' + pluginName); // Remove the generated markup if (this.$range && this.$range.length) { this.$range[0].parentNode.removeChild(this.$range[0]); } }; // A really lightweight plugin wrapper around the constructor, // preventing against multiple instantiations $.fn[pluginName] = function(options) { var args = Array.prototype.slice.call(arguments, 1); return this.each(function() { var $this = $(this), data = $this.data('plugin_' + pluginName); // Create a new instance. if (!data) { $this.data('plugin_' + pluginName, (data = new Plugin(this, options))); } // Make it possible to access methods from public. // e.g `$element.rangeslider('method');` if (typeof options === 'string') { data[options].apply(data, args); } }); }; return 'rangeslider.js is available in jQuery context e.g $(selector).rangeslider(options);'; }));

// Mixer v2.01 // console.log('mixer 2.06'); function Mixer() { this.context; this.isPlaying = false; this.isLoaded = false; this.channels = []; this.interface; this.playlist; this.selectors; this.maxChannels = 8; this.timerInterval = null; this.duration = 0; this.currentTime = 0; this.channelLevels = [[],[]]; this.channelsActive = 0; this.masterGainLevel = 1; this.domain = "https://domaind56137.us.stackstaging.com" this.bg = 'eastwest_web-mixer_3@2x.jpg'; this.$master = $('
'); this.$gain = $('
'); this.$interface = $('
'); this.$media = $('

0:00

0:00

'); this.$overlay = $('

Please rotate your phone in horizontal mode

'); } Mixer.prototype.init = function() { var $this = this; this.context = new (window.AudioContext || window.webkitAudioContext)(); var $meter = $('
'); var $channels = $('
'); for(var i = 0; i < this.maxChannels; i++) { var channel = new Channel(this); var $channel = channel.$channel; channel.number = (i+1); $(channel.$pan).appendTo($channel); $(channel.$volume).appendTo($channel); $(channel.$mute).appendTo($channel); $(channel.$solo).appendTo($channel); $(channel.$meter).appendTo($channel); $this.channels.push(channel); $channels.append($channel); channel.setPan(this,0.5); } this.$gain.appendTo(this.$master); $meter.appendTo(this.$master); this.$interface.append(this.$media); this.$interface.append($channels); this.$interface.append(this.$master); this.$interface.append(this.$overlay); this.interface.append(this.$interface); var width = $this.$interface.width(); $this.size(width); this.$interface.on('touchstart',function(e){ document.documentElement.style.overflow = 'hidden'; }); $(document).on('touchend', function(e) { document.documentElement.style.overflow = 'auto'; }); $this.$gain.on('mousedown touchstart',function(e){ var y = _mixerCoords(e); var coordStart = y; var lastCoord = y; var $gain = $(e.target).parents('.master-gain'); $(this).on("mousemove touchmove",function(e){ e.preventDefault(); var yy = _mixerCoords(e); var coord = yy; if(coord > coordStart) { if(coord > lastCoord) $this.masterGainLevel -= (coord - lastCoord) * 0.01; else $this.masterGainLevel += (lastCoord - coord) * 0.01; } else { if(coord < lastCoord) $this.masterGainLevel -= (coord - lastCoord) * 0.01; else $this.masterGainLevel += (lastCoord - coord) * 0.01; } if($this.masterGainLevel > 2) $this.masterGainLevel = 2; else if($this.masterGainLevel > 0.98 && $this.masterGainLevel <= 1.01) $this.masterGainLevel = 1; else if($this.masterGainLevel < 0.01) $this.masterGainLevel = 0; lastCoord = yy; $this.setGain(width); }); }); $(document).on('mouseup touchend',function(e){ $($this.$gain).off("mousemove touchmove"); }); this.interface.find('.media-play').click(function(){ if(!$this.isLoaded) $this.load(true); else if(!$this.isPlaying) $this.play($this.currentTime); else $this.stop(); return false; }); this.interface.find('.media-rewind').click(function(){ $this.currentTime = 0; $this.interface.find('.duration-current').text('0:00'); $this.interface.find('.progress-bar').css('width','0%'); if($this.isPlaying) $this.stop(); $this.play(0); return false; }); this.interface.find('.media-forward').click(function(){ if(!$this.duration) return false; if($this.isPlaying) $this.stop(); $this.currentTime = 0; $this.interface.find('.duration-current').text($this.formatTime($this.duration)); $this.interface.find('.progress-bar').css('width','100%'); return false; }); var isDragging = false; this.interface.find('.progress-bar-container').mousedown(function(e){ isDragging = true; var $t = $(this); var newWidth = (e.pageX - $t.offset().left); $t.on("mousemove",function(e){ newWidth = (e.pageX - $t.offset().left); $this.interface.find('.progress-bar').css('width',newWidth+'px'); }); $t.on("mouseup",function(e){ $t.off("mousemove"); if($this.isPlaying) { var width = $t.width(); var newWidth = $this.interface.find('.progress-bar').width(); var seconds = ((newWidth / width) * $this.duration); $this.stop(); $this.play(seconds); $this.currentTime = seconds; $this.interface.find('.duration-current').text($this.formatTime($this.currentTime)); isDragging = false; } }); $this.interface.find('.progress-bar').css('width',newWidth+'px'); return false; }); this.interface.mouseup(function(){ if(isDragging) { var $t = $this.interface.find('.progress-bar-container'); var width = $t.width(); var newWidth = $this.interface.find('.progress-bar').width(); var seconds = ((newWidth / width) * $this.duration); $this.stop(); $this.play(seconds); $this.currentTime = seconds; $this.interface.find('.duration-current').text($this.formatTime($this.currentTime)); isDragging = false; $t.off("mousemove"); } }); $(document).ready(function(){ if($this.playlist.filter('.mixer-demo.selected').length) $this.load(); // else // $this.setDemo($this.playlist.filter('.mixer-demo:eq(0)').addClass('selected')); if($this.selectors && $this.selectors.length) { $this.selectors.click(function(){ if($this.isPlaying) $this.stop(); if($this.$interface.find('.mobile-overlay').is(':visible')) return false; $this.selectors.removeClass('active'); $(this).addClass('active'); var id = $(this).attr('data-id'); $this.playlist.removeClass('selected'); $this.playlist.filter('#'+id).addClass('selected'); $this.load(); return false; }); } else { var selector = ''; $this.playlist.each(function(){ selector += ''; }); $this.$media.find('select.title-select').append(selector).trigger("chosen:updated"); $('select.title-select').chosen().change(function(e){ var id = $(this).val(); if(id != "#") { $this.playlist.removeClass('selected'); $this.playlist.filter('#mixer-'+id).addClass('selected'); $this.load(); } return false; }); } /* $this.interface.hover(function() { $("body").css("overflow","hidden"); }, function() { $("body").css("overflow","auto"); }); */ $(window).resize(function(){ var width = $this.$interface.width(); $this.size(width,true); $this.setGain(width,true); $this.interface.find('input[type="range"]').rangeslider('update', true); }); }); $(window).load(function(){ $this.interface.find('input[type="range"]').rangeslider({ polyfill: false }); }); } Mixer.prototype.size = function(width) { var sizes = { 'largest':1000, 'large':768, 'medium':540, 'small':480 }; for(var size in sizes) { if(sizes[size] < width) { if(!this.interface.hasClass(size)) this.interface.addClass(size); } else if(this.interface.hasClass(size)) { this.interface.removeClass(size); } } var mixerWidth = 1077; var scale = (Math.round((width / mixerWidth)*100)); var rounded = (((Math.ceil(scale/5)*5) + 5) * .01); // console.log('scale: ' + scale + ' / ' + fives); if(rounded > 1) rounded = 1; this.$gain.find('.master-gain-inner').css('transform','scale('+rounded+') translate(-50%, -50%)'); } Mixer.prototype.setGain = function(width,init) { var deg = Math.round(this.masterGainLevel * 50); if(deg > 100) deg = 100; var position = 135; this.$gain.find('.master-gain-inner').css('background-position-y', '-'+(deg * position) + 'px'); if(init) return true; for(var i = 0; i < this.channels.length; i++) { if(this.channels[i].isLoaded) this.channels[i].gain.gain.value = this.masterGainLevel; } } Mixer.prototype.setDemo = function($demo) { var title = $demo.attr('data-title') || ""; var creator = $demo.attr('data-creator') || ""; $('.mixer .media-title .chosen-container .chosen-single span').text(title); this.$media.find('.media-title h5').html(creator); // this.$media.find('select.title-select').val($demo.attr('id').replace('mixer-','')); } Mixer.prototype.load = function(autoPlay) { // console.log('loading..'); if(!this.playlist.filter('.selected').length) { this.$media.find('select.title-select').trigger("chosen:open"); return false; } this.$interface.addClass('loading'); var $this = this; if(this.isLoaded) this.destroy(); $this.playlist.filter('.selected').each(function(){ $this.channelsActive = $(this).find('.track').length; $this.setDemo($(this)); var number = 0; $(this).find('.track').each(function(){ $this.channels[number].init($this); $this.channelLevels[0].push(0); $this.channelLevels[1].push(0); $this.channels[number].load($this,$(this),autoPlay); number++; }); for(var i = 0; i < $this.maxChannels; i++) { if(i + 1 <= $this.channelsActive) $this.channels[i].fade(0.84); else $this.channels[i].fade(0); $this.channels[i].setPan(this,0.5); } }); }; Mixer.prototype.destroy = function(soft) { // console.log('destroying mixer..'); if(this.isPlaying) this.stop(); if(!soft) { for(var i = 0; i < this.channels.length; i++) this.channels[i].destroy(); this.isLoaded = false; this.duration = 0; this.$interface.find('.track-title').text(''); this.$interface.find('.mixer-button.mute, .mixer-button.solo').removeClass('active'); this.$interface.find('.channel').removeClass('loaded'); } clearInterval(this.timerInterval); this.channelLevels = [[],[]]; this.currentTime = 0; this.$interface.find('.media-play').removeClass('is-playing'); this.$interface.find('.progress-bar').css('width','0px'); this.$interface.find('.meter .meter-fill').css('height','0px'); this.$interface.find('.duration-current').text('0:00'); this.$interface.find('.channel .volume').addClass('off'); } Mixer.prototype.play = function(time) { if(!this.isLoaded || this.isPlaying) return false; else if(!time) { time = 0; this.$interface.find('.progress-bar').css('width','0px'); this.$interface.find('.meter .meter-fill').css('height','0px'); this.$interface.find('.duration-current').text('0:00'); } for(var i = 0; i < this.channels.length; i++) this.channels[i].play(this,time); this.interface.find('.media-play').addClass('is-playing'); this.isPlaying = true; this.timerInterval = setInterval(this.timer, 1000, this); }; Mixer.prototype.stop = function() { for(var i = 0; i < this.channels.length; i++) { this.channels[i].stop(); this.channelLevels[0][i] = 0; this.channelLevels[1][i] = 0; } this.$interface.find('.channel.loaded .meter .meter-fill, .master-controls .meter .meter-fill').css('height','0%'); this.$interface.find('.media-play').removeClass('is-playing'); this.isPlaying = false; clearInterval(this.timerInterval); }; Mixer.prototype.timer = function(mixer) { mixer.currentTime++; if(mixer.currentTime >= mixer.duration) { mixer.destroy(true); return false; } mixer.$interface.find('.duration-current').text(mixer.formatTime(mixer.currentTime)); var width = mixer.$interface.find('.progress-bar-container').width(); var currentWidth = (width / mixer.duration) * mixer.currentTime; mixer.$interface.find('.progress-bar').css('width',((currentWidth / width) * 100).toFixed(2)+'%'); }; Mixer.prototype.formatTime = function(seconds) { var minutes = Math.floor(seconds / 60); var remainer = Math.round(seconds - minutes * 60); return (minutes+':'+(remainer < 10 ? '0' : '')+remainer); } function Channel(mixer) { this.number = 0; this.url; this.audioBuffer; this.analyser; this.volumeLevel = .84; this.panLevel = 0; this.jsNode; this.isLoaded = false; this.$channel = $('
'); this.$pan = $('
'); this.$volume = $('
'); this.$mute = $('
'); this.$solo = $('
'); this.$meter = $('
'); var $this = this; var $pan = this.$pan; $this.$channel.on('mousedown touchstart',function(e){ var y = _mixerCoords(e); var coordStart = y; var lastCoord = y; if(!$(e.target).hasClass('.top') && $(e.target).parents('.pan').length) { $(this).on("mousemove touchmove",function(e){ e.preventDefault(); var yy = _mixerCoords(e); var coord = yy; if(coord > coordStart) { if(coord > lastCoord) $this.panLevel -= (coord - lastCoord) * 0.01; else $this.panLevel += (lastCoord - coord) * 0.01; } else { if(coord < lastCoord) $this.panLevel -= (coord - lastCoord) * 0.01; else $this.panLevel += (lastCoord - coord) * 0.01; } if($this.panLevel > 1) $this.panLevel = 1; lastCoord = yy; $this.setPan(mixer); }); } }); $(document).on('mouseup touchend',function(e){ $this.$channel.off("mousemove touchmove"); }); this.$volume.find('.slider').on("input change",function(){ if(!$(this).parents('.channel').hasClass('loaded')) return false; $this.volumeLevel = parseFloat($(this).val()); $this.setVolume($this.volumeLevel); }); this.$mute.click(function(){ if(!$(this).parents('.channel').hasClass('loaded')) return false; if($(this).hasClass('active')) $this.volumeLevel = $this.$volume.find('input').val() else $this.volumeLevel = 0; $this.setVolume($this.volumeLevel); $(this).toggleClass('active'); $this.$volume.toggleClass('off'); return false; }); this.$solo.click(function(){ if(!$(this).parents('.channel').hasClass('loaded')) return false; $(this).toggleClass('active'); mixer.$interface.find('.channel .mute').removeClass('active'); if($(this).hasClass('active')) mixer.$interface.find('.channel.loaded .solo').not(this).removeClass('active'); for(var i = 0; i < mixer.channels.length; i++) { if($(this).hasClass('active') && i != ($this.number - 1)) { mixer.channels[i].setVolume(0); mixer.channels[i].$mute.addClass('active'); } else { mixer.channels[i].setVolume(mixer.channels[i].$volume.find('input').val()); } } return false; }); } Channel.prototype.init = function(mixer) { this.source = mixer.context.createBufferSource(); this.pan = mixer.context.createPanner(); this.pan.panningModel = 'equalpower'; this.gain = mixer.context.createGain(); this.volume = mixer.context.createGain(); this.mute = mixer.context.createGain(); this.gain.gain.value = mixer.masterGainLevel; this.volume.gain.value = this.volumeLevel; this.mute.gain.value = 0; this.analyser = mixer.context.createAnalyser(); this.analyser.smoothingTimeConstant = 0.3; this.analyser.fftSize = 1024; var $this = this; this.jsNode = mixer.context.createScriptProcessor(2048, 1, 1); this.jsNode.onaudioprocess = function() { var num = $this.number - 1; var level = 0; var masterGainLeft = 0; var masterGainRight = 0; if(mixer.isPlaying) { var array = new Uint8Array($this.analyser.frequencyBinCount); $this.analyser.getByteFrequencyData(array); var panLeft = 1; var panRight = 1; var avg = average(array); level = (avg * ($this.volume.gain.value * 100)/100); if($this.panLevel < 0.0) panRight = (1 + $this.panLevel); else if($this.panLevel > 0.0) panLeft = (1 - $this.panLevel); mixer.channelLevels[0][num] = (level * panLeft); mixer.channelLevels[1][num] = (level * panRight); var highestLeft = Math.max.apply(Math,mixer.channelLevels[0]); var highestRight = Math.max.apply(Math,mixer.channelLevels[1]); masterGainLeft = Math.round((highestLeft) * mixer.masterGainLevel); masterGainRight = Math.round((highestRight) * mixer.masterGainLevel); if(highestLeft == mixer.channelLevels[0][num] && panLeft < 1) masterGainLeft = (masterGainLeft * panLeft); if(highestRight == mixer.channelLevels[1][num] && panRight < 1) masterGainRight = (masterGainRight * panRight); } else { mixer.channelLevels[0][num] = 0; mixer.channelLevels[1][num] = 0; } $this.$meter.find('.meter-left .meter-fill').css('height',mixer.channelLevels[0][num] + "%"); $this.$meter.find('.meter-right .meter-fill').css('height',mixer.channelLevels[1][num] + "%"); mixer.$interface.find('.master-controls .meter-left .meter-fill').css('height', masterGainLeft+"%"); mixer.$interface.find('.master-controls .meter-right .meter-fill').css('height', masterGainRight+"%"); } function average(nums) { var total = 0; for(var i = 0; i < nums.length; i++) total += nums[i]; return (total / nums.length); } this.source.connect(this.volume); this.volume.connect(this.gain); this.gain.connect(this.pan); this.pan.connect(mixer.context.destination); this.jsNode.connect(mixer.context.destination); this.analyser.connect(this.jsNode); } Channel.prototype.setPan = function(mixer) { var deg = Math.round((this.panLevel + .5) * 100); if(deg > 47 && deg < 53) deg = 50; else if(deg > 100) deg = 100; var position = (deg * 63); this.$pan.css('background-position-y', '-'+position + 'px'); if(mixer.isLoaded && this.isLoaded) this.pan.setPosition(this.panLevel, 0, 1 - Math.abs(this.panLevel)); }; Channel.prototype.setVolume = function(level) { if(this.isLoaded) this.volume.gain.value = level; } Channel.prototype.fade = function(level) { var $this = this; var interval = function() { var cur = (Math.round(parseFloat($this.$volume.find('.slider').val()) * 100) / 100); if(cur < level) $this.$volume.find('.slider').val(cur + 0.01).change(); else if(cur > level) $this.$volume.find('.slider').val(cur - 0.01).change(); else clearInterval(motion); } var motion = setInterval(interval, 1); } Channel.prototype.destroy = function() { if(!this.isLoaded) return false; this.isLoaded = false; this.volumeLevel = .84; this.panLevel = 0; this.jsNode.onaudioprocess = null; // this.jsNode = null; this.audioBuffer = null; this.gain.disconnect(); this.volume.disconnect(); this.mute.disconnect(); this.source.disconnect(); // this.analyser = null; }; Channel.prototype.play = function(mixer,time) { if(!this.isLoaded) return false; else if(!time) time = 0; this.source = mixer.context.createBufferSource(); this.source.buffer = this.audioBuffer; this.source.connect(this.analyser); this.source.connect(this.volume); this.source.start(0,time); }; Channel.prototype.stop = function() { if(this.isLoaded) this.source.stop(0); }; Channel.prototype.load = function(mixer,$elem,autoPlay) { // console.log('channel '+this.number+' loading'); this.url = $elem.attr('data-url'); mixer.$interface.find('.channel:eq('+(this.number-1)+') .track-title').text($elem.attr('data-title')); var $this = this; var request = new XMLHttpRequest(); if ("withCredentials" in request){ request.open('GET', $this.url, true); } else if (typeof XDomainRequest != "undefined"){ request = new XDomainRequest(); request.open('GET', $this.url); } else { request = null; } if(request) { request.responseType = 'blob'; request.onload = function() { var reader = new FileReader(); reader.readAsArrayBuffer(request.response); reader.onload = function(e){ mixer.context.decodeAudioData(this.result, function(buffer) { $this.audioBuffer = buffer; $this.isLoaded = true; mixer.$interface.find('.channel:eq('+($this.number-1)+')').addClass('loaded'); $this.loaded(mixer,autoPlay); }); }; }; request.send(); } }; Channel.prototype.loaded = function(mixer,autoPlay) { if(mixer.channelsActive <= mixer.$interface.find('.channel.loaded').length) { // console.log('loaded!'); mixer.isLoaded = true; mixer.duration = mixer.channels[0].audioBuffer.duration; mixer.$interface.find('.channel.loaded .volume').removeClass('off'); mixer.$interface.find('.media .duration-total').text(mixer.formatTime(mixer.duration)); mixer.$interface.find('.meter .meter-fill').show().css('height','2px'); mixer.$interface.addClass('loaded'); mixer.$interface.removeClass('loading'); if(autoPlay) { mixer.play(); } } }; function _mixerCoords(e) { var y = 0; if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){ var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; y = touch.pageY; } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') { y = e.clientY; } return y; } var mixer = new Mixer(); mixer.interface = $('.mixer'); mixer.playlist = $('.mixer-demo'); // mixer.selectors = $('.mixer-selector'); mixer.init();