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 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 |
サンプリング数値の絶対値の大きさは、大まかには音量を表す。
コンプレッサーは、ざっくり言うと以下の処理を行う。
- 音量の大きい所を小さくする
- 小さくした分、全体的に音量をわずかに上げる
これらが、サンプリング数値に及ぼす影響は、以下になる。
- サンプリング数値が閾値以上のものが、一定の割合で小さくなる
- 全てのサンプリング数値が、一定の割合で大きくなる
(厳密には、自然に聞こえるように、圧縮されるサンプルの前後では割合が緩やかに変化するため、単純では無い)
大きい音から小さい音までとっ散らかった音量がコンプレッサーで圧縮されるので、直感的には分散が減りそう……と思ったが、その後で全体の音量を上げるので、かけた後の方が(平均ー個々のサンプル)が多くのサンプルで僅かずつ大きくなり、結果として分散が増えるようだ。ただしそれも圧縮されたサンプル数と量に依るので、正しかったり正しくなかったりする。
尖度なら、平均より外れたデータが分散よりさらに重大に評価されるので、よく当てはまったということか。