1 | (function (Sink) {
|
---|
2 |
|
---|
3 | /**
|
---|
4 | * Splits a sample buffer into those of different channels.
|
---|
5 | *
|
---|
6 | * @static Sink
|
---|
7 | * @name deinterleave
|
---|
8 | *
|
---|
9 | * @arg {Buffer} buffer The sample buffer to split.
|
---|
10 | * @arg {Number} channelCount The number of channels to split to.
|
---|
11 | *
|
---|
12 | * @return {Array} An array containing the resulting sample buffers.
|
---|
13 | */
|
---|
14 |
|
---|
15 | Sink.deinterleave = function (buffer, channelCount) {
|
---|
16 | var l = buffer.length,
|
---|
17 | size = l / channelCount,
|
---|
18 | ret = [],
|
---|
19 | i, n;
|
---|
20 | for (i=0; i<channelCount; i++){
|
---|
21 | ret[i] = new Float32Array(size);
|
---|
22 | for (n=0; n<size; n++){
|
---|
23 | ret[i][n] = buffer[n * channelCount + i];
|
---|
24 | }
|
---|
25 | }
|
---|
26 | return ret;
|
---|
27 | };
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * Joins an array of sample buffers into a single buffer.
|
---|
31 | *
|
---|
32 | * @static Sink
|
---|
33 | * @name resample
|
---|
34 | *
|
---|
35 | * @arg {Array} buffers The buffers to join.
|
---|
36 | * @arg {Number} !channelCount The number of channels. Defaults to buffers.length
|
---|
37 | * @arg {Buffer} !buffer The output buffer.
|
---|
38 | *
|
---|
39 | * @return {Buffer} The interleaved buffer created.
|
---|
40 | */
|
---|
41 |
|
---|
42 | Sink.interleave = function (buffers, channelCount, buffer) {
|
---|
43 | channelCount = channelCount || buffers.length;
|
---|
44 | var l = buffers[0].length,
|
---|
45 | bufferCount = buffers.length,
|
---|
46 | i, n;
|
---|
47 | buffer = buffer || new Float32Array(l * channelCount);
|
---|
48 | for (i=0; i<bufferCount; i++) {
|
---|
49 | for (n=0; n<l; n++) {
|
---|
50 | buffer[i + n * channelCount] = buffers[i][n];
|
---|
51 | }
|
---|
52 | }
|
---|
53 | return buffer;
|
---|
54 | };
|
---|
55 |
|
---|
56 | /**
|
---|
57 | * Mixes two or more buffers down to one.
|
---|
58 | *
|
---|
59 | * @static Sink
|
---|
60 | * @name mix
|
---|
61 | *
|
---|
62 | * @arg {Buffer} buffer The buffer to append the others to.
|
---|
63 | * @arg {Buffer} bufferX The buffers to append from.
|
---|
64 | *
|
---|
65 | * @return {Buffer} The mixed buffer.
|
---|
66 | */
|
---|
67 |
|
---|
68 | Sink.mix = function (buffer) {
|
---|
69 | var buffers = [].slice.call(arguments, 1),
|
---|
70 | l, i, c;
|
---|
71 | for (c=0; c<buffers.length; c++){
|
---|
72 | l = Math.max(buffer.length, buffers[c].length);
|
---|
73 | for (i=0; i<l; i++){
|
---|
74 | buffer[i] += buffers[c][i];
|
---|
75 | }
|
---|
76 | }
|
---|
77 | return buffer;
|
---|
78 | };
|
---|
79 |
|
---|
80 | /**
|
---|
81 | * Resets a buffer to all zeroes.
|
---|
82 | *
|
---|
83 | * @static Sink
|
---|
84 | * @name resetBuffer
|
---|
85 | *
|
---|
86 | * @arg {Buffer} buffer The buffer to reset.
|
---|
87 | *
|
---|
88 | * @return {Buffer} The 0-reset buffer.
|
---|
89 | */
|
---|
90 |
|
---|
91 | Sink.resetBuffer = function (buffer) {
|
---|
92 | var l = buffer.length,
|
---|
93 | i;
|
---|
94 | for (i=0; i<l; i++){
|
---|
95 | buffer[i] = 0;
|
---|
96 | }
|
---|
97 | return buffer;
|
---|
98 | };
|
---|
99 |
|
---|
100 | /**
|
---|
101 | * Copies the content of a buffer to another buffer.
|
---|
102 | *
|
---|
103 | * @static Sink
|
---|
104 | * @name clone
|
---|
105 | *
|
---|
106 | * @arg {Buffer} buffer The buffer to copy from.
|
---|
107 | * @arg {Buffer} !result The buffer to copy to.
|
---|
108 | *
|
---|
109 | * @return {Buffer} A clone of the buffer.
|
---|
110 | */
|
---|
111 |
|
---|
112 | Sink.clone = function (buffer, result) {
|
---|
113 | var l = buffer.length,
|
---|
114 | i;
|
---|
115 | result = result || new Float32Array(l);
|
---|
116 | for (i=0; i<l; i++){
|
---|
117 | result[i] = buffer[i];
|
---|
118 | }
|
---|
119 | return result;
|
---|
120 | };
|
---|
121 |
|
---|
122 | /**
|
---|
123 | * Creates an array of buffers of the specified length and the specified count.
|
---|
124 | *
|
---|
125 | * @static Sink
|
---|
126 | * @name createDeinterleaved
|
---|
127 | *
|
---|
128 | * @arg {Number} length The length of a single channel.
|
---|
129 | * @arg {Number} channelCount The number of channels.
|
---|
130 | * @return {Array} The array of buffers.
|
---|
131 | */
|
---|
132 |
|
---|
133 | Sink.createDeinterleaved = function (length, channelCount) {
|
---|
134 | var result = new Array(channelCount),
|
---|
135 | i;
|
---|
136 | for (i=0; i<channelCount; i++){
|
---|
137 | result[i] = new Float32Array(length);
|
---|
138 | }
|
---|
139 | return result;
|
---|
140 | };
|
---|
141 |
|
---|
142 | Sink.memcpy = function (src, srcOffset, dst, dstOffset, length) {
|
---|
143 | src = src.subarray || src.slice ? src : src.buffer;
|
---|
144 | dst = dst.subarray || dst.slice ? dst : dst.buffer;
|
---|
145 |
|
---|
146 | src = srcOffset ? src.subarray ?
|
---|
147 | src.subarray(srcOffset, length && srcOffset + length) :
|
---|
148 | src.slice(srcOffset, length && srcOffset + length) : src;
|
---|
149 |
|
---|
150 | if (dst.set) {
|
---|
151 | dst.set(src, dstOffset);
|
---|
152 | } else {
|
---|
153 | for (var i=0; i<src.length; i++) {
|
---|
154 | dst[i + dstOffset] = src[i];
|
---|
155 | }
|
---|
156 | }
|
---|
157 |
|
---|
158 | return dst;
|
---|
159 | };
|
---|
160 |
|
---|
161 | Sink.memslice = function (buffer, offset, length) {
|
---|
162 | return buffer.subarray ? buffer.subarray(offset, length) : buffer.slice(offset, length);
|
---|
163 | };
|
---|
164 |
|
---|
165 | Sink.mempad = function (buffer, out, offset) {
|
---|
166 | out = out.length ? out : new (buffer.constructor)(out);
|
---|
167 | Sink.memcpy(buffer, 0, out, offset);
|
---|
168 | return out;
|
---|
169 | };
|
---|
170 |
|
---|
171 | Sink.linspace = function (start, end, out) {
|
---|
172 | var l, i, n, step;
|
---|
173 | out = out.length ? (l=out.length) && out : Array(l=out);
|
---|
174 | step = (end - start) / --l;
|
---|
175 | for (n=start+step, i=1; i<l; i++, n+=step) {
|
---|
176 | out[i] = n;
|
---|
177 | }
|
---|
178 | out[0] = start;
|
---|
179 | out[l] = end;
|
---|
180 | return out;
|
---|
181 | };
|
---|
182 |
|
---|
183 | Sink.ftoi = function (input, bitCount, output) {
|
---|
184 | var i, mask = Math.pow(2, bitCount - 1);
|
---|
185 |
|
---|
186 | output = output || new (input.constructor)(input.length);
|
---|
187 |
|
---|
188 | for (i=0; i<input.length; i++) {
|
---|
189 | output[i] = ~~(mask * input[i]);
|
---|
190 | }
|
---|
191 |
|
---|
192 | return output;
|
---|
193 | };
|
---|
194 |
|
---|
195 | }(this.Sink));
|
---|