Xmas Contest 2017
A - Compressor
問題
- どっちがコンプレッサーかけた音でしょう?(15問)
所感
これを1問目にぶち込んでくるセンスよ。面白いなあ。
耳で聴いたら10/15だった。意外といけるな(自分に対するハードルが低い)
ここまで巫山戯た問題なら、解答側も Brute force で自動Submit する人とかいそうだけど、連投制限あるんだっけ。
解法
wavを読み込んでサンプリングされた数値を得ても、コンプレッサー前後の数値的特徴がどんなところに現れるか、というセンスが無いとどうしようもない。
今回の問題では、「尖度」を計算することでぴたりと答えに当てはまるとのこと。
import wave from scipy import fromstring, int16 from scipy.stats import variation, kurtosis src_tpl = 'C:\\path\\to\\data\\input\\{:02d}_{}.wav' def kurt(wav_path): with wave.open(wav_path, 'rb') as wr: data = wr.readframes(wr.getnframes()) nums = fromstring(data, dtype=int16) return variation(nums), kurtosis(nums) v_ans, k_ans = [], [] for i in range(1, 16): va, ka = kurt(src_tpl.format(i, 'A')) vb, kb = kurt(src_tpl.format(i, 'B')) v_ans.append('A' if va < vb else 'B') k_ans.append('A' if ka < kb else 'B') print(''.join(v_ans)) # 分散 print(''.join(k_ans)) # 尖度 # 分散: BBABBBBABABBAAB # 尖度: AABAAAABABABBAB # 答え: AABAAAABABABBAB
サンプリング数値の絶対値の大きさは、大まかには音量を表す。
コンプレッサーは、ざっくり言うと以下の処理を行う。
- 音量の大きい所を小さくする
- 小さくした分、全体的に音量をわずかに上げる
これらが、サンプリング数値に及ぼす影響は、以下になる。
- サンプリング数値が閾値以上のものが、一定の割合で小さくなる
- 全てのサンプリング数値が、一定の割合で大きくなる
(厳密には、自然に聞こえるように、圧縮されるサンプルの前後では割合が緩やかに変化するため、単純では無い)
大きい音から小さい音までとっ散らかった音量がコンプレッサーで圧縮されるので、直感的には分散が減りそう……と思ったが、その後で全体の音量を上げるので、かけた後の方が(平均ー個々のサンプル)が多くのサンプルで僅かずつ大きくなり、結果として分散が増えるようだ。ただしそれも圧縮されたサンプル数と量に依るので、正しかったり正しくなかったりする。
尖度なら、平均より外れたデータが分散よりさらに重大に評価されるので、よく当てはまったということか。