Xmas Contest 2017
A - Compressor
問題
- どっちがコンプレッサーかけた音でしょう?(15問)
所感
これを1問目にぶち込んでくるセンスよ。面白いなあ。
耳で聴いたら10/15だった。意外といけるな(自分に対するハードルが低い)
ここまで巫山戯た問題なら、解答側も Brute force で自動Submit する人とかいそうだけど、連投制限あるんだっけ。
解法
wavを読み込んでサンプリングされた数値を得ても、コンプレッサー前後の数値的特徴がどんなところに現れるか、というセンスが無いとどうしようもない。
今回の問題では、「尖度」を計算することでぴたりと答えに当てはまるとのこと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import wavefrom scipy import fromstring, int16from scipy.stats import variation, kurtosissrc_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 |
サンプリング数値の絶対値の大きさは、大まかには音量を表す。
コンプレッサーは、ざっくり言うと以下の処理を行う。
- 音量の大きい所を小さくする
- 小さくした分、全体的に音量をわずかに上げる
これらが、サンプリング数値に及ぼす影響は、以下になる。
- サンプリング数値が閾値以上のものが、一定の割合で小さくなる
- 全てのサンプリング数値が、一定の割合で大きくなる
(厳密には、自然に聞こえるように、圧縮されるサンプルの前後では割合が緩やかに変化するため、単純では無い)
大きい音から小さい音までとっ散らかった音量がコンプレッサーで圧縮されるので、直感的には分散が減りそう……と思ったが、その後で全体の音量を上げるので、かけた後の方が(平均ー個々のサンプル)が多くのサンプルで僅かずつ大きくなり、結果として分散が増えるようだ。ただしそれも圧縮されたサンプル数と量に依るので、正しかったり正しくなかったりする。
尖度なら、平均より外れたデータが分散よりさらに重大に評価されるので、よく当てはまったということか。

