技術的なやつ

技術的なやつ

5.6 要素の調整と融合

  1. Unityを用いる
    1. C#について少し復習する
    2. Unityの2D描画について簡単に学ぶ
  2. Unityの音声制御
    1. MIDIを再生させる手段を見つける
    2. 音声のマイク入力手段を見つける
  3. 入力音声の解析
    1. UnityのFFTライブラリを触ってみる
    2. FFTされたデータから音程を確定させるアルゴリズムを考える
  4. MIDIの解析
    1. 第1トラックの楽譜を解析する
    2. MIDIの再生箇所を解析する手段を見つける
  5. 採点のための解析
    1. 全体の点数計算アルゴリズムを考える
    2. ビブラート判定アルゴリズムを考える
    3. しゃくり判定アルゴリズムを考える
    4. タイミング判定アルゴリズムを考える
    5. なめらかさ判定アルゴリズムを考える

f:id:ibako31:20140214002026j:plain

特に新しいことはやっていない。今まで作ってきた要素を調整し、融合して1つのものとした。

譜面の調整

バックに音程の基準を表す土台をつけた。左端に音程も示している。黒鍵音は黒っぽいバックにしていたりと何気に凝っている。

譜面はGUITextureを使って表示していたが、そもそもGUI系は画面上に表示するゲージとかに使われるもので、最も上に描画されてしまう。今回の場合、それは非常に困るので、新しいGameObject(Plane)を生成してテクスチャを貼り付ける作戦に出た。
譜面をめくる度に、以下の処理を行う。

  1. ノートを全て消去する(GameObjectをDestroyする)
  2. 現在の譜面で必要なノートを計算する
  3. 新たなGameObjectを生成する

しかし、この方法だと譜面をめくる度に0.3秒ほどの処理落ちが発生した。どうやらGameObjectの生成・削除は少し重い処理らしい。

よって、以下の方法に変更した。

  1. 初期化時にノートを全て計算し、GameObjectを生成する
  2. 譜面をめくる度に、全てのノートを非表示にする(SetActive(false))。また、現在の譜面で必要なノートを計算し表示を有効にする

これでもやや処理落ちが発生するものの、全然マシだったので採用。

あと苦労したのは、ノートの表示位置の基準。以下のアルゴリズムで最高点の音程を決定している。

  1. 表示している譜面の平均音程を中央に持ってくるように最高点の音程を決定する
  2. 表示している譜面の最高音程が表示できていない場合、最高点の音程をその音程とする
  3. 2以外の場合で表示している譜面の最低音程が表示できていない場合、最低点の音程をその音程とする

…だけど、どうやらどこかにバグが有るらしく、たまに上手く動かない(妙に上に表示される)。まぁ、ぼちぼちと修正していこう。

演奏位置の表示

赤線のこと。
Unityには再生中のオーディオの再生位置を手に入れる機能が標準で搭載されている。

public AudioSource obj;

void Start(){
    obj.Play();
}

void Update(){
    Debug.Log(obj.time);  // 再生位置がfloat型・秒数で取得できる
}

なお、数値を弄って再びPlayすることで指定位置から再生も可能。
これと全ての要素を同期させている。

歌唱線の表示

音が取れていない場所でも線が繋がるのは不格好なので、いくつかLineRendererを用意して…と考えていたが、非常に面倒なのでパスした。まぁ、機能上そこまで影響ないやろ…。
ノートがない場所では譜面中に収まるオクターブに、ある場所ではノートとの差が最も小さくなるオクターブに合わせて表示する。JOYでよく発生するオクターブエラーはこれで回避できる。

16:9表示への対応

カメラサイズを適当にしていたので、全画面表示で左右が切れてしまった。
今の時代だと16:9のモニターが標準だと思うので、それに合わせて作りなおした。


f:id:ibako31:20140214002009j:plain

カエルの歌を歌った。