Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | 1x 4x 4x 4x 1x 4x 4x 3x 3x 4x 4x 4x 4x 4x 6x 6x | import { on } from '@ember/object/evented'; import EmberObject from '@ember/object'; /** * An instance of the Sampler class behaves just like a Sound, but allows * many {{#crossLink "AudioBuffer"}}AudioBuffers{{/crossLink}} to exist and * automatically alternately plays them (round-robin) each time any of the play * methods are called. * * @public * @class Sampler * * @todo humanize gain and time - should be optional and customizable * @todo loop */ const Sampler = EmberObject.extend({ /** * Determines the gain applied to each sample. * * @public * @property gain * @type {number} * @default 1 */ gain: 1, /** * Determines the stereo pan position of each sample. * * @public * @property pan * @type {number} * @default 0 */ pan: 0, /** * Temporary storage for the iterable that comes from the sounds Set. * This iterable is meant to be replaced with a new copy every time it reaches * it's end, resulting in an infinite stream of Sound instances. * * @private * @property _soundIterator * @type {Iterator} * */ _soundIterator: null, /** * Acts as a register for loaded audio sources. Audio sources can be anything * that uses {{#crossLink "Playable"}}{{/crossLink}}. If not set on * instantiation, automatically set to `new Set()` via `_initSounds`. * * @public * @property sounds * @type {set} */ sounds: null, /** * Gets the next audio source and plays it immediately. * * @public * @method play */ play() { this._getNextSound().play(); }, /** * Gets the next Sound and plays it after the specified offset has elapsed. * * @public * @method playIn * * @param {number} seconds Number of seconds from "now" that the next Sound * should be played. */ playIn(seconds) { this._getNextSound().playIn(seconds); }, /** * Gets the next Sound and plays it at the specified moment in time. A * "moment in time" is measured in seconds from the moment that the * {{#crossLink "AudioContext"}}{{/crossLink}} was instantiated. * * @param {number} time The moment in time (in seconds, relative to the * {{#crossLink "AudioContext"}}AudioContext's{{/crossLink}} "beginning of * time") when the next Sound should be played. * * @public * @method playAt */ playAt(time) { this._getNextSound().playAt(time); }, /** * Gets _soundIterator and returns it's next value. If _soundIterator has * reached it's end, replaces _soundIterator with a fresh copy from sounds * and returns the first value from that. * * @private * @method _getNextSound * @return {Sound} */ _getNextSound() { let soundIterator = this.get('_soundIterator'); let nextSound; if (!soundIterator) { soundIterator = this.get('sounds').values(); } nextSound = soundIterator.next(); if (nextSound.done) { soundIterator = this.get('sounds').values(); nextSound = soundIterator.next(); } this.set('_soundIterator', soundIterator); return this._setGainAndPan(nextSound.value); }, /** * Applies the `gain` and `pan` properties from the Sampler instance to a * Sound instance and returns the Sound instance. * * @private * @method _setGainAndPan * @return {Sound} The input sound after having it's gain and pan set */ _setGainAndPan(sound) { sound.changeGainTo(this.get('gain')).from('ratio'); sound.changePanTo(this.get('pan')); return sound; }, /** * Sets `sounds` to `new Set()` if null on instantiation. * * @private * @method _initSounds */ _initSounds: on('init', function() { Eif (!this.get('sounds')) { this.set('sounds', new Set()); } }) }); export default Sampler; |