annotate WAVE.js @ 2202:61c8e13f1e2e

Merge branch 'master' of https://github.com/BrechtDeMan/WebAudioEvaluationTool
author www-data <www-data@sucuk.dcs.qmul.ac.uk>
date Fri, 08 Apr 2016 13:20:54 +0100
parents a4ad9e55b5b8
children
rev   line source
n@1153 1 // Decode and perform WAVE file byte level manipulation
n@1153 2
n@1153 3 find_subarray = function(arr,subarr) {
n@1153 4 var arr_length = arr.length;
n@1153 5 var subarr_length = subarr.length;
n@1153 6 var last_check_index = arr_length - subarr_length;
n@1153 7
n@1153 8 positionLoop:
n@1153 9 for (var i=0; i <= last_check_index; i++)
n@1153 10 {
n@1153 11 for (var j=0; j< subarr_length; j++)
n@1153 12 {
n@1153 13 if (arr[i + j] !== subarr[j]) {
n@1153 14 continue positionLoop;
n@1153 15 }
n@1153 16 }
n@1153 17 return i;
n@1153 18 }
n@1153 19 return -1;
n@1153 20 };
n@1153 21
n@1184 22 function convertToInteger(arr) {
n@1184 23 var value = 0;
n@1184 24 for (var i=0; i<arr.length; i++)
n@1184 25 {
n@1184 26 value += arr[i]<<(i*8);
n@1184 27 }
n@1184 28 return value;
n@1184 29 }
n@1184 30 function convertToString(arr) {
n@1184 31 var str = "";
n@1184 32 for (var i=0; i<arr.length; i++)
n@1184 33 {
n@1184 34 str = str.concat(String.fromCharCode(arr[i]));
n@1184 35 }
n@1184 36 return str;
n@1184 37 }
n@1184 38
n@1153 39 function WAVE()
n@1153 40 {
n@1153 41 // The WAVE file object
n@1153 42 this.status == 'WAVE_DECLARED'
n@1153 43
n@1153 44 this.decoded_data = null;
n@1153 45
n@1153 46 this.RIFF = String(); //ChunkID
n@1153 47 this.size; //ChunkSize
n@1153 48 this.FT_Header; //Format
n@1153 49 this.fmt_marker; //Subchunk1ID
n@1153 50 this.formatDataLength; //Subchunk1Size
n@1153 51 this.type; //AudioFormat
n@1153 52 this.num_channels; //NumChannels
n@1153 53 this.sample_rate; //SampleRate
n@1153 54 this.byte_rate; //ByteRate
n@1153 55 this.block_align; //BlockAlign
n@1153 56 this.bits_per_sample; //BitsPerSample
n@1153 57 this.data_header; //Subchunk2ID
n@1153 58 this.data_size; //Subchunk2Size
n@1153 59 this.num_samples;
n@1153 60
n@1153 61 this.open = function(IOArrayBuffer)
n@1153 62 {
n@1153 63 var IOView8 = new Uint8Array(IOArrayBuffer);
n@1184 64 this.RIFF = convertToString(IOView8.subarray(0,4));
n@1153 65 if (this.RIFF != 'RIFF')
n@1153 66 {
n@1153 67 console.log('WAVE ERR - Not a RIFF file');
n@1153 68 return 1;
n@1153 69 }
n@1184 70 this.size = convertToInteger(IOView8.subarray(4,8));
n@1184 71 this.FT_Header = convertToString(IOView8.subarray(8,12));
n@1184 72 this.fmt_marker = convertToString(IOView8.subarray(12,16));
n@1184 73 this.formatDataLength = convertToInteger(IOView8.subarray(16,20));
n@1184 74 this.type = convertToInteger(IOView8.subarray(20,22));
n@1184 75 this.num_channels = convertToInteger(IOView8.subarray(22,24));
n@1184 76 this.sample_rate = convertToInteger(IOView8.subarray(24,28));
n@1184 77 this.byte_rate = convertToInteger(IOView8.subarray(28,32));
n@1184 78 this.block_align = convertToInteger(IOView8.subarray(32,34));
n@1184 79 this.bits_per_sample = convertToInteger(IOView8.subarray(34,36));
n@1153 80
n@1153 81 // Find the data header first
n@1153 82 var data_start = find_subarray(IOView8,[100, 97, 116, 97]);
n@1153 83
n@1184 84 this.data_header = convertToString(IOView8.subarray(data_start,data_start+4));
n@1184 85 this.data_size = convertToInteger(IOView8.subarray(data_start+4,data_start+8));
n@1153 86
n@1153 87 this.num_samples = this.data_size / this.block_align;
n@1153 88
n@1153 89 this.decoded_data = [];
n@1153 90 if (this.type != 1 && this.type != 3) {
n@1153 91 console.log("Neither PCM nor IEEE float, cannot decode");
n@1153 92 return 1;
n@1153 93 }
n@1153 94 for (var c=0; c<this.num_channels; c++)
n@1153 95 {
n@1153 96 this.decoded_data.push(new Float32Array(this.num_samples));
n@1153 97 }
n@1153 98 var sampleDataOffset = data_start+8;
n@1153 99
n@1153 100 // Now need to decode the data from sampleDataOffset
n@1153 101 // Data is always interleved
n@1153 102 var data_view;
n@1153 103 if (this.type == 3)
n@1153 104 {
n@1153 105 // Already in float
n@1153 106 if (this.bits_per_sample == 32) {
n@1153 107 data_view = new Float32Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size));
n@1153 108 } else if (this.bits_per_sample == 64) {
n@1153 109 data_view = new Float64Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size));
n@1153 110 }
n@1153 111 } else if (this.type == 1)
n@1153 112 {
n@1157 113 data_view = new Float32Array(this.num_samples*this.num_channels);
n@1153 114 integerConvert(new Uint8Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size)),data_view,this.bits_per_sample/8);
n@1153 115 }
n@1153 116 deInterlace(data_view,this.decoded_data);
n@1153 117 return 0;
n@1153 118 };
n@1153 119 }
n@1153 120
n@1153 121 function deInterlace(src_array, dst_array)
n@1153 122 {
n@1153 123 var number = src_array.length;
n@1153 124 var channels = dst_array.length;
n@1153 125 var channel_index = 0;
n@1153 126 var dst_index = 0;
n@1153 127 for (var n=0; n<number; n++)
n@1153 128 {
n@1153 129 dst_array[channel_index][dst_index] = src_array[n];
n@1153 130 channel_index++;
n@1153 131 if (channel_index >= channels) {
n@1153 132 channel_index = 0;
n@1153 133 dst_index++;
n@1153 134 }
n@1153 135 }
n@1153 136 }
n@1153 137
n@1153 138 function integerConvert(srcView,dstView,srcBytes)
n@1153 139 {
n@1153 140 //Convert integers of a Uint8Array of certain byte length into a Float32Array
n@1153 141 var number = dstView.length;
n@1153 142 var outBits = srcBytes*8;
n@1153 143 var endShift = 32 - outBits;
n@1153 144 if (srcView.length != dstView.length*srcBytes)
n@1153 145 {
n@1153 146 return -1;
n@1153 147 }
n@1153 148 for (var n=0; n<number; n++)
n@1153 149 {
n@1153 150 var srcIndex = n*srcBytes;
n@1184 151 var intData = convertToInteger(srcView.subarray(srcIndex,srcIndex+srcBytes));
n@1153 152 intData = (intData << (endShift));
n@1153 153 dstView[n] = intData / 2147483648;
n@1153 154 }
n@1153 155 }