ref: 【ニコニコ動画】ミクをPCの再生音に合わせて自動で踊らせてみた
âã«è§¦çºããã¦æ³¢ã®å¦çãããããªã£ãã®ã§ãRuby 㧠FFT (é«éãã¼ãªã¨å¤æ) ãæ¸ãã¦ã¿ã¾ããã
FFT ã¨ã¯ãæ³¢ã®å½¢ãè¦ã¦å¨æ³¢æ°ã¨ããè¦æãéæ³ã®ãã¨ã§ããæ°å¼ã¨ãèããããªãã®ã§ãã¨ã«ãã Ruby ã§æ¸ãã¦ã¿ã¾ãã *1 ã
def fft(a) n = a.size return a if n == 1 w = Complex.polar(1, -2 * Math::PI / n) a1 = fft((0 .. n / 2 - 1).map {|i| a[i] + a[i + n / 2] }) a2 = fft((0 .. n / 2 - 1).map {|i| (a[i] - a[i + n / 2]) * (w ** i) }) a1.zip(a2).flatten end
ããã ãã§ããçãã§ãããã
å®ç¨ä¸ã¯ãããã in-place åã¨ã scramble ã¨ãå®æ°ãªã¼ãã®æé©åãå¾
ã£ã¦ãããããã§ãããRuby ã§æ¸ãã¦ãæç¹ã§ãããªæ¹åã«ã¯èå³ãããã¾ããã*2
ãããªãã¨ããã¡ãã£ã¨åããã¦ã¿ã¾ããããã¾ãã¯å ¥åç¨ã®æ³¢å½¢ãä½ãããã£ãã® fft ã®å®è£ ã§ã¯ããµã³ãã«æ°ã 2 ã®ç´¯ä¹ã§ãªãã¨ãã¡ã§ãã
N = 64 a = (0...N).map do |n| v = Math.sin(2 * 2 * Math::PI * n / N) * 2 v + Math.cos(5 * 2 * Math::PI * n / N) end
2 Hz ã® sin 波㨠5 Hz ã® cos æ³¢ãåæãã波形ã2 Hz ã®æ¯å¹ 㯠2 åãå³ç¤ºãã¦ç¢ºèªããã¨
a.map do |v| s = [" "] * 20 min, max = [(-v * 3 + 10).round, 10].sort s[min..max] = ["#"] * (max - min) s end.transpose.each do |l| puts l.join end
# ### ## ##### #### ##### ###### ####### ### ####### ####### ################ ######### ################ ######### ################ ########### # ################# ########### ################ ######### ################ ######### ####### ### ####### ###### ####### #### ##### ## ##### ### #
ãªãããããããã¾ããããã§ãã¦ãã®ããªï¼ ãããè¦ã¦ã2 Hz ã¯ãªãã¨ãªããããã¾ããã5 Hz ãæ··ãã£ã¦ããã¨ã¯ã¡ãã£ã¨ããããªãã§ãããããã£ãã® FFT ã«ããã¦ã¿ã¾ãã
fft(a)[0, N/2].each_with_index do |v, n| next if n == 0 puts "%2d Hz: %.3f" % [n, v.abs / (N / 2)] end
1 Hz: 0.000 2 Hz: 2.000 3 Hz: 0.000 4 Hz: 0.000 5 Hz: 1.000 6 Hz: 0.000 7 Hz: 0.000 8 Hz: 0.000 9 Hz: 0.000 10 Hz: 0.000 11 Hz: 0.000 12 Hz: 0.000 13 Hz: 0.000 14 Hz: 0.000 15 Hz: 0.000 16 Hz: 0.000 17 Hz: 0.000 18 Hz: 0.000 19 Hz: 0.000 20 Hz: 0.000 21 Hz: 0.000 22 Hz: 0.000 23 Hz: 0.000 24 Hz: 0.000 25 Hz: 0.000 26 Hz: 0.000 27 Hz: 0.000 28 Hz: 0.000 29 Hz: 0.000 30 Hz: 0.000 31 Hz: 0.000
ã°ã¼ãã2 Hz 㨠5 Hz ãè¦äºè¦ç ´ã£ã¦ããã¾ãããfft ã®è¿ãå¤ã®è¦ããã®ãã¤ã³ãã¯ã
- æå³ã®ããæ å ±ã¯é åã®ååã ã
- 0 çªç®ã®å¤ãç¡è¦ãã
- å¤ã¯è¤ç´ æ°ã«ãªã£ã¦ããã®ã§å¤§ãã (v.abs) ãã¨ã
- (N / 2) ã§å²ã£ãå¤ããã®å¨æ³¢æ°ã®å¼·ã
- ã¡ãªã¿ã«ä½ç¸ã®æ å ±ã¯åè§ (v.angle) ã¨ãã¦å ¥ã£ã¦ããããã (ããã¾è¦ã¦ãªã)
ã¨ããæãã§ãã*3
*1:「FFT (高速フーリエ・コサイン・サイン変換) の概略と設計法」 ã®ããªã¹ã1.2.1-1. å帰å¼ã³åºãã«ãã FFTãã®ç§»æ¤ã§ãã
*2:ã¾ããã« Ruby 㧠FFT ã¨ãããã人㯠NArray の FFTW3 ã¨ã使ãã¨ãããã ã¨æãã¾ããã¼ãã¯ãã£ããã¨ããã¾ããã