aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/xterm/src/browser/services/SoundService.ts
blob: a3b6800d4229e09ded900e07ac085c242113a23d (plain)
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
/**
 * Copyright (c) 2018 The xterm.js authors. All rights reserved.
 * @license MIT
 */

import { IOptionsService } from 'common/services/Services';
import { ISoundService } from 'browser/services/Services';

export class SoundService implements ISoundService {
  public serviceBrand: undefined;

  private static _audioContext: AudioContext;

  public static get audioContext(): AudioContext | null {
    if (!SoundService._audioContext) {
      const audioContextCtor: typeof AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;
      if (!audioContextCtor) {
        console.warn('Web Audio API is not supported by this browser. Consider upgrading to the latest version');
        return null;
      }
      SoundService._audioContext = new audioContextCtor();
    }
    return SoundService._audioContext;
  }

  constructor(
    @IOptionsService private _optionsService: IOptionsService
  ) {
  }

  public playBellSound(): void {
    const ctx = SoundService.audioContext;
    if (!ctx) {
      return;
    }
    const bellAudioSource = ctx.createBufferSource();
    ctx.decodeAudioData(this._base64ToArrayBuffer(this._removeMimeType(this._optionsService.rawOptions.bellSound)), (buffer) => {
      bellAudioSource.buffer = buffer;
      bellAudioSource.connect(ctx.destination);
      bellAudioSource.start(0);
    });
  }

  private _base64ToArrayBuffer(base64: string): ArrayBuffer {
    const binaryString = window.atob(base64);
    const len = binaryString.length;
    const bytes = new Uint8Array(len);

    for (let i = 0; i < len; i++) {
      bytes[i] = binaryString.charCodeAt(i);
    }

    return bytes.buffer;
  }

  private _removeMimeType(dataURI: string): string {
    // Split the input to get the mime-type and the data itself
    const splitUri = dataURI.split(',');

    // Return only the data
    return splitUri[1];
  }
}