Audio.js 4.4 KB
Newer Older
R
Rich Harris 已提交
1 2
import { Object3D } from '../core/Object3D';

3 4
/**
 * @author mrdoob / http://mrdoob.com/
R
Reece Lecrivain 已提交
5
 * @author Reece Aaron Lecrivain / http://reecenotes.com/
6 7
 */

R
Rich Harris 已提交
8 9
function Audio ( listener ) {
	this.isAudio = true;
10

R
Rich Harris 已提交
11
	Object3D.call( this );
12 13 14 15 16

	this.type = 'Audio';

	this.context = listener.context;
	this.source = this.context.createBufferSource();
17
	this.source.onended = this.onEnded.bind( this );
18 19

	this.gain = this.context.createGain();
20
	this.gain.connect( listener.getInput() );
21

M
Mr.doob 已提交
22 23
	this.autoplay = false;

24
	this.startTime = 0;
25
	this.playbackRate = 1;
26
	this.isPlaying = false;
27 28
	this.hasPlaybackControl = true;
	this.sourceType = 'empty';
M
Mr.doob 已提交
29

S
sunag 已提交
30
	this.filters = [];
31

32 33
};

R
Rich Harris 已提交
34
Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
35

R
Rich Harris 已提交
36
	constructor: Audio,
M
Mr.doob 已提交
37

38
	getOutput: function () {
M
Mr.doob 已提交
39

40
		return this.gain;
41

42
	},
43

44
	setNodeSource: function ( audioNode ) {
M
Mr.doob 已提交
45

46 47 48 49
		this.hasPlaybackControl = false;
		this.sourceType = 'audioNode';
		this.source = audioNode;
		this.connect();
50

51
		return this;
52

53
	},
54

55
	setBuffer: function ( audioBuffer ) {
M
Mr.doob 已提交
56

S
sunag 已提交
57 58
		this.source.buffer = audioBuffer;
		this.sourceType = 'buffer';
59

S
sunag 已提交
60
		if ( this.autoplay ) this.play();
61

62
		return this;
63

64
	},
65

66
	play: function () {
67

68
		if ( this.isPlaying === true ) {
69

70 71
			console.warn( 'THREE.Audio: Audio is already playing.' );
			return;
M
Mr.doob 已提交
72

73
		}
74

75
		if ( this.hasPlaybackControl === false ) {
76

77 78
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return;
79

80
		}
81

82
		var source = this.context.createBufferSource();
M
Mr.doob 已提交
83

84 85 86 87 88
		source.buffer = this.source.buffer;
		source.loop = this.source.loop;
		source.onended = this.source.onended;
		source.start( 0, this.startTime );
		source.playbackRate.value = this.playbackRate;
M
Mr.doob 已提交
89

90
		this.isPlaying = true;
M
Mr.doob 已提交
91

92
		this.source = source;
93

S
sunag 已提交
94
		return this.connect();
95

96
	},
97

98
	pause: function () {
M
Mr.doob 已提交
99

100
		if ( this.hasPlaybackControl === false ) {
M
Mr.doob 已提交
101

102 103
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return;
M
Mr.doob 已提交
104

105
		}
106

107 108
		this.source.stop();
		this.startTime = this.context.currentTime;
M
Mr.doob 已提交
109
		this.isPlaying = false;
110

S
sunag 已提交
111 112
		return this;

113
	},
114

115
	stop: function () {
M
Mr.doob 已提交
116

117
		if ( this.hasPlaybackControl === false ) {
M
Mr.doob 已提交
118

119 120
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return;
121

122
		}
M
Mr.doob 已提交
123

124 125
		this.source.stop();
		this.startTime = 0;
M
Mr.doob 已提交
126
		this.isPlaying = false;
127

S
sunag 已提交
128 129
		return this;

130
	},
131

132
	connect: function () {
M
Mr.doob 已提交
133

S
sunag 已提交
134 135 136 137 138 139 140 141 142
		if ( this.filters.length > 0 ) {

			this.source.connect( this.filters[ 0 ] );

			for ( var i = 1, l = this.filters.length; i < l; i ++ ) {

				this.filters[ i - 1 ].connect( this.filters[ i ] );

			}
143

S
sunag 已提交
144
			this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
145

146
		} else {
147

148
			this.source.connect( this.getOutput() );
149

150
		}
151

S
sunag 已提交
152 153
		return this;

154
	},
155

156
	disconnect: function () {
M
Mr.doob 已提交
157

S
sunag 已提交
158 159 160 161 162
		if ( this.filters.length > 0 ) {

			this.source.disconnect( this.filters[ 0 ] );

			for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
163

S
sunag 已提交
164 165 166 167 168
				this.filters[ i - 1 ].disconnect( this.filters[ i ] );

			}

			this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
169

170
		} else {
171

172
			this.source.disconnect( this.getOutput() );
173

174
		}
175

S
sunag 已提交
176 177
		return this;

178
	},
M
Mr.doob 已提交
179

S
sunag 已提交
180
	getFilters: function () {
M
Mr.doob 已提交
181

S
sunag 已提交
182
		return this.filters;
M
Mr.doob 已提交
183

184
	},
185

S
sunag 已提交
186
	setFilters: function ( value ) {
M
Mr.doob 已提交
187

S
sunag 已提交
188
		if ( ! value ) value = [];
M
Mr.doob 已提交
189

190
		if ( this.isPlaying === true ) {
191

192
			this.disconnect();
S
sunag 已提交
193
			this.filters = value;
194
			this.connect();
195

196
		} else {
197

S
sunag 已提交
198
			this.filters = value;
199

200
		}
201

S
sunag 已提交
202 203 204 205 206 207 208 209 210 211 212 213 214 215
		return this;

	},

	getFilter: function () {

		return this.getFilters()[ 0 ];

	},

	setFilter: function ( filter ) {

		return this.setFilters( filter ? [ filter ] : [] );

216
	},
217

218
	setPlaybackRate: function ( value ) {
M
Mr.doob 已提交
219

220
		if ( this.hasPlaybackControl === false ) {
M
Mr.doob 已提交
221

222 223
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return;
224

225
		}
226

227
		this.playbackRate = value;
M
Mr.doob 已提交
228

229
		if ( this.isPlaying === true ) {
M
Mr.doob 已提交
230

231
			this.source.playbackRate.value = this.playbackRate;
232

233
		}
234

S
sunag 已提交
235 236
		return this;

237
	},
238

239
	getPlaybackRate: function () {
240

241
		return this.playbackRate;
242

243
	},
244

245
	onEnded: function () {
246

247
		this.isPlaying = false;
248

249
	},
M
Mr.doob 已提交
250

251
	getLoop: function () {
M
Mr.doob 已提交
252

253
		if ( this.hasPlaybackControl === false ) {
M
Mr.doob 已提交
254

255 256
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return false;
257

258
		}
M
Mr.doob 已提交
259

260
		return this.source.loop;
M
Mr.doob 已提交
261

262
	},
M
Mr.doob 已提交
263

264
	setLoop: function ( value ) {
M
Mr.doob 已提交
265

266
		if ( this.hasPlaybackControl === false ) {
M
Mr.doob 已提交
267

268 269
			console.warn( 'THREE.Audio: this Audio has no playback control.' );
			return;
270

271
		}
272

273
		this.source.loop = value;
274

275
	},
276

277
	getVolume: function () {
M
Matthew Tung 已提交
278

279
		return this.gain.gain.value;
M
Matthew Tung 已提交
280

281
	},
M
Matthew Tung 已提交
282

283

284
	setVolume: function ( value ) {
285

286 287
		this.gain.gain.value = value;

S
sunag 已提交
288 289
		return this;

290 291 292
	}

} );
R
Rich Harris 已提交
293 294 295


export { Audio };