真・聴力検査 hacks

41
真・聴力検査 HACKS 社外版 2012/10/24 @nipotan

Upload: koichi-taniguchi

Post on 24-May-2015

1.671 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: 真・聴力検査 HACKS

真・聴力検査 HACKS

社外版2012/10/24@nipotan

Page 2: 真・聴力検査 HACKS

以前社内で

• 「聴力検査 HACKS」というネタで LT• Mac で簡単に聴力検査をしたい• だけど音を鳴らすのって複雑だよね

Page 3: 真・聴力検査 HACKS

say -v Ralph "poe"

#!/bin/sh

v=1while [ $v -le 200 ]do vol=`echo "scale=2; ${v} / 100" | bc | sed -e 's/^\./0./g'` echo $vol /usr/bin/osascript -e "set Volume ${vol}" /usr/bin/say -r 250 -v Ralph "poe" v=`expr $v + 1`done

Page 4: 真・聴力検査 HACKS

まぁ…

• 急に作ったネタとは言え、だいぶお粗末• 音程によって声の人物、発音する単語を変えるのはいかがなものか

• “声” ではなく “音” を扱うのに say は不適切なのでは?

Page 5: 真・聴力検査 HACKS

聴力検査• オージオメーター• 英語で書くと audiometer• 健康診断でお馴染み• 「“ピーピーピー” “ポーポーポー” と音が鳴ってる間はボタンを押してください」

• もっとオージオメーターを手軽に

Page 6: 真・聴力検査 HACKS

ポー そして ピー• say で poe とか pee とか変じゃない?• 音程によって低音は Ralph さんとか、高音なら Ya-Ling さんとか、指名するのはなんか変

• そもそも機械的な音声のピーもポーも音程が違うだけで同じ音色

• 何故 Ralph は “poe” と言わされたか?

Page 7: 真・聴力検査 HACKS

擬音語、奥深い• カタカナで表現する擬音語• 子音は attack (立ち上がり) による• 母音は音程による (高 イ→エ→ア→オ→ウ 低)

• decay (減衰) は「ン」で表現• Wikipedia の「子音」の項見るとすごい

※個人の感想であり、効果・効能を示すものではありません

Page 8: 真・聴力検査 HACKS

擬音語、奥深い• サイレン「ピーポーピーポー」時報「ピ、ピ、ピ、ポーン」鐘「キンコンカンコン」

• だいたいこの法則に則ってる• 「ノーシンピュア」の CM でアッキーナが最後に言う「ポンピーン」は唯一例外

• 字が違うが、音程違いだけど同じ音なはず※個人の感想であり、効果・効能を示すものではありません

Page 9: 真・聴力検査 HACKS

人間の口腔は複雑

• 声帯から出る音声は同じでも、口腔の形状で響き (母音) がかわる

• イコライザ、トーンカーブ的な役割• 人間の音声以外は口腔を介していない

※個人の感想であり、効果・効能を示すものではありません

Page 10: 真・聴力検査 HACKS

人間の口腔は複雑• ボコーダー、トーキングモジュレータ、ワウペダル、ワウワウミュート等は人間の口腔による音色変化をシミュレート• ボコーダー: YMO「Technopolis」

• トーキングモジュレータ: BON JOVI「Livin’ On a Prayer」、同じ BON JOVI で、 なかやまきんに君がパスタに粉チーズかける時の BGM「It’s My Life」

• ワウペダル: Jimi Hendrix「Voodoo Child」、B’z 松本孝弘の音作り (マニアック)

• ワウワウミュート: Pee Wee Hunt「Somebody Stole My Gal」(吉本新喜劇のテーマ)

※個人の感想であり、効果・効能を示すものではありません

Page 11: 真・聴力検査 HACKS

Mac で音を鳴らす• say はやめて、純粋な音を鳴らす• Perl で .wav (WAVE) ファイルを作ろう• データ形式について軽く調べれば出来る• ちなみに音に関しては完全にド素人。このネタのために、調べたり頭で考えながら作った資料なのであんまり細かいこと言わないでください

※個人の感想であり、効果・効能を示すものではありません

Page 12: 真・聴力検査 HACKS

CD 音質• 44100 Hz, 16bit, ステレオ• 秒間 44100 サンプル• 1 サンプル 16bit → 2 bytes• ステレオはサンプルが左右交互に 2 つ• block size は 2 bytes x 2 = 4 bytes• 44100 (sample) x 4 (bytes) =176,400 bytes/sec (≒ 172.27KB ≒ 1.35Mbps)

Page 13: 真・聴力検査 HACKS

WAVE データ形式

• RIFF (Resource Interchange File Format) という汎用メタファイル形式

• RIFF ヘッダと RIFF データからなる• WAVE データは RIFF データ内のWAVE ヘッダとサブチャンクから構成

Page 14: 真・聴力検査 HACKS

WAVE データ形式

• 格納データはリトルエンディアン形式• Apple が採用する AIFF (Audio Interchange File Format) は似たフォーマットで格納データはビッグエンディアン形式

• そもそも RIFF は AIFF を元に作られた?

Page 15: 真・聴力検査 HACKS

WAVE データ内容 バイト数

RIFF ヘッダ 8

WAVE ヘッダ “WAVE” 4

fmt チャンク 24~

data チャンク -

あくまで、音を鳴らすための最低限

Page 16: 真・聴力検査 HACKS

RIFF ヘッダ

内容 バイト数

RIFF 識別子 “RIFF” 4

これより後ろのデータサイズ(合計サイズ -8) 4

Page 17: 真・聴力検査 HACKS

WAVE ヘッダ

内容 バイト数

WAVE 識別子 “WAVE” 4

Page 18: 真・聴力検査 HACKS

fmt チャンク内容 バイト数

fmt 識別子 “fmt ” 4fmt チャンクの

これより後ろのデータサイズ 4フォーマット ID (リニア PCM = 1) 2

チャンネル数(モノ:1 ステレオ: 2) 2

サンプリングレート (Hz) 4データ速度

(サンプリングレート x block size) 4block size 2bit 数 2

Page 19: 真・聴力検査 HACKS

data チャンク内容 バイト数

data 識別子 “data” 4

data チャンクのこれより後ろのデータサイズ 4

音声データ -

Page 20: 真・聴力検査 HACKS

音声データ内容 バイト数

左チャンネルのサンプル 2

右チャンネルのサンプル 2

↑これが 1 ブロック1 秒あたり 44100 ブロック

Page 21: 真・聴力検査 HACKS

音の基礎• 440Hz (秒間 440 回振幅) の音はラ (A4)• 半分の 220Hz、倍の 880Hz もラ(A3, A5)

• A3~A5 は用紙サイズではなく A がラを、後ろの数字がオクターブを表す

• MIDI データだとオクターブが 1 つ下の扱い

Page 22: 真・聴力検査 HACKS

音の基礎• オクターブ間の周波数を 12 分割したのが音階 ((十二)平均律) で、世の中の音楽のデファクト

• 和声で平均律の不自然さに異を唱える思想もあり。「音律」で Wikipedia

• 振幅の幅が音量• 振幅の形が音色

Page 23: 真・聴力検査 HACKS

振幅の形 (波形)• 代表: 正弦波 (sine)、矩形波 (square)、三角波 (triangle)、のこぎり波 (sawtooth)

Page 24: 真・聴力検査 HACKS

楽器の音色の違い

• 波形の違い• attack, decay の違い• 基音 (fundamental tone) と倍音 (harmonics) の音量と組み合わせの違い

• トーンの違い

※個人の感想であり、効果・効能を示すものではありません

Page 25: 真・聴力検査 HACKS

純音

• 楽音と違い、オージオメーターは「純音」• 倍音を一切含まない正弦波• 自然界には存在しない音 (口笛、音叉、クリスタルガラス楽器演奏が近い)

※個人の感想であり、効果・効能を示すものではありません

Page 26: 真・聴力検査 HACKS

純音• アナログでは、ウィーンブリッジ発振回路 (Wien bridge oscillator) で実現可能

• デジタルでは量子化による誤差が生じる• 「完全な正弦波は作れない」• サンプリングレート、量子化ビット数を上げることで近似的な音は作れる

※個人の感想であり、効果・効能を示すものではありません

Page 27: 真・聴力検査 HACKS

オージオメータ仕様• 125Hz, 250Hz, 500Hz, 1000Hz, 2000Hz, 4000Hz, 8000Hz を出力する

• シの音 (123.47Hz, 246.94Hz, 493.88Hz, 987.76Hz ...) に近い

• 音が鳴ってる箇所、無音の箇所の繰り返し• 左右で鳴り分け (ステレオ)

Page 28: 真・聴力検査 HACKS

WAVE で作る純音

• 音声データ生成における Hello World (多分)• 正弦波を 16bit で表現する

※個人の感想であり、効果・効能を示すものではありません

Page 29: 真・聴力検査 HACKS

WAVE で作る純音sub make_sine {    my($hz, $sec, $lvol, $rvol) = @_;    my $maxno = 2 ** 16 / 2 - 1; # 32767    $lvol = $lvol / 100 * $maxno;    $rvol = $rvol / 100 * $maxno;    my $length = 44100 * $sec;    my $sound = '';    for my $pos (1 .. $length) {        my $val = sin 2 * 3.14 * $hz * ($pos / 44100);        $sound .= pack 'v', $val * $lvol; # left        $sound .= pack 'v', $val * $rvol; # right    }    return $sound;}

Page 30: 真・聴力検査 HACKS

WAVE で作る無音

sub make_silent {    my $sec = shift;    my $length = 44100 * $sec;    my $sound = '';    for my $pos (1 .. $length) {        $sound .= "\0" x 4;    }    return $sound;}

Page 31: 真・聴力検査 HACKS

純音無音の繰り返し

sub audiometer {    my($lr, $oct) = @_;    my $hz = 500 * 2 ** ($oct - 3);    my $data = '';    for my $vol (1 .. 20) {        my @vol_args = uc($lr) eq 'L' ? ($vol, 0) : (0, $vol);        $data .= make_sine($hz, 0.3, @vol_args);        $data .= make_silent(0.2);    }    return $data;}

Page 32: 真・聴力検査 HACKS

忘れないで、ヘッダmy $header = riff_header(length $data);

sub riff_header {    my $size = shift;    my $header = 'RIFF'; # RIFF header    $header .= pack 'V', $size + 36; # following data size     $header .= 'WAVE'; # WAVE header    $header .= 'fmt '; # fmt header    $header .= pack 'V', 16; # format chunk size    $header .= pack 'v', 1; # format id (PCM = 1)    $header .= pack 'v', 2; # monaural = 1, stereo = 2    $header .= pack 'V', 44100; # sampling rate (44.1kHz)    $header .= pack 'V', 44100 * 4; # byte/sec    $header .= pack 'v', 4; # block size (16bit stereo)    $header .= pack 'v', 16; # bit/sample    $header .= 'data'; # data header    $header .= pack 'V', $size; # data chunk size    return $header;}

Page 33: 真・聴力検査 HACKS

お洒落に PSGI でmy $app = sub {    my $env = shift;    my @path = $env->{REQUEST_URI} =~ m{^/([lr])/([1-7])/?$}i;    die "invalid path $env->{REQUEST_URI}" unless @path == 2;    my $wave = audiometer(@path);    return [        200,        [             'Content-Type' => 'audio/x-wav',            'Content-Length' => length($wave) + 44,        ],        [             riff_header(length $wave),             $wave,        ],     ];};

Page 34: 真・聴力検査 HACKS

DEMO

Page 35: 真・聴力検査 HACKS

応用: モスキート音sub mosquito { return make_sine(17000, 10, 100, 100) }

• 17kHz 以上の音はモスキート音• 若者には聞こえるらしいぜ• はぁ、どうせ聞こえねーし

※個人の感想であり、効果・効能を示すものではありません

Page 36: 真・聴力検査 HACKS

応用: 簡易シーケンサsub tone_to_hz {    my $tone = shift;    my($scale, $shift, $octave) = $tone =~ / ^ ([A-G]) # A-G ([-+b\#]?) # -, +, b, # ([1-9]?) # 1-9 $ /x;    return 0 unless $scale;    my %tone_index = (        C => -9, D => -7, E => -5, F => -4, G => -2, A => 0, B => 2,    );    my $index = $tone_index{$scale};    if ($shift) {        my $num = $shift eq '+' || $shift eq '#' ? 1 : -1;        $index += $num;    }    if ($octave && $octave != 3) {        $index += ($octave - 3) * 12;    }    return 440 * (2 ** ($index / 12));}

Page 37: 真・聴力検査 HACKS

応用: 簡易シーケンサsub sequence {    my $bpm = shift;    my $crotchet = 60 / $bpm;    my $seconds = +{        16 => $crotchet / 4,        8 => $crotchet / 2,        4 => $crotchet,        2 => $crotchet * 2,        1 => $crotchet * 4,    };    my $wave = '';    for my $data (@_) {        my($tone, $len, $vol) = @$data;        $vol ||= 80;        my $sec = 0;        for my $note (split /-/, $len) {            my $dotted = $tone =~ s/\.$// ? 1 : 0;            $sec += $seconds->{$note} * ($dotted ? 1.5 : 1);        }        if ($tone eq '-') {            $wave .= make_silent($sec);            next;        }        $wave .= make_sine(tone_to_hz($tone), $sec, $vol, $vol);    }    return $wave;}

Page 38: 真・聴力検査 HACKS

応用: 簡易シーケンサsub heavy_rotation {    my $bpm = shift;    my $crotchet = 60 / $bpm;    return sequence(        $bpm,        ['E3', 4], # I        ['F#3', 4], # want        ['G#3', '1-4'], # you        ['-', 4],        ['E3', 4], # I        ['F#3', 4], # need        ['G#3', '1-4'], # you        ['-', 4],        ['E3', 4], # I        ['F#3', 4], # love        ['G#3', '1-4'], # you        ['-', 4],        ['G#3', 4], # あ        ['A3', 4], # た        ['B3', 2], # ま        ['G#3', 2], # の        ['F#3', 2], # な        ['E3', 2], # か        ['C#4', 4], # ガ

        ['C#4', 4], # ン        ['C#4', 4], # ガ        ['A3', 4], # ン        ['F#3', 4], # な        ['F#3', 4], # っ        ['G#3', 4], # て        ['A3', 4], # る        ['B3', 4], # mu        ['B3', 4], # -        ['B3', 4], # si        ['G#3', 4], # -        ['E3', 2], # c        ['-', 4],        ['G#3', 4], # hea        ['A3', 2], # vy        ['C#3', 2], # -        ['E3', 4], # ro        ['D#3', 4], # -        ['C#3', 4], # ta        ['D#3', 4], # -        ['E3', 2], # tion    );}

Page 39: 真・聴力検査 HACKS

この聴力検査方法• 厳密な聴力の検査には向かない• 再生デバイス側でボリュームコントロール可能

• 音波への変換装置の個体差• あくまで簡易的な検査にとどめましょう• 耳の異常を感じたら、早めに耳鼻科へ

Page 40: 真・聴力検査 HACKS

まとめ

• あくまで、音を扱ってみただけです• でも音を扱うのは基本がわかればちょっと楽しくなってくる

Page 41: 真・聴力検査 HACKS

おわり

• 質問はあんまり受けたくありません