1 | void function (Sink, proto) {
|
---|
2 |
|
---|
3 | proto = Sink.prototype;
|
---|
4 |
|
---|
5 | Sink.on('init', function (sink) {
|
---|
6 | sink.asyncBuffers = [];
|
---|
7 | sink.syncBuffers = [];
|
---|
8 | sink.on('preprocess', sink.writeBuffersSync);
|
---|
9 | sink.on('postprocess', sink.writeBuffersAsync);
|
---|
10 | });
|
---|
11 |
|
---|
12 | proto.writeMode = 'async';
|
---|
13 | proto.asyncBuffers = proto.syncBuffers = null;
|
---|
14 |
|
---|
15 | /**
|
---|
16 | * Private method that handles the mixing of asynchronously written buffers.
|
---|
17 | *
|
---|
18 | * @method Sink
|
---|
19 | * @name writeBuffersAsync
|
---|
20 | *
|
---|
21 | * @arg {Array} buffer The buffer to write to.
|
---|
22 | */
|
---|
23 | proto.writeBuffersAsync = function (buffer) {
|
---|
24 | var buffers = this.asyncBuffers,
|
---|
25 | l = buffer.length,
|
---|
26 | buf,
|
---|
27 | bufLength,
|
---|
28 | i, n, offset;
|
---|
29 | if (buffers) {
|
---|
30 | for (i=0; i<buffers.length; i++) {
|
---|
31 | buf = buffers[i];
|
---|
32 | bufLength = buf.b.length;
|
---|
33 | offset = buf.d;
|
---|
34 | buf.d -= Math.min(offset, l);
|
---|
35 |
|
---|
36 | for (n=0; n + offset < l && n < bufLength; n++) {
|
---|
37 | buffer[n + offset] += buf.b[n];
|
---|
38 | }
|
---|
39 | buf.b = buf.b.subarray(n + offset);
|
---|
40 | if (i >= bufLength) {
|
---|
41 | buffers.splice(i--, 1);
|
---|
42 | }
|
---|
43 | }
|
---|
44 | }
|
---|
45 | };
|
---|
46 |
|
---|
47 | /**
|
---|
48 | * A private method that handles mixing synchronously written buffers.
|
---|
49 | *
|
---|
50 | * @method Sink
|
---|
51 | * @name writeBuffersSync
|
---|
52 | *
|
---|
53 | * @arg {Array} buffer The buffer to write to.
|
---|
54 | */
|
---|
55 | proto.writeBuffersSync = function (buffer) {
|
---|
56 | var buffers = this.syncBuffers,
|
---|
57 | l = buffer.length,
|
---|
58 | i = 0,
|
---|
59 | soff = 0;
|
---|
60 | for (;i<l && buffers.length; i++) {
|
---|
61 | buffer[i] += buffers[0][soff];
|
---|
62 | if (buffers[0].length <= soff){
|
---|
63 | buffers.splice(0, 1);
|
---|
64 | soff = 0;
|
---|
65 | continue;
|
---|
66 | }
|
---|
67 | soff++;
|
---|
68 | }
|
---|
69 | if (buffers.length) {
|
---|
70 | buffers[0] = buffers[0].subarray(soff);
|
---|
71 | }
|
---|
72 | };
|
---|
73 |
|
---|
74 | /**
|
---|
75 | * Writes a buffer asynchronously on top of the existing signal, after a specified delay.
|
---|
76 | *
|
---|
77 | * @method Sink
|
---|
78 | * @name writeBufferAsync
|
---|
79 | *
|
---|
80 | * @arg {Array} buffer The buffer to write.
|
---|
81 | * @arg {Number} delay The delay to write after. If not specified, the Sink will calculate a delay to compensate the latency.
|
---|
82 | * @return {Number} The number of currently stored asynchronous buffers.
|
---|
83 | */
|
---|
84 | proto.writeBufferAsync = function (buffer, delay) {
|
---|
85 | buffer = this.mode === 'deinterleaved' ? Sink.interleave(buffer, this.channelCount) : buffer;
|
---|
86 | var buffers = this.asyncBuffers;
|
---|
87 | buffers.push({
|
---|
88 | b: buffer,
|
---|
89 | d: isNaN(delay) ? ~~((+new Date() - this.previousHit) / 1000 * this.sampleRate) : delay
|
---|
90 | });
|
---|
91 | return buffers.length;
|
---|
92 | };
|
---|
93 |
|
---|
94 | /**
|
---|
95 | * Writes a buffer synchronously to the output.
|
---|
96 | *
|
---|
97 | * @method Sink
|
---|
98 | * @name writeBufferSync
|
---|
99 | *
|
---|
100 | * @param {Array} buffer The buffer to write.
|
---|
101 | * @return {Number} The number of currently stored synchronous buffers.
|
---|
102 | */
|
---|
103 | proto.writeBufferSync = function (buffer) {
|
---|
104 | buffer = this.mode === 'deinterleaved' ? Sink.interleave(buffer, this.channelCount) : buffer;
|
---|
105 | var buffers = this.syncBuffers;
|
---|
106 | buffers.push(buffer);
|
---|
107 | return buffers.length;
|
---|
108 | };
|
---|
109 |
|
---|
110 | /**
|
---|
111 | * Writes a buffer, according to the write mode specified.
|
---|
112 | *
|
---|
113 | * @method Sink
|
---|
114 | * @name writeBuffer
|
---|
115 | *
|
---|
116 | * @arg {Array} buffer The buffer to write.
|
---|
117 | * @arg {Number} delay The delay to write after. If not specified, the Sink will calculate a delay to compensate the latency. (only applicable in asynchronous write mode)
|
---|
118 | * @return {Number} The number of currently stored (a)synchronous buffers.
|
---|
119 | */
|
---|
120 | proto.writeBuffer = function () {
|
---|
121 | return this[this.writeMode === 'async' ? 'writeBufferAsync' : 'writeBufferSync'].apply(this, arguments);
|
---|
122 | };
|
---|
123 |
|
---|
124 | /**
|
---|
125 | * Gets the total amount of yet unwritten samples in the synchronous buffers.
|
---|
126 | *
|
---|
127 | * @method Sink
|
---|
128 | * @name getSyncWriteOffset
|
---|
129 | *
|
---|
130 | * @return {Number} The total amount of yet unwritten samples in the synchronous buffers.
|
---|
131 | */
|
---|
132 | proto.getSyncWriteOffset = function () {
|
---|
133 | var buffers = this.syncBuffers,
|
---|
134 | offset = 0,
|
---|
135 | i;
|
---|
136 | for (i=0; i<buffers.length; i++) {
|
---|
137 | offset += buffers[i].length;
|
---|
138 | }
|
---|
139 | return offset;
|
---|
140 | };
|
---|
141 |
|
---|
142 | } (this.Sink);
|
---|