all files / src/plugins/ VueNoiseGeneratorPlugin.js

15.58% Statements 12/77
43.75% Branches 7/16
5.56% Functions 1/18
10.96% Lines 8/73
1 branch Ignored     
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                                                                                                                                                                                                                                             
// plugins/VueNoiseGenerator.js
import _ from 'underscore'
 
// Thanks to this great tutorial: http://noisehack.com/generate-noise-web-audio-api/
var audioContext, bufferSize, noise
 
audioContext = {
  resume: function () {},
  suspend: function () {},
  fake: true
}
 
Iif (window.AudioContext || window.webkitAudioContext) {
  audioContext = new (window.AudioContext || window.webkitAudioContext)()
}
 
function generateWhiteNoise () {
  var noiseBuffer, output
 
  bufferSize = 2 * audioContext.sampleRate
  noiseBuffer = audioContext.createBuffer(1, bufferSize, audioContext.sampleRate)
 
  output = noiseBuffer.getChannelData(0)
  _.times(bufferSize, i => {
    output[i] = Math.random() * 2 - 1
  })
 
  noise = audioContext.createBufferSource()
  noise.buffer = noiseBuffer
  noise.loop = true
  noise.start(0)
 
  return noise
}
 
function generatePinkNoise () {
  bufferSize = 4096
  noise = (function () {
    var b0, b1, b2, b3, b4, b5, b6, node
    b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0
    node = audioContext.createScriptProcessor(bufferSize, 1, 1)
    node.onaudioprocess = function (e) {
      var output
 
      output = e.outputBuffer.getChannelData(0)
      _.times(bufferSize, i => {
        var white = Math.random() * 2 - 1
        b0 = 0.99886 * b0 + white * 0.0555179
        b1 = 0.99332 * b1 + white * 0.0750759
        b2 = 0.96900 * b2 + white * 0.1538520
        b3 = 0.86650 * b3 + white * 0.3104856
        b4 = 0.55000 * b4 + white * 0.5329522
        b5 = -0.7616 * b5 - white * 0.0168980
        output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362
        output[i] *= 0.11 // (roughly) compensate for gain
        b6 = white * 0.115926
      })
    }
    return node
  })()
 
  return noise
}
 
function generateBrownNoise () {
  bufferSize = 4096
 
  noise = (function () {
    var lastOut, node
 
    lastOut = 0.0
    node = audioContext.createScriptProcessor(bufferSize, 1, 1)
    node.onaudioprocess = function (e) {
      var output = e.outputBuffer.getChannelData(0)
      _.times(bufferSize, i => {
        var white = Math.random() * 2 - 1
        output[i] = (lastOut + (0.02 * white)) / 1.02
        lastOut = output[i]
        output[i] *= 3.5 // (roughly) compensate for gain
      })
    }
    return node
  })()
 
  return noise
}
 
export default {
  install: function (Vue) {
    Vue.directive('noise', (value) => {
      var noise
 
      if (audioContext.fake) {
        return
      }
      switch (value) {
        case 'white':
          noise = generateWhiteNoise()
          break
        case 'pink':
          noise = generatePinkNoise()
          break
        case 'brown':
          noise = generateBrownNoise()
          break
        default:
          noise = generateWhiteNoise()
      }
      noise.connect(audioContext.destination)
      audioContext.suspend()
    })
    Vue.noise = {
      start () {
        audioContext.resume()
      },
      pause () {
        audioContext.suspend()
      },
      stop () {
        audioContext.suspend()
      }
    }
  }
}