UNPKG

4.77 kBJavaScriptView Raw
1/**
2 * @author mrdoob / http://mrdoob.com/
3 * @author Reece Aaron Lecrivain / http://reecenotes.com/
4 */
5
6import { Object3D } from '../core/Object3D.js';
7
8function Audio( listener ) {
9
10 Object3D.call( this );
11
12 this.type = 'Audio';
13
14 this.context = listener.context;
15
16 this.gain = this.context.createGain();
17 this.gain.connect( listener.getInput() );
18
19 this.autoplay = false;
20
21 this.buffer = null;
22 this.loop = false;
23 this.startTime = 0;
24 this.offset = 0;
25 this.playbackRate = 1;
26 this.isPlaying = false;
27 this.hasPlaybackControl = true;
28 this.sourceType = 'empty';
29
30 this.filters = [];
31
32}
33
34Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
35
36 constructor: Audio,
37
38 getOutput: function () {
39
40 return this.gain;
41
42 },
43
44 setNodeSource: function ( audioNode ) {
45
46 this.hasPlaybackControl = false;
47 this.sourceType = 'audioNode';
48 this.source = audioNode;
49 this.connect();
50
51 return this;
52
53 },
54
55 setBuffer: function ( audioBuffer ) {
56
57 this.buffer = audioBuffer;
58 this.sourceType = 'buffer';
59
60 if ( this.autoplay ) this.play();
61
62 return this;
63
64 },
65
66 play: function () {
67
68 if ( this.isPlaying === true ) {
69
70 console.warn( 'THREE.Audio: Audio is already playing.' );
71 return;
72
73 }
74
75 if ( this.hasPlaybackControl === false ) {
76
77 console.warn( 'THREE.Audio: this Audio has no playback control.' );
78 return;
79
80 }
81
82 var source = this.context.createBufferSource();
83
84 source.buffer = this.buffer;
85 source.loop = this.loop;
86 source.onended = this.onEnded.bind( this );
87 source.playbackRate.setValueAtTime( this.playbackRate, this.startTime );
88 this.startTime = this.context.currentTime;
89 source.start( this.startTime, this.offset );
90
91 this.isPlaying = true;
92
93 this.source = source;
94
95 return this.connect();
96
97 },
98
99 pause: function () {
100
101 if ( this.hasPlaybackControl === false ) {
102
103 console.warn( 'THREE.Audio: this Audio has no playback control.' );
104 return;
105
106 }
107
108 if ( this.isPlaying === true ) {
109
110 this.source.stop();
111 this.offset += ( this.context.currentTime - this.startTime ) * this.playbackRate;
112 this.isPlaying = false;
113
114 }
115
116 return this;
117
118 },
119
120 stop: function () {
121
122 if ( this.hasPlaybackControl === false ) {
123
124 console.warn( 'THREE.Audio: this Audio has no playback control.' );
125 return;
126
127 }
128
129 this.source.stop();
130 this.offset = 0;
131 this.isPlaying = false;
132
133 return this;
134
135 },
136
137 connect: function () {
138
139 if ( this.filters.length > 0 ) {
140
141 this.source.connect( this.filters[ 0 ] );
142
143 for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
144
145 this.filters[ i - 1 ].connect( this.filters[ i ] );
146
147 }
148
149 this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
150
151 } else {
152
153 this.source.connect( this.getOutput() );
154
155 }
156
157 return this;
158
159 },
160
161 disconnect: function () {
162
163 if ( this.filters.length > 0 ) {
164
165 this.source.disconnect( this.filters[ 0 ] );
166
167 for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
168
169 this.filters[ i - 1 ].disconnect( this.filters[ i ] );
170
171 }
172
173 this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
174
175 } else {
176
177 this.source.disconnect( this.getOutput() );
178
179 }
180
181 return this;
182
183 },
184
185 getFilters: function () {
186
187 return this.filters;
188
189 },
190
191 setFilters: function ( value ) {
192
193 if ( ! value ) value = [];
194
195 if ( this.isPlaying === true ) {
196
197 this.disconnect();
198 this.filters = value;
199 this.connect();
200
201 } else {
202
203 this.filters = value;
204
205 }
206
207 return this;
208
209 },
210
211 getFilter: function () {
212
213 return this.getFilters()[ 0 ];
214
215 },
216
217 setFilter: function ( filter ) {
218
219 return this.setFilters( filter ? [ filter ] : [] );
220
221 },
222
223 setPlaybackRate: function ( value ) {
224
225 if ( this.hasPlaybackControl === false ) {
226
227 console.warn( 'THREE.Audio: this Audio has no playback control.' );
228 return;
229
230 }
231
232 this.playbackRate = value;
233
234 if ( this.isPlaying === true ) {
235
236 this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );
237
238 }
239
240 return this;
241
242 },
243
244 getPlaybackRate: function () {
245
246 return this.playbackRate;
247
248 },
249
250 onEnded: function () {
251
252 this.isPlaying = false;
253
254 },
255
256 getLoop: function () {
257
258 if ( this.hasPlaybackControl === false ) {
259
260 console.warn( 'THREE.Audio: this Audio has no playback control.' );
261 return false;
262
263 }
264
265 return this.loop;
266
267 },
268
269 setLoop: function ( value ) {
270
271 if ( this.hasPlaybackControl === false ) {
272
273 console.warn( 'THREE.Audio: this Audio has no playback control.' );
274 return;
275
276 }
277
278 this.loop = value;
279
280 if ( this.isPlaying === true ) {
281
282 this.source.loop = this.loop;
283
284 }
285
286 return this;
287
288 },
289
290 getVolume: function () {
291
292 return this.gain.gain.value;
293
294 },
295
296 setVolume: function ( value ) {
297
298 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
299
300 return this;
301
302 }
303
304} );
305
306export { Audio };