如何使用Audioworklet编码振荡器?

时间:2019-09-13 10:28:59

标签: web-audio-api audio-worklet

class MyOsc extends AudioWorkletProcessor {

  // When constructor() undefined, the default constructor will be
  // implicitly used.

  static get parameterDescriptors() {
    return [{
      name: 'frequency',
      defaultValue: 440,
      minValue: 0,
      maxValue: 0.5 * sampleRate
    }];
  }

  process(inputs, outputs, parameters) {
    // By default, the node has a single output.

    const output = outputs[0];

    const frequency = parameters.frequency;
    var outputChannel = output[0];


    for (let i = 0; i < outputChannel.length; ++i) {

      val = 0;                 // <=== what here?!

      outputChannel[i] = val;

    }

    return true;
  }
}

registerProcessor('myosc', MyOsc);

1 个答案:

答案 0 :(得分:0)

这将创建一个基本的正弦振荡器:

// processor.js
class Oscillator extends AudioWorkletProcessor {
  prevFreq = 440
  d = 0
  static get parameterDescriptors() {
    return [{
      name: 'frequency',
      defaultValue: 440,
      minValue: 0,
      maxValue: 0.5 * sampleRate,
      automationRate: "a-rate"
    }];
  }
  process (inputs, outputs, parameters) {
    const output = outputs[0]
    const freqs = parameters.frequency
    output.forEach(channel => {
      for (let i = 0; i < channel.length; i++) {
        const freq = freqs.length > 1 ? freqs[i] : freqs[0]
        const globTime = currentTime + i / sampleRate
        this.d += globTime * (this.prevFreq - freq)
        this.prevFreq = freq
        const time = globTime * freq + this.d
        const vibrato = 0 // Math.sin(globTime * 2 * Math.PI * 7) * 2
        channel[i] = Math.sin(2 * Math.PI * time + vibrato)
      }
    })
    return true
  }
}

registerProcessor('oscillator', Oscillator)
//script.js
const audioContext = new AudioContext();
audioContext.audioWorklet.addModule('processor.js').then(() => {
    const osc = new AudioWorkletNode(audioContext, 'oscillator');
    osc.connect(audioContext.destination)
    const freq = osc.parameters.get('frequency')
    const time = audioContext.currentTime
    freq.setValueAtTime(440, time + 1)
    freq.linearRampToValueAtTime(660, time + 1.5)
    setTimeout(()=>audioContext.close(), 5000)
});

尝试: https://next.plnkr.co/edit/DqYuLBrpWCo5Ks75