Home

電脳麻将UI 〜 音声

電脳麻将UI 〜 牌電脳麻将 では牌の表示を「雛形のコピー」で実装していることを説明しましたが、チー・ポンなどの鳴きの発声に使う音声データも同様の方法で処理しています。


具体的な雛形は下記としています*1

    <div id="loaddata">
      ......
      <audio data-name="dapai" src="audio/dahai11.wav" volume="0.2" preload></audio>
      <audio data-name="chi" src="audio/chii.wav" volume="0.3" preload></audio>
      <audio data-name="peng" src="audio/pon.wav" volume="0.3" preload></audio>
      <audio data-name="gang" src="audio/kan.wav" volume="0.3" preload></audio>
      <audio data-name="zimo" src="audio/tsumo.wav" volume="0.3" preload></audio>
      <audio data-name="rong" src="audio/ron.wav" volume="0.3" preload></audio>
      <audio data-name="lizhi" src="audio/richi.wav" volume="0.2" preload></audio>
      <audio data-name="gong" src="audio/nc43994.wav" volume="1.0" preload></audio>
      <audio data-name="beep" src="audio/beep.wav" volume="0.2" preload></audio>
    </div>

これを @kobalab/majiang-ui の関数 Majiang.UI.audio で処理します。

/*
 *  Majiang.UI.audio
 */
"use strict";

const $ = require('jquery');

module.exports = function(loaddata) {

    const audio = {};

    $('audio', loaddata).each((i, n)=>{
        let name = $(n).data('name');
        audio[name] = $(n);
    });

    return function(name){
        let new_audio = audio[name].clone()[0];
        let volume    = audio[name].attr('volume');
        if (volume) {
            new_audio.oncanplaythrough = ()=>{
                new_audio.volume = + volume;
                new_audio.oncanplaythrough = null;
            };
        }
        return new_audio;
    }
}

loaddata で指定されたDOM領域の中から audio 要素を探し、その data-name 属性の値をキーに要素を保存します。 雛形にはダミーの属性 volume*2 があり、この値をヒントに実際に出力する音量を調整しています*3返り値 は先ほどキーとした音声名を引数として雛形からコピーした audio 要素を返す関数です。 jQueryオブジェクトではなく、生のDOMの audio 要素であることに注意してください。

以下で実際の動作を確認できます。

  1. ^ preload を指定していますが、事前にダウンロードするブラウザはなさそうです
  2. ^ かつて音量調整の目的で volume 属性を実装していたブラウザもあったと記憶しています
  3. ^ 音量の調整は「音が出せるようになった」タイミングでする必要があるようなので、canplaythrough イベントのハンドラで調整しています