1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- class PCMPlayer
- {
- constructor(channels, sampleRate)
- {
- this._samples = new Float32Array();
- this._flushingTime = 200;
- this._channels = channels;
- this._sampleRate = sampleRate;
- this._flush = this._flush.bind(this);
- this._audioCtx = new (window.AudioContext || window.webkitAudioContext)();
- this._gainNode = this._audioCtx.createGain();
- this._gainNode.gain.value = 1;
- this._gainNode.connect(this._audioCtx.destination);
- this._startTime = this._audioCtx.currentTime;
- this._interval = setInterval(this._flush, this._flushingTime);
- }
- setVolume(volume)
- {
- this._gainNode.gain.value = volume;
- }
- close()
- {
- if(this._interval)
- {
- clearInterval(this._interval);
- }
- this._audioCtx.close();
- };
- feed(data)
- {
- let tmp = new Float32Array(this._samples.length + data.length);
- tmp.set(this._samples, 0);
- tmp.set(data, this._samples.length);
- this._samples = tmp;
- };
- _flush()
- {
- if(!this._channels || !this._sampleRate || !this._samples.length)
- {
- return;
- }
- let bufferSource = this._audioCtx.createBufferSource();
- let length = this._samples.length / this._channels;
- let audioBuffer = this._audioCtx.createBuffer(this._channels, length, this._sampleRate);
- for (let channel = 0; channel != this._channels; ++channel)
- {
- let audioData = audioBuffer.getChannelData(channel);
- let offset = channel;
- let decrement = 50;
- for (let i = 0; i != length; ++i)
- {
- audioData[i] = this._samples[offset];
- if (i < 50)
- {
- audioData[i] = (audioData[i] * i) / 50;
- }
- if (i >= (length - 51))
- {
- audioData[i] = (audioData[i] * decrement--) / 50;
- }
- offset += this._channels;
- }
- }
-
- if (this._startTime < this._audioCtx.currentTime)
- {
- this._startTime = this._audioCtx.currentTime;
- }
- bufferSource.buffer = audioBuffer;
- bufferSource.connect(this._gainNode);
- bufferSource.start(this._startTime);
- this._startTime += audioBuffer.duration;
- this._samples = new Float32Array();
- }
- }
|