annotate new/js/WAVE.js @ 22:1f375b7d75fd tip

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