diff options
Diffstat (limited to 'ext/mixed/js/audio-system.js')
| -rw-r--r-- | ext/mixed/js/audio-system.js | 56 | 
1 files changed, 35 insertions, 21 deletions
diff --git a/ext/mixed/js/audio-system.js b/ext/mixed/js/audio-system.js index 45b733fc..3273f982 100644 --- a/ext/mixed/js/audio-system.js +++ b/ext/mixed/js/audio-system.js @@ -40,7 +40,7 @@ class TextToSpeechAudio {          }      } -    play() { +    async play() {          try {              if (this._utterance === null) {                  this._utterance = new SpeechSynthesisUtterance(this.text || ''); @@ -66,10 +66,10 @@ class TextToSpeechAudio {  }  class AudioSystem { -    constructor({getAudioUri}) { -        this._cache = new Map(); +    constructor({audioUriBuilder, useCache}) { +        this._cache = useCache ? new Map() : null;          this._cacheSizeMaximum = 32; -        this._getAudioUri = getAudioUri; +        this._audioUriBuilder = audioUriBuilder;          if (typeof speechSynthesis !== 'undefined') {              // speechSynthesis.getVoices() will not be populated unless some API call is made. @@ -79,21 +79,31 @@ class AudioSystem {      async getDefinitionAudio(definition, sources, details) {          const key = `${definition.expression}:${definition.reading}`; -        const cacheValue = this._cache.get(definition); -        if (typeof cacheValue !== 'undefined') { -            const {audio, uri, source} = cacheValue; -            return {audio, uri, source}; +        const hasCache = (this._cache !== null); + +        if (hasCache) { +            const cacheValue = this._cache.get(key); +            if (typeof cacheValue !== 'undefined') { +                const {audio, uri, source} = cacheValue; +                const index = sources.indexOf(source); +                if (index >= 0) { +                    return {audio, uri, index}; +                } +            }          } -        for (const source of sources) { +        for (let i = 0, ii = sources.length; i < ii; ++i) { +            const source = sources[i];              const uri = await this._getAudioUri(definition, source, details);              if (uri === null) { continue; }              try { -                const audio = await this._createAudio(uri, details); -                this._cacheCheck(); -                this._cache.set(key, {audio, uri, source}); -                return {audio, uri, source}; +                const audio = await this._createAudio(uri); +                if (hasCache) { +                    this._cacheCheck(); +                    this._cache.set(key, {audio, uri, source}); +                } +                return {audio, uri, index: i};              } catch (e) {                  // NOP              } @@ -102,7 +112,7 @@ class AudioSystem {          throw new Error('Could not create audio');      } -    createTextToSpeechAudio({text, voiceUri}) { +    createTextToSpeechAudio(text, voiceUri) {          const voice = this._getTextToSpeechVoiceFromVoiceUri(voiceUri);          if (voice === null) {              throw new Error('Invalid text-to-speech voice'); @@ -114,20 +124,24 @@ class AudioSystem {          // NOP      } -    async _createAudio(uri, details) { +    async _createAudio(uri) {          const ttsParameters = this._getTextToSpeechParameters(uri);          if (ttsParameters !== null) { -            if (typeof details === 'object' && details !== null) { -                if (details.tts === false) { -                    throw new Error('Text-to-speech not permitted'); -                } -            } -            return this.createTextToSpeechAudio(ttsParameters); +            const {text, voiceUri} = ttsParameters; +            return this.createTextToSpeechAudio(text, voiceUri);          }          return await this._createAudioFromUrl(uri);      } +    _getAudioUri(definition, source, details) { +        return ( +            this._audioUriBuilder !== null ? +            this._audioUriBuilder.getUri(definition, source, details) : +            null +        ); +    } +      _createAudioFromUrl(url) {          return new Promise((resolve, reject) => {              const audio = new Audio(url);  |