-
-
Notifications
You must be signed in to change notification settings - Fork 102
/
sound-manager.service.ts
84 lines (73 loc) · 2.03 KB
/
sound-manager.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { TetrisStateService } from '@angular-tetris/state/tetris/tetris.state';
import { Injectable, inject } from '@angular/core';
const SOUND_FILE_PATH = '/assets/tetris-sound.mp3';
@Injectable({
providedIn: 'root'
})
export class SoundManagerService {
private context: AudioContext;
private buffer: AudioBuffer;
private tetrisState = inject(TetrisStateService);
start() {
this.playMusic(0, 3.7202, 3.6224);
}
clear() {
this.playMusic(0, 0, 0.7675);
}
fall() {
this.playMusic(0, 1.2558, 0.3546);
}
gameOver() {
this.playMusic(0, 8.1276, 1.1437);
}
rotate() {
this.playMusic(0, 2.2471, 0.0807);
}
move() {
this.playMusic(0, 2.9088, 0.1437);
}
private playMusic(when: number, offset: number, duration: number) {
if (!this.tetrisState.isEnableSound()) {
return;
}
this.loadSound().then((source) => {
if (source) {
source.start(when, offset, duration);
}
});
}
private loadSound(): Promise<AudioBufferSourceNode> {
return new Promise((resolve, reject) => {
if (this.context && this.buffer) {
resolve(this.getSource(this.context, this.buffer));
return;
}
const context = new AudioContext();
const req = new XMLHttpRequest();
req.open('GET', SOUND_FILE_PATH, true);
req.responseType = 'arraybuffer';
req.onload = () => {
context.decodeAudioData(
req.response,
(buffer) => {
this.context = context;
this.buffer = buffer;
resolve(this.getSource(context, buffer));
},
() => {
const msg = 'Sorry lah, cannot play sound. But I hope you still enjoy Angular Tetris!!';
alert(msg);
reject(msg);
}
);
};
req.send();
});
}
private getSource(context: AudioContext, buffer: AudioBuffer): AudioBufferSourceNode {
const source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
return source;
}
}