Audio.js 4.5 KB
Newer Older
1 2
/**
 * @author mrdoob / http://mrdoob.com/
R
Reece Lecrivain 已提交
3
 * @author Reece Aaron Lecrivain / http://reecenotes.com/
4 5
 */

M
Mr.doob 已提交
6 7
import { Object3D } from '../core/Object3D';

M
Mr.doob 已提交
8
function Audio( listener ) {
9

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

	this.type = 'Audio';

	this.context = listener.context;

	this.gain = this.context.createGain();
17
	this.gain.connect( listener.getInput() );
18

M
Mr.doob 已提交
19 20
	this.autoplay = false;

21 22
	this.buffer = null;
	this.loop = false;
23
	this.startTime = 0;
24
	this.playbackRate = 1;
25
	this.isPlaying = false;
26 27
	this.hasPlaybackControl = true;
	this.sourceType = 'empty';
M
Mr.doob 已提交
28

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

M
Mr.doob 已提交
31
}
32

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

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

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

39
		return this.gain;
40

41
	},
42

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

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

50
		return this;
51

52
	},
53

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

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

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

61
		return this;
62

63
	},
64

65
	play: function () {
66

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

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

72
		}
73

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

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

79
		}
80

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

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

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

91
		this.source = source;
92

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

95
	},
96

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

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

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

104
		}
105

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

S
sunag 已提交
110 111
		return this;

112
	},
113

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

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

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

121
		}
M
Mr.doob 已提交
122

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

S
sunag 已提交
127 128
		return this;

129
	},
130

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

S
sunag 已提交
133 134 135 136 137 138 139 140 141
		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 ] );

			}
142

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

145
		} else {
146

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

149
		}
150

S
sunag 已提交
151 152
		return this;

153
	},
154

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

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

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

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

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

			}

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

169
		} else {
170

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

173
		}
174

S
sunag 已提交
175 176
		return this;

177
	},
M
Mr.doob 已提交
178

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

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

183
	},
184

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

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

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

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

195
		} else {
196

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

199
		}
200

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

	},

	getFilter: function () {

		return this.getFilters()[ 0 ];

	},

	setFilter: function ( filter ) {

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

215
	},
216

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

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

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

224
		}
225

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

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

230
			this.source.playbackRate.setValueAtTime( this.playbackRate, this.context.currentTime );
231

232
		}
233

S
sunag 已提交
234 235
		return this;

236
	},
237

238
	getPlaybackRate: function () {
239

240
		return this.playbackRate;
241

242
	},
243

244
	onEnded: function () {
245

246
		this.isPlaying = false;
247

248
	},
M
Mr.doob 已提交
249

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

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

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

257
		}
M
Mr.doob 已提交
258

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

261
	},
M
Mr.doob 已提交
262

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

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

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

270
		}
271

272 273 274 275 276 277 278 279 280
		this.loop = value;

		if ( this.isPlaying === true ) {

			this.source.loop = this.loop;

		}

		return this;
281

282
	},
283

284
	getVolume: function () {
M
Matthew Tung 已提交
285

286
		return this.gain.gain.value;
M
Matthew Tung 已提交
287

288
	},
T
Tristan VALCKE 已提交
289
	
290
	setVolume: function ( value ) {
291

292 293
		this.gain.gain.value = value;

S
sunag 已提交
294 295
		return this;

296 297 298
	}

} );
R
Rich Harris 已提交
299

M
Mr.doob 已提交
300
export { Audio };