Skip to content

Instantly share code, notes, and snippets.

@0x07dc
Forked from asanoboy/makewav.js
Created June 8, 2014 11:51

Revisions

  1. @asanoboy asanoboy revised this gist Oct 30, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion makewav.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Wav = function(opt_params){
    var Wav = function(opt_params){

    /**
    * @private
  2. @asanoboy asanoboy created this gist Oct 30, 2012.
    138 changes: 138 additions & 0 deletions makewav.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    Wav = function(opt_params){

    /**
    * @private
    */
    this._sampleRate = opt_params && opt_params.sampleRate ? opt_params.sampleRate : 44100;

    /**
    * @private
    */
    this._channels = opt_params && opt_params.channels ? opt_params.channels : 2;

    /**
    * @private
    */
    this._eof = true;

    /**
    * @private
    */
    this._bufferNeedle = 0;

    /**
    * @private
    */
    this._buffer;

    };

    Wav.prototype.setBuffer = function(buffer){
    this._buffer = this.getWavInt16Array(buffer);
    this._bufferNeedle = 0;
    this._internalBuffer = '';
    this._hasOutputHeader = false;
    this._eof = false;
    };

    Wav.prototype.getBuffer = function(len){

    var rt;
    if( this._bufferNeedle + len >= this._buffer.length ){
    rt = new Int16Array(this._buffer.length - this._bufferNeedle);
    this._eof = true;
    }
    else {
    rt = new Int16Array(len);
    }

    for(var i=0; i<rt.length; i++){
    rt[i] = this._buffer[i+this._bufferNeedle];
    }
    this._bufferNeedle += rt.length;

    return rt.buffer;


    };

    Wav.prototype.eof = function(){
    return this._eof;
    };

    Wav.prototype.getWavInt16Array = function(buffer){

    var intBuffer = new Int16Array(buffer.length + 23), tmp;

    intBuffer[0] = 0x4952; // "RI"
    intBuffer[1] = 0x4646; // "FF"

    intBuffer[2] = (2*buffer.length + 15) & 0x0000ffff; // RIFF size
    intBuffer[3] = ((2*buffer.length + 15) & 0xffff0000) >> 16; // RIFF size

    intBuffer[4] = 0x4157; // "WA"
    intBuffer[5] = 0x4556; // "VE"

    intBuffer[6] = 0x6d66; // "fm"
    intBuffer[7] = 0x2074; // "t "

    intBuffer[8] = 0x0012; // fmt chunksize: 18
    intBuffer[9] = 0x0000; //

    intBuffer[10] = 0x0001; // format tag : 1
    intBuffer[11] = this._channels; // channels: 2

    intBuffer[12] = this._sampleRate & 0x0000ffff; // sample per sec
    intBuffer[13] = (this._sampleRate & 0xffff0000) >> 16; // sample per sec

    intBuffer[14] = (2*this._channels*this._sampleRate) & 0x0000ffff; // byte per sec
    intBuffer[15] = ((2*this._channels*this._sampleRate) & 0xffff0000) >> 16; // byte per sec

    intBuffer[16] = 0x0004; // block align
    intBuffer[17] = 0x0010; // bit per sample
    intBuffer[18] = 0x0000; // cb size
    intBuffer[19] = 0x6164; // "da"
    intBuffer[20] = 0x6174; // "ta"
    intBuffer[21] = (2*buffer.length) & 0x0000ffff; // data size[byte]
    intBuffer[22] = ((2*buffer.length) & 0xffff0000) >> 16; // data size[byte]

    for (var i = 0; i < buffer.length; i++) {
    tmp = buffer[i];
    if (tmp >= 1) {
    intBuffer[i+23] = (1 << 15) - 1;
    }
    else if (tmp <= -1) {
    intBuffer[i+23] = -(1 << 15);
    }
    else {
    intBuffer[i+23] = Math.round(tmp * (1 << 15));
    }
    }

    return intBuffer;
    };
    var i=0, vol=0.1,
    sampleRate = 48000,
    wav = new Wav({sampleRate: sampleRate, channels: 1}),
    buffer = new Float32Array(sampleRate);

    while(i<sampleRate){
    if( parseInt(i/100) % 2 ){
    buffer[i] = -vol;
    }
    else {
    buffer[i] = vol;
    }
    i++;
    }
    wav.setBuffer(buffer);

    var srclist = [];
    while( !wav.eof() ){
    srclist.push(wav.getBuffer(1000));
    }

    var b = new Blob(srclist, {type:'audio/wav'});
    var URLObject = window.webkitURL || window.URL;
    var url = URLObject.createObjectURL(b);
    document.write("<a href='"+url+"'>play</a>");