Index: ppapi/examples/audio_encode/audio_encode.html |
diff --git a/ppapi/examples/audio_encode/audio_encode.html b/ppapi/examples/audio_encode/audio_encode.html |
index 36b322a54d1e8d236a68a4d86867a3bd94a477c0..14cab7b3a2f8d8553532fe2736c74e8dd02f1e6e 100644 |
--- a/ppapi/examples/audio_encode/audio_encode.html |
+++ b/ppapi/examples/audio_encode/audio_encode.html |
@@ -14,71 +14,126 @@ |
var profiles; |
function writeString(array, offset, string) { |
- var out = new Uint8Array(array); |
for (var i = 0; i < string.length; i++) |
- out.set([string.charCodeAt(i)], i + offset); |
+ array.set([string.charCodeAt(i)], i + offset); |
return string.length; |
} |
function writeValue(array, bytes, offset, value) { |
- var out = new Uint8Array(array); |
for (var i = 0; i < bytes; i++) |
- out.set([((value >>> (i * 8)) & 0xff)], offset + i); |
+ array.set([((value >>> (i * 8)) & 0xff)], offset + i); |
return bytes; |
} |
- // Writes way data. |
+ |
+ 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.arrayBuffer = new ArrayBuffer(); |
+ this.buffer = new BufferArray(); |
}; |
WavWriter.prototype = { |
writeHeader: function(format) { |
- this.arrayBuffer = |
- new ArrayBuffer(4 + 4 + 4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 4 + 4); |
+ var buffer = |
+ new Uint8Array(4 + 4 + 4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 4 + 4); |
var i = 0; |
// File header |
- i += writeString(this.arrayBuffer, i, 'RIFF'); |
+ i += writeString(buffer, i, 'RIFF'); |
i += 4; // Gap for final size. |
- i += writeString(this.arrayBuffer, i, 'WAVE'); |
+ i += writeString(buffer, i, 'WAVE'); |
// Chunk ID. |
- i += writeString(this.arrayBuffer, i, 'fmt '); |
+ i += writeString(buffer, i, 'fmt '); |
// Chunk length. |
- i += writeValue(this.arrayBuffer, 4, i, 16); |
+ i += writeValue(buffer, 4, i, 16); |
// Codec (uncompressed LPCM). |
- i += writeValue(this.arrayBuffer, 2, i, 1); |
+ i += writeValue(buffer, 2, i, 1); |
// Number of channels. |
- i += writeValue(this.arrayBuffer, 2, i, format.channels); |
+ i += writeValue(buffer, 2, i, format.channels); |
// Sample rate. |
- i += writeValue(this.arrayBuffer, 4, i, format.sample_rate); |
+ i += writeValue(buffer, 4, i, format.sample_rate); |
// Average bytes per seconds (sample rate * bytes per sample) |
- i += writeValue(this.arrayBuffer, 4, i, |
+ i += writeValue(buffer, 4, i, |
format.sample_rate * format.sample_size); |
// Bytes per sample. |
- i += writeValue(this.arrayBuffer, 2, i, |
+ i += writeValue(buffer, 2, i, |
format.sample_size * format.channels); |
// Bits per sample. |
- i += writeValue(this.arrayBuffer, 2, i, format.sample_size * 8); |
+ i += writeValue(buffer, 2, i, format.sample_size * 8); |
// Data chunk |
- i += writeString(this.arrayBuffer, i, 'data'); |
+ i += writeString(buffer, i, 'data'); |
this.chunkSizeOffset = i; // Location of the chunk's size |
+ this.buffer.appendData(buffer); |
}, |
writeData: function(data) { |
- var tmp = new Uint8Array(this.arrayBuffer.byteLength + data.byteLength); |
- tmp.set(new Uint8Array(this.arrayBuffer), 0); |
- tmp.set(new Uint8Array(data), this.arrayBuffer.byteLength); |
- this.arrayBuffer = tmp.buffer; |
+ this.buffer.appendData(data); |
}, |
end: function() { |
- var out = new Uint32Array(this.arrayBuffer); |
- out.set([this.arrayBuffer.byteLength - 8], 1); |
- out.set([this.arrayBuffer.byteLength - this.chunkSizeOffset], |
- this.chunkSizeOffset / 4); |
+ this.buffer.writeValue(4, 4, this.buffer.getSize() - 8); |
+ this.buffer.writeValue(4, this.chunkSizeOffset, |
+ this.buffer.getSize() - this.chunkSizeOffset); |
}, |
getSize: function() { |
- return this.arrayBuffer.byteLength; |
+ return this.buffer.getSize(); |
}, |
getData: function() { |
- return this.arrayBuffer; |
+ return this.buffer; |
}, |
getExtension: function() { |
return 'wav'; |
@@ -88,7 +143,7 @@ |
// Writes ogg data. |
var OggWriter = function(profile) { |
this.writeHeader = this._writeOpusHeader; |
- this.arrayBuffer = new ArrayBuffer(); |
+ this.buffer = new BufferArray(); |
this.pageSequence = 0; |
this.bitstreamNumber = 0; |
this.position = 0; |
@@ -98,12 +153,6 @@ |
_Start: 0x2, |
_Continue: 0x1, |
_Stop: 0x4, |
- _append: function(data) { |
- var tmp = new Uint8Array(this.arrayBuffer.byteLength + data.byteLength); |
- tmp.set(new Uint8Array(this.arrayBuffer), 0); |
- tmp.set(new Uint8Array(data), this.arrayBuffer.byteLength); |
- this.arrayBuffer = tmp.buffer; |
- }, |
_makeCRCTable: function() { |
var crcTable = []; |
for (var n = 0; n < 256; n++) { |
@@ -120,15 +169,14 @@ |
}, |
_crc32: function(data, start, end) { |
var crc = 0; |
- var u8data = new Uint8Array(data) |
var crcTable = this._crcTable || (this._crcTable = this._makeCRCTable()); |
for (var i = start; i < end; i++) |
- crc = (crc << 8) ^ crcTable[((crc >> 24) & 0xff) ^ u8data[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 ArrayBuffer(27 + pages), i = 0; |
+ var buffer = new Uint8Array(27 + pages), i = 0; |
// capture_pattern. |
i += writeString(buffer, i, 'OggS'); |
// stream_structure_version. |
@@ -154,17 +202,17 @@ |
i += writeValue(buffer, 1, i, 255); |
i += writeValue(buffer, 1, i, size % 255); |
- this._append(buffer); |
+ this.buffer.appendData(buffer); |
}, |
_writePageChecksum: function(pageOffset) { |
- var crc = this._crc32(this.arrayBuffer, pageOffset, |
- this.arrayBuffer.byteLength); |
- writeValue(this.arrayBuffer, 4, pageOffset + 22, crc); |
+ 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.getSize(); |
- var buffer = new ArrayBuffer(8 + 1 + 1 + 2 + 4 + 2 + 1), i = 0; |
+ 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. |
@@ -181,13 +229,13 @@ |
i += writeValue(buffer, 1, i, 0); |
this._writePage(this._Start, buffer.byteLength); |
- this._append(buffer); |
+ this.buffer.appendData(buffer); |
this._writePageChecksum(start); |
this._writeCommentHeader('OpusTags'); |
}, |
_writeCommentHeader: function(name) { |
- var start = this.getSize(); |
- var buffer = new ArrayBuffer(8 + 4 + 8 + 4 + 4 + 13), i = 0; |
+ var start = this.buffer.getSize(); |
+ var buffer = new Uint8Array(8 + 4 + 8 + 4 + 4 + 13), i = 0; |
// Opus comment header. |
i += writeString(buffer, i, name); |
// Vendor string. |
@@ -198,7 +246,7 @@ |
i += this._writeLengthString(buffer, i, 'TITLE=example'); |
this._writePage(this._Continue, buffer.byteLength); |
- this._append(buffer); |
+ this.buffer.appendData(buffer); |
this._writePageChecksum(start); |
}, |
_writeLengthString: function(buffer, offset, str) { |
@@ -207,20 +255,17 @@ |
}, |
writeData: function(data) { |
this.position += this.format.sample_per_frame / this.format.channels; |
- var start = this.getSize(); |
+ var start = this.buffer.getSize(); |
this._writePage(0, data.byteLength, this.position); |
- this._append(data); |
+ this.buffer.appendData(data); |
this._writePageChecksum(start); |
this.dataWritten = true; |
}, |
end: function() { |
this._writePage(this._Stop, 0); |
}, |
- getSize: function() { |
- return this.arrayBuffer.byteLength; |
- }, |
getData: function() { |
- return this.arrayBuffer; |
+ return this.buffer; |
}, |
getExtension: function() { |
return 'ogg'; |
@@ -255,9 +300,8 @@ |
download.parentNode.removeChild(download); |
} |
- function setDownload(data, filename) { |
+ function setDownload(blob, filename) { |
var mimeType = 'application/octet-stream'; |
- var blob = new Blob([data], { type: mimeType }); |
var a = document.createElement('a'); |
a.id = "download"; |
a.download = filename; |
@@ -297,12 +341,8 @@ |
}); |
track.stop(); |
writer.end(); |
- setDownload(writer.getData(), 'Capture.' + writer.getExtension()); |
- } |
- |
- function saveBlob(blob) { |
- var blobUrl = URL.createObjectURL(blob); |
- window.location = blobUrl; |
+ setDownload(writer.getData().toBlob(), |
+ 'Capture.' + writer.getExtension()); |
} |
function handleMessage(msg) { |
@@ -312,10 +352,10 @@ |
console.error(msg.data.message); |
} else if (msg.data.command == 'data') { |
writer.writeData(msg.data.buffer); |
- $('length').textContent = ' Size: ' + writer.getSize() + ' bytes'; |
+ $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes'; |
} else if (msg.data.command == 'format') { |
writer.writeHeader(msg.data); |
- $('length').textContent = ' Size: ' + writer.getSize() + ' bytes'; |
+ $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes'; |
} else if (msg.data.command == 'supportedProfiles') { |
profiles = []; |
var profileList = $('profileList'); |
@@ -342,7 +382,7 @@ |
function resetData() { |
writer = new WavWriter(); |
- $('length').textContent = ' Size: ' + writer.getSize() + ' bytes'; |
+ $('length').textContent = ' Size: ' + writer.getData().getSize() + ' bytes'; |
} |
function initialize() { |