ならば

音とかで遊んでいたログ

同期する拍手のシミュレーション

良いコンサートや劇、スピーチの後で拍手が沸き起こるとき、聴衆をまとめる指揮者のような存在はいないので普通は拍手のテンポは人によって全然違う。でも拍手の最中に自然とテンポがほぼ統一されてリズミカルな拍手になることもあって、特に東ヨーロッパでは結構見られる現象らしい。
リズミカルな拍手がどんな感じなのか聴きたければ、意図的に引き起こされた実例をスティーヴン・ストロガッツのTEDトークの1:00あたりから体験できる。意図的なのでこれは「自然と」とは言えないけれど。

拍手だけではなく、ホタルの発光や日ごとの睡眠リズムのように、全体をまとめる存在がないのに自然に起きる同期現象はいろいろな分野で見られる。上でリンクしたTEDトークのテーマがまさに同期現象。
このような同期現象を記述するための数学的なモデルのひとつに蔵本モデルというのがある。

蔵本モデルを使って同期する拍手をシミュレートしてみた。
ChucKのプログラム。clap.wavは単発の拍手を録音したファイル。

25::ms => dur T;
40 => int N;     // 聴衆の人数
.15 => float K;  // 秩序パラメータ:相互作用の強さ
K / N => float M;
float phase[N];
float freq[N];
float v[N];
"clap.wav" @=> string file;

SndBuf s[N];
Pan2 p[N];
Pan2 g => dac;
.5 => g.gain;

for (int i; i < N; i++) {
    s[i] => p[i] => g;
    file => s[i].read;
    s[i].samples() => s[i].pos;
    0 => s[i].loop;
    Std.rand2f(.8, 1.2) => s[i].rate;
    Std.rand2f(.01, .05) => s[i].gain;
    Std.rand2f(-1, 1) => p[i].pan;
    Std.rand2f(0, 2 * pi) => phase[i];
    Std.rand2f(.4, .6) => freq[i];
}

while (T => now) {
    float sum;
    for (int i; i < N; i++) {
        0 => sum;
        for (int j; j < N; j++) {
            Math.sin(phase[j] - phase[i]) +=> sum;
        }
        freq[i] + M * sum => v[i];
    }
    for (int i; i < N; i++) {
        v[i] +=> phase[i];
        if (phase[i] > 2 * pi) {
            2 * pi -=> phase[i];
            0 => s[i].pos;
        }
    }
}

秩序パラメータKの値が相互作用の強さを決める。この値がある閾値を超えると全体が同期する。


乱数の種を固定して初期条件を揃えた状態で、Kの値を変えて録音した結果*1。グラフのほうは横軸が時間で、縦軸に聴衆一人ひとりの「位相」をプロットしたもの。最初はばらばらでもK=0.15のときは全体が同期することが録音からもグラフからもよくわかる。

  • K=0.05

Download

  • K=0.1

Download

  • K=0.15

Download


それにしてもTEDトークは良いなあ。気楽に英語が聴ければもっといろいろ楽しめるのに。

*1:ところで、Firefox以外のブラウザだと再生ボタンを押しても再生されないかも。ダウンロードならできる