<!DOCTYPE html>
<html>
  <!--
  Copyright 2015 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
  -->
<head>
  <title>Audio Encoder Example</title>
  <script type="text/javascript">
    var plugin;
    var track;
    var writer;
    var profiles;

    function writeString(array, offset, string) {
      for (var i = 0; i < string.length; i++)
        array.set([string.charCodeAt(i)], i + offset);
      return string.length;
    }
    function writeValue(array, bytes, offset, value) {
      for (var i = 0; i < bytes; i++)
        array.set([((value >>> (i * 8)) & 0xff)], offset + i);
      return bytes;
    }

    var BufferArray = function() {
      this._arrays = [ this._createBuffer() ];
    };
    BufferArray.prototype = {
      _createBuffer: function() {
        var buffer = new Uint8Array(100 * 1024);
        buffer.dataLength = 0;
        return buffer;
      },
      appendData: function(data) {
        var currentBuffer = this._arrays[this._arrays.length - 1];
        if (currentBuffer.byteLength < (currentBuffer.dataLength + data.byteLength)) {
          this._arrays.push(this._createBuffer());
          currentBuffer = this._arrays[this._arrays.length - 1];
        }
        currentBuffer.set(new Uint8Array(data), currentBuffer.dataLength);
        currentBuffer.dataLength += data.byteLength;
      },
      getByte: function(offset) {
        var bufferOffset = 0;
        for (var i = 0; i < this._arrays.length; i++) {
          var buffer = this._arrays[i];
          if (offset < (bufferOffset + buffer.dataLength)) {
            return buffer[offset - bufferOffset];
          }
          bufferOffset += buffer.dataLength;
        }
        throw new Error('Out of range access');
      },
      getSize: function() {
        var size = 0;
        for (var i = 0; i < this._arrays.length; i++)
          size += this._arrays[i].dataLength;
        return size;
      },
      writeValue: function(bytes, offset, value) {
        var bufferOffset = 0;
        for (var i = 0; i < this._arrays.length; i++) {
          var buffer = this._arrays[i];
          if (offset < (bufferOffset + buffer.dataLength)) {
            writeValue(buffer, bytes, offset - bufferOffset, value);
            return;
          }
          bufferOffset += buffer.dataLength;
        }
        throw new Error('Out of range access');
      },
      toBlob: function() {
        var result = new Uint8Array(this.getSize());
        var offset = 0;
        for (var i = 0; i < this._arrays.length; i++) {
          var buffer = this._arrays[i];
          result.set(buffer.subarray(0, buffer.dataLength), offset);
          offset += buffer.dataLength;
        }
        return new Blob([result]);
      },
    };

    // Writes wav data.
    var WavWriter = function() {
      this.chunkSizeOffset = 0;
      this.buffer = new BufferArray();
    };
    WavWriter.prototype = {
      writeHeader: function(format) {
        var buffer =
          new Uint8Array(4 + 4 + 4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 4 + 4);
        var i = 0;
        // File header
        i += writeString(buffer, i, 'RIFF');
        i += 4; // Gap for final size.
        i += writeString(buffer, i, 'WAVE');
        // Chunk ID.
        i += writeString(buffer, i, 'fmt ');
        // Chunk length.
        i += writeValue(buffer, 4, i, 16);
        // Codec (uncompressed LPCM).
        i += writeValue(buffer, 2, i, 1);
        // Number of channels.
        i += writeValue(buffer, 2, i, format.channels);
        // Sample rate.
        i += writeValue(buffer, 4, i, format.sample_rate);
        // Average bytes per seconds (sample rate * bytes per sample)
        i += writeValue(buffer, 4, i,
                        format.sample_rate * format.sample_size);
        // Bytes per sample.
        i += writeValue(buffer, 2, i,
                        format.sample_size * format.channels);
        // Bits per sample.
        i += writeValue(buffer, 2, i, format.sample_size * 8);

        // Data chunk
        i += writeString(buffer, i, 'data');
        this.chunkSizeOffset = i; // Location of the chunk's size
        this.buffer.appendData(buffer);
      },
      writeData: function(data) {
        this.buffer.appendData(data);
      },
      end: function() {
        this.buffer.writeValue(4, 4, this.buffer.getSize() - 8);
        this.buffer.writeValue(4, this.chunkSizeOffset,
                               this.buffer.getSize() - this.chunkSizeOffset);
      },
      getSize: function() {
        return this.buffer.getSize();
      },
      getData: function() {
        return this.buffer;
      },
      getExtension: function() {
        return 'wav';
      },
    };

    // Writes ogg data.
    var OggWriter = function(profile) {
      this.writeHeader = this._writeOpusHeader;
      this.buffer = new BufferArray();
      this.pageSequence = 0;
      this.bitstreamNumber = 0;
      this.position = 0;
      this.dataWritten = false;
    };
    OggWriter.prototype = {
      _Start: 0x2,
      _Continue: 0x1,
      _Stop: 0x4,
      _makeCRCTable: function() {
        var crcTable = [];
        for (var n = 0; n < 256; n++) {
          var r = n << 24;
          for (var i = 0; i < 8; i++) {
            if (r & 0x80000000)
              r = (r << 1) ^ 0x04c11db7;
            else
              r <<= 1;
          }
          crcTable[n] = r & 0xffffffff;
        }
        return crcTable;
      },
      _crc32: function(data, start, end) {
        var crc = 0;
        var crcTable = this._crcTable || (this._crcTable = this._makeCRCTable());
        for (var i = start; i < end; i++)
          crc = (crc << 8) ^ crcTable[((crc >> 24) & 0xff) ^ data.getByte(i)];
        return crc;
      },
      _writePage: function(flag, size, position) {
        var pages = 1 + Math.floor(size / 255);
        var buffer = new Uint8Array(27 + pages), i = 0;
        // capture_pattern.
        i += writeString(buffer, i, 'OggS');
        // stream_structure_version.
        i += writeValue(buffer, 1, i, 0);
        // header_type_flag.
        i += writeValue(buffer, 1, i, flag);
        // granule_position.
        // TODO(llandwerlin): Not writing more than 32bits for now,
        // because Javascript doesn't have 64bits integers, this limits
        // the duration to ~24 hours at 48kHz sampling rate.
        i += writeValue(buffer, 4, i, position != undefined ? position : 0);
        i += writeValue(buffer, 4, i, 0);
        // bitstream_serial_number.
        i += writeValue(buffer, 4, i, this.bitstreamNumber);
        // page_sequence_number.
        i += writeValue(buffer, 4, i, this.pageSequence++);
        // CRC_checksum.
        i += writeValue(buffer, 4, i, 0);
        // number_page_segments.
        i += writeValue(buffer, 1, i, pages);
        // segment sizes.
        for (var j = 0; j < (pages - 1); j++)
          i += writeValue(buffer, 1, i, 255);
        i += writeValue(buffer, 1, i, size % 255);

        this.buffer.appendData(buffer);
      },
      _writePageChecksum: function(pageOffset) {
        var crc = this._crc32(this.buffer, pageOffset,
                              this.buffer.getSize());
        this.buffer.writeValue(4, pageOffset + 22, crc);
      },
      _writeOpusHeader: function(format) {
        this.format = format;
        var start = this.buffer.getSize();
        var buffer = new Uint8Array(8 + 1 + 1 + 2 + 4 + 2 + 1), i = 0;
        // Opus header.
        i += writeString(buffer, i, 'OpusHead');
        // version.
        i += writeValue(buffer, 1, i, 1);
        // channel count.
        i += writeValue(buffer, 1, i, format.channels);
        // pre-skip.
        i += writeValue(buffer, 2, i, 0);
        // input sample rate.
        i += writeValue(buffer, 4, i, format.sample_rate);
        // output gain.
        i += writeValue(buffer, 2, i, 0);
        // channel mapping family.
        i += writeValue(buffer, 1, i, 0);

        this._writePage(this._Start, buffer.byteLength);
        this.buffer.appendData(buffer);
        this._writePageChecksum(start);
        this._writeCommentHeader();
      },
      _writeCommentHeader: function(name) {
        var start = this.buffer.getSize();
        var buffer = new Uint8Array(8 + 4 + 8 + 4 + 4 + 13), i = 0;
        // Opus comment header.
        i += writeString(buffer, i, 'OpusTags');
        // Vendor string.
        i += this._writeLengthString(buffer, i, 'Chromium');
        // User comment list length
        i += writeValue(buffer, 4, i, 1);
        // User comment 0 length.
        i += this._writeLengthString(buffer, i, 'TITLE=example');

        this._writePage(0, buffer.byteLength);
        this.buffer.appendData(buffer);
        this._writePageChecksum(start);
      },
      _writeLengthString: function(buffer, offset, str) {
        return (writeValue(buffer, 4, offset, str.length) +
                writeString(buffer, offset + 4, str));
      },
      writeData: function(data) {
        this.position += this.format.sample_per_frame / this.format.channels;
        var start = this.buffer.getSize();
        this._writePage(0, data.byteLength, this.position);
        this.buffer.appendData(data);
        this._writePageChecksum(start);
        this.dataWritten = true;
      },
      end: function() {
        this._writePage(this._Stop, 0);
      },
      getData: function() {
        return this.buffer;
      },
      getExtension: function() {
        return 'ogg';
      },
    };

    function $(id) {
      return document.getElementById(id);
    }

    function success(stream) {
      track = stream.getAudioTracks()[0];
      var list = $('profileList');
      var profile = profiles[list.selectedIndex];
      plugin.postMessage({
        command: 'start',
        profile: profile.name,
        sample_size: profile.sample_size,
        sample_rate: profile.sample_rate,
        track: track,
      });
    }

    function failure(e) {
      console.log("Error: ", e);
    }

    function cleanupDownload() {
      var download = $('download');
      if (!download)
        return;
      download.parentNode.removeChild(download);
    }

    function setDownload(blob, filename) {
      var mimeType = 'application/octet-stream';
      var a = document.createElement('a');
      a.id = "download";
      a.download = filename;
      a.href = window.URL.createObjectURL(blob);
      a.textContent = 'Download';
      a.dataset.downloadurl = [mimeType, a.download, a.href].join(':');
      $('download-box').appendChild(a);
    }

    function startRecord() {
      var list = $('profileList');
      var profile = profiles[list.selectedIndex];
      if (profile.name == 'wav')
        writer = new WavWriter();
      else
        writer = new OggWriter(profile);
      cleanupDownload();

      var constraints = [];
      if (profile.name == 'opus') {
        // Chromium outputs 32kHz sampling rate by default. This isn't a
        // supported sampling rate for the Opus codec. So we force the
        // output to 48kHz. If Chromium implements the GetUserMedia
        // audio constraints at some point, we could potentially get rid
        // of this.
        constraints.push({ googAudioProcessing48kHzSupport: true });
      }

      navigator.webkitGetUserMedia({ audio: { optional: constraints },
                                     video: false},
                                   success, failure);
    }

    function stopRecord() {
      plugin.postMessage({
        command: "stop"
      });
      track.stop();
      writer.end();
      setDownload(writer.getData().toBlob(),
                  'Capture.' + writer.getExtension());
    }

    function handleMessage(msg) {
      if (msg.data.command == 'log') {
        console.log(msg.data.message);
      } else if (msg.data.command == 'error') {
        console.error(msg.data.message);
      } else if (msg.data.command == 'data') {
        writer.writeData(msg.data.buffer);
        $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes';
      } else if (msg.data.command == 'format') {
        writer.writeHeader(msg.data);
        $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes';
      } else if (msg.data.command == 'supportedProfiles') {
        profiles = [];
        var profileList = $('profileList');
        while (profileList.lastChild)
          profileList.remove(profileList.lastChild);

        var item = document.createElement('option');
        item.label = 'wav';
        profiles.push({ name: 'wav',
                        sample_rate: 0,
                        sample_size: 0,
                        sample_per_frame:
                        msg.data.profiles[0].sample_per_frame });
        profileList.appendChild(item);
        for (var i = 0; i < msg.data.profiles.length; i++) {
          var item = document.createElement('option');
          item.label = msg.data.profiles[i].name + ' - ' +
            msg.data.profiles[i].sample_rate + 'Hz';
          profiles.push(msg.data.profiles[i]);
          profileList.appendChild(item);
        }
      }
    }

    function resetData() {
      writer = new WavWriter();
      $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes';
    }

    function initialize() {
      plugin = $('plugin');
      plugin.addEventListener('message', handleMessage, false);

      $('start').addEventListener('click', function (e) {
        resetData();
        startRecord();
      });
      $('stop').addEventListener('click', function (e) {
        stopRecord();
      });
    }

    document.addEventListener('DOMContentLoaded', initialize, false);
  </script>
</head>

<body>
  <h1>Pepper Audio Encoder API Example</h1><br>
  This example demonstrates receiving frames from an audio MediaStreamTrack and
  encoding them using AudioEncode.<br>

  <select id="profileList"></select>
  <input type="button" id="start" value="Start Recording"/>
  <input type="button" id="stop" value="Stop Recording"/>
  <div id="download-box"></div>
  <div id="length"></div>
  <br>
  <embed id="plugin" type="application/x-ppapi-example-audio-encode"/>
</body>
</html>
