Clear audio cache when backgrounded

This commit is contained in:
kichikuou
2017-04-23 11:02:17 +09:00
parent 25ce99e434
commit 35b62c98c2
2 changed files with 30 additions and 17 deletions
+19 -12
View File
@@ -7,7 +7,7 @@ namespace xsystem35 {
private context: AudioContext;
private masterGain: GainNode;
private slots: PCMSound[];
private buffers: AudioBuffer[];
private bufCache: AudioBuffer[];
private isSafari: boolean;
constructor(volumeControl: VolumeControl) {
@@ -21,9 +21,10 @@ namespace xsystem35 {
this.masterGain = this.context.createGain();
this.masterGain.connect(this.context.destination);
this.slots = [];
this.buffers = [];
this.bufCache = [];
volumeControl.addEventListener(this.onVolumeChanged.bind(this));
this.masterGain.gain.value = volumeControl.volume();
document.addEventListener('visibilitychange', this.onVisibilityChange.bind(this));
}
private removeUserGestureRestriction() {
@@ -52,7 +53,7 @@ namespace xsystem35 {
decoded = this.context.decodeAudioData(buf);
}
return decoded.then((audioBuf) => {
this.buffers[no] = audioBuf;
this.bufCache[no] = audioBuf;
return audioBuf;
});
}
@@ -71,8 +72,8 @@ namespace xsystem35 {
pcm_load(slot: number, no: number) {
EmterpreterAsync.handle((resume) => {
this.pcm_stop(slot);
if (this.buffers[no]) {
this.slots[slot] = new PCMSoundSimple(this.masterGain, this.buffers[no]);
if (this.bufCache[no]) {
this.slots[slot] = new PCMSoundSimple(this.masterGain, this.bufCache[no]);
return resume();
}
this.load(no).then((audioBuf) => {
@@ -85,15 +86,16 @@ namespace xsystem35 {
pcm_load_mixlr(slot: number, noL: number, noR: number) {
EmterpreterAsync.handle((resume) => {
this.pcm_stop(slot);
if (this.buffers[noL] && this.buffers[noR]) {
this.slots[slot] = new PCMSoundMixLR(this.masterGain, this.buffers[noL], this.buffers[noR]);
if (this.bufCache[noL] && this.bufCache[noR]) {
this.slots[slot] = new PCMSoundMixLR(this.masterGain, this.bufCache[noL], this.bufCache[noR]);
return resume();
}
let ps = [];
if (!this.buffers[noL]) ps.push(this.load(noL));
if (!this.buffers[noR]) ps.push(this.load(noR));
Promise.all(ps).then(() => {
this.slots[slot] = new PCMSoundMixLR(this.masterGain, this.buffers[noL], this.buffers[noR]);
let ps: [Promise<AudioBuffer>, Promise<AudioBuffer>] = [
this.bufCache[noL] ? Promise.resolve(this.bufCache[noL]) : this.load(noL),
this.bufCache[noR] ? Promise.resolve(this.bufCache[noR]) : this.load(noR),
];
Promise.all(ps).then((bufs) => {
this.slots[slot] = new PCMSoundMixLR(this.masterGain, bufs[0], bufs[1]);
resume();
});
});
@@ -147,6 +149,11 @@ namespace xsystem35 {
return this.slots[slot].isPlaying() ? 1 : 0;
}
private onVisibilityChange() {
if (document.hidden)
this.bufCache = [];
}
private onVolumeChanged(evt: CustomEvent) {
this.masterGain.gain.value = evt.detail;
}
+11 -5
View File
@@ -4,7 +4,7 @@
namespace xsystem35 {
export class CDPlayer {
private audio = <HTMLAudioElement>$('audio');
private blobs: Blob[];
private blobCache: Blob[];
private currentTrack: number;
private isVolumeSupported: boolean;
private unmute: () => void; // Non-null if emulating mute by pause
@@ -15,7 +15,7 @@ namespace xsystem35 {
this.audio.volume = 0.5;
this.isVolumeSupported = this.audio.volume !== 1;
this.blobs = [];
this.blobCache = [];
volumeControl.addEventListener(this.onVolumeChanged.bind(this));
this.audio.volume = volumeControl.volume();
this.audio.addEventListener('error', this.onAudioError.bind(this));
@@ -26,6 +26,7 @@ namespace xsystem35 {
if (this.audio.volume === 0)
this.unmute = () => {};
}
document.addEventListener('visibilitychange', this.onVisibilityChange.bind(this));
}
play(track: number, loop: number) {
@@ -35,12 +36,12 @@ namespace xsystem35 {
return;
}
this.waiting = true;
if (this.blobs[track]) {
this.startPlayback(this.blobs[track], loop);
if (this.blobCache[track]) {
this.startPlayback(this.blobCache[track], loop);
return;
}
this.imageLoader.getCDDA(track).then((blob) => {
this.blobs[track] = blob;
this.blobCache[track] = blob;
this.startPlayback(blob, loop);
});
}
@@ -69,6 +70,11 @@ namespace xsystem35 {
this.waiting = false;
}
private onVisibilityChange() {
if (document.hidden)
this.blobCache = [];
}
private onVolumeChanged(evt: CustomEvent) {
if (this.isVolumeSupported) {
this.audio.volume = evt.detail;