UNPKG

@skyway-sdk/core

Version:

The official Next Generation JavaScript SDK for SkyWay

81 lines 3.72 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AudioLevel = void 0; /**@internal */ class AudioLevel { constructor(audioStreamTrack) { // ChromeのAudioLevelに近い挙動とするために取得範囲と更新周期を100msとする this.LEVEL_RANGE_MS = 100; // ChromeのAudioLevelに近い挙動とするために100ms毎に1/4減衰させる this.DECAY_FACTOR = 0.25; // 1/4 this.DECAY_INTERVAL_MS = 100; // 使用する環境によってサンプリングレートは8000〜48000Hzまで様々であるため、中間値24000Hzを想定したデフォルト値を設定する this.DEFAULT_BUFFER_SIZE = 24000 * (this.LEVEL_RANGE_MS / 1000); this.currentMaxLevel = 0; this.audioContext = new AudioContext(); this.analyser = this.setupAnalyser(audioStreamTrack); this.decayTimer = this.setDecayTimer(); } [Symbol.dispose]() { return __awaiter(this, void 0, void 0, function* () { yield this.dispose(); }); } calculate() { // マイクの切り替えを考慮して毎回AudioContextからsampleRateを取得する const sampleRate = this.audioContext.sampleRate; // LEVEL_RANGE_MS分の音声サンプルを取得する const duration = this.LEVEL_RANGE_MS / 1000; const bufferLength = sampleRate ? sampleRate * duration : this.DEFAULT_BUFFER_SIZE; const timeDomainData = new Float32Array(bufferLength); this.analyser.getFloatTimeDomainData(timeDomainData); let level = Math.max(...timeDomainData); // 大きな音が発生した場合その影響を残すために保持する const _currentMaxLevel = this.currentMaxLevel; if (level > _currentMaxLevel) { this.currentMaxLevel = level; } else { level = _currentMaxLevel; } return this.clamp(level, 0, 1); } setupAnalyser(audioStreamTrack) { const mediaStream = new MediaStream([audioStreamTrack]); const source = this.audioContext.createMediaStreamSource(mediaStream); const analyser = this.audioContext.createAnalyser(); source.connect(analyser); return analyser; } setDecayTimer() { // 100ms毎に現在の最大レベルを減衰させて一時的なピークの影響を抑える return setInterval(() => { this.currentMaxLevel = this.currentMaxLevel * this.DECAY_FACTOR; }, this.DECAY_INTERVAL_MS); } clamp(value, min, max) { return Math.min(Math.max(value, min), max); } dispose() { return __awaiter(this, void 0, void 0, function* () { if (this.decayTimer) { clearInterval(this.decayTimer); this.decayTimer = null; } yield this.audioContext.close(); }); } } exports.AudioLevel = AudioLevel; //# sourceMappingURL=audioLevel.js.map