MUSHRAをMax/MSPで実行する

MUSHRA (MUltiple Stimuli with Hidden Reference and Anchors)という実験手法があります。これは知覚符号化音源など、違いの小さな複数の音刺激の音質評価を行うために開発された手法です、複数(10個くらい)の刺激をボタンで切り替えながら試聴し、それぞれが標準刺激と比べてどの程度劣化(変化)しているかをスライダーで答えます。

以前、Javaでステレオ版を作ったことがあるのですが、5.1chサラウンドの実験などでマルチチャンネルに対応させようと思うと、なかなかJava Sound APIはめんどくさい*1ので、今回はMax 5の勉強も兼ね、丸一日かけて作ってみました。今回はとりあえず4つの音刺激を比較評価できればOKです。一番最初にぶつかった壁は、複数のサラウンド音源ファイルを同期させて再生する方法が分からなかったこと。しょうがないので6chファイルを4つくっつけて24chのファイルとして使うことにしました。(sfplay~は最大32chまでしか対応していないので、この方法だとファイル5つぶんしか比較できませんが…。)

音源の提示順序をランダム化させるところまでは難なく進んだのですが、めんどくさかったのが各試行における音源の提示順序をランダム化することでした。ちょっと分かりにくいんですが、たとえば曲A〜Cを符号化1〜4で圧縮して符号化の音声品質を比較したいとします。そのときは各曲の登場順序をABCだけにしてしまうと、Aを聞いたあとでBを聞くと物足りなかったり、ということが起きてしまう可能性があります。そのため、曲の提示順をランダムにする必要があります。これはスクリーンショット中央下あたりでやっています(「urn 3」とかあるあたり)。

めんどくさかったのはこの部分ではなく、ある1曲について符号化アルゴリズム同士を比較する部分。各スライダーに同じ曲で違う音質の音刺激が割り当てられるわけですが、この割り当て方もランダム順にしないといけません。曲被験者ごとにランダム順で音刺激が提示されないと実験に偏りが出てしまうので、ここは大事です。楽曲の提示順序とは違い、「1曲の評価が終わったら次の曲をランダムに選ぶ」という逐次実行ではなく「符号化された4音源ををあらかじめランダム順に並べておく」必要があります。この「あらかじめ」という部分が、Maxだとめんどくさいのです(CやJavaみたいな文字ベースのプログラミング言語だと簡単なのに…)。ここは、urnオブジェクトでルックアップ・テーブルを使い、zlオブジェクトで読み取ることにしました(スクリーンショット右下のあたり)。

あとは、おまけ機能として、スペースバーを押すごとに再生音刺激を切り替えるものを用意。(スクリーンショット左下)

得られた評価データをどういった形で出力するかはまだ考えていません。データの出力順を決めるのも意外に思い通りにいきません。また、現在は4つの音刺激の比較しかできませんが、せめて9つくらいは比較したいので、このあとどうやって改良するかが問題です。複数のsfplay~を同時再生するときって、サンプル単位で同期取れてるのかなぁ。

*1:オーディオ・ハードウェアをマルチチャンネルのデバイスとしてではなく、複数の2chデバイスとして扱ってしまうのが大きな欠点で、しかもGUIを作るのもいろいろ面倒です。