release_audio_by_src(src) {
    const stop_promises = [];

    // music
    if (this._music && this._music.get_src() === src) {
      stop_promises.push(this.stop_music(0.0));
    }

    // voice
    if (this._voice && this._voice.get_src() === src) {
      stop_promises.push(this.stop_voice(0.0));
    }

    // sfx
    if (window.isDesktop) {
      // on desktop, use streaming sfx
      if (this._sfx.length > 0) {
        for (let i = this._sfx.length - 1; i >= 0; i--) {
          const effect = this._sfx[i];
          if (effect.get_src() === src) {
            stop_promises.push(this.stop_effect(effect));
          }
        }
      }
    } else {
      // on web, use cocos sfx
      cc.audioEngine.unloadEffect(src);
    }

    // wait for all to stop and release from pools
    return Promise.all(stop_promises).then(() => {
      this.release_pool_by_src(src);
    });
  }
Release all audio objects matching src.
@param {String} src