å»å¹´ã®ã¯ãªã¹ãã¹ã«å ¬éããカラオケ機能つき Quine ã®ä»çµã¿ã«ã¤ãã¦ã
ref: 声の高さで操作するゲームを作ってみた
ã§è§£èª¬ããã¦ããå 容ã¨åä¸ã§ãããããã
ã§çµããã®ãã¤ã¾ããªãã®ã§ãç°¡åã«è§£èª¬ãã¾ããã§ãæãã ããªããæ¸ãã¦ããã®ã§åæ¸ãã¦ããããããªãããåç»ã«ã¯å³ã¨ãããã®ã§ããã¯ããã£ã¡è¦ãæ¹ãããã¨æããã©ã
ããããæ¤åºãªã㦠FFT ããã ãã§ãããã¨æã£ã¦ã人ã¯ç´ 人ã§ãé³åã¿ããã«ããããªæ£å¼¦æ³¢ã測ããããªãã¨ãããã声ã楽å¨ã®é³ãªã©åé³ãå«ãã é³ã§ã¯èª¤å¤å®ãèµ·ãã¾ããããã§ããåãããªãã¨è¨ã£ã¦ãç§ãç´ äººã§ããããã§ãWikipedia ã® Pitch detection algorithm ã§æãããã¦ãããMPM ã¢ã«ã´ãªãºã ã調ã¹ã¦å®è£ ãã¦ã¿ã¾ããã以ä¸ã®è«æã
ref: P. McLeod and G. Wyvill. A smarter way to find pitch
波形ãã自己相関関数ãè¨ç®ãã
èªå·±ç¸é¢é¢æ°ã¨ã¯ã波形ãæé軸æ¹åã«ãããã¦ã¿ã¦ãå ã®æ³¢å½¢ã¨ã©ã®ãããä¸è´ãã¦ããããã¨ããææ¨ããã®å®ç¾©éãã«è¨ç®ããã¨éå¹çã§ããã不思議な力ã«ãã£ã¦ãFFT 2 åã§å¹ççã«è¨ç®ã§ããããã§ããã¡ãªã¿ã« Ruby 㧠FFT ã¯
F=proc{|n,t,a|n/=2;r=(0..n-1);n<1?(a):(F[n,t*2,r.map{|i|a[i]+a[i+n]}].zip(F[n,t*2,r.map{|i|(a[i]-a[i+n])*Complex.polar(1,t*i)}]).flatten)}
ã¨ããããã«æ¸ãã¾ã (参考) ãå®æ°ãªã¼ãã®å¹çã¯ãããªãã§ãããã«ã©ãªã±å¤å®ç¨åº¦ãªãããããå®æéã§ã§ããããã§ãã(8000 bps 㧠1024 ç¹ãã¤å¦çã1 ç§ãããããã 8 * 2 = 16 åããã FFT ãã¦ã)
MPM ã¢ã«ã´ãªãºã ã§ã¯ãèªå·±ç¸é¢é¢æ°ãåºã«ãã Normalized Square Difference Function (NSDF) ã¨ãããé¢æ°ã使ãã¾ãã-1 ãã 1 ã«æ£è¦åããã¦ããããã¤ã³ã¯ãªã¡ã³ã¿ã«ã«è¨ç®ã§ããããä½ãã¨é½åãããé¢æ°ã®ããã§ãã
nsdf = F[N*2,-T,F[N*2,T,w+[0.0]*N].map{|v|v.abs2}].map{|v|v.real/N/2}[0,N].map{|v|v=2*v/m;m-=w[i]**2+w[-i+=1]**2;v}
NSDF ã®ãã¼ã¯ãè¦ã¤ãã
波形ã®ããããæ±ããã«ã¯ãå
ã®æ³¢å½¢ã¨ãããã波形ã®ä¸è´åº¦ãé«ãã¨ãããã¤ã¾ã NSDF ã®å¤ã大ããã¨ãããæ±ããã°ããããã§ãããããã誤æ¤ç¥ãé²ãããã®ããããã¦ãã¦ã®ã¨ããã®ããã§ããªããªã dirty ã«ãªã£ã¦ãã¾ãã
ã¾ã波形ãæé軸æ¹åã«ãªãã¦ãã£ã¦ãå¤ãè² ããæ£ã«å
¥ã£ã¦ãããæ£ããè² ã«è½ã¡ãã¾ã§ã®éã§ããã£ã¨ãå¤ã®å¤§ããªã¨ãã (ãã¼ã¯) ãåæãã¦ããã¾ããåç´ãªãã¼ã¯ (å¾®åããã 0 ã«ãªãå°ç¹) ã§ã¯ãªããã¨ã«æ³¨æã
ããã«ãåãã¼ã¯ã®åå¾ã®å¤ãè¦ã¦ãæ¾ç©ç·è£å®ã使ã£ã¦ããæ£ç¢ºã«ãã¼ã¯ã®æå»ã»å¤§ãããç¹å®ããã
ãããã¦åæããããã¼ã¯ã®ä¸ã§ãæ大ãã¼ã¯ã®å¤§ããã® 8 å²ä»¥ä¸ã®å¤§ãããæã¤ãã¼ã¯ã§ãä¸çªæåã«ç¾ãããã®ãæ¡ç¨ãã¾ãããã®ãã¼ã¯ãç¾ããæå» (ã¤ã¾ãæ³¢é·) ã®éæ°ããæ±ãããããã®å¨æ³¢æ°ã
ã¾ãããã¼ã¯ã®å¤ã®å¤§ãã㯠0 ãã 1 ã«æ£è¦åããã¦ãã¦ããããæ¤åºã®ç¢ºåº¦ã¨ãã¦ä½¿ãã¾ã (大ããã»ã©ç¢ºå®) ã
å³ããªãã¨ããããªãã§ãããããå
ã®åç»ãè«æãè¦ã¦ãã ãããã½ã¼ã¹ã³ã¼ãã§è¨ãã¨ãã®é¨åãk ãæ³¢é·ãv ããã¼ã¯ã®å¤§ããã«ãªãã¾ãã
nsdf.each_cons(3){|x,y,z|j+=1;x>0&&(0>=y&&(e<<[k*11,h];g<h&&g=h;h=0.0);y-x>0&&z-y<=0&&(d=(x-z)/t=2*(x-2*y+z);(h<c=y-t*d*d/4)&&(k,h=j+d,c)))};k,v=e.find{|i,v|v>g*0.9}
ãããããé³éã«ç´ã
é³ã®æ³¢é·ããé³éã«ç´ãã®ã¯ãlog ã§è¨ç®ã§ãã¾ãã440Hz ããªã¯ã¿ã¼ã 4 ã®ã©ã®é³ãªã®ã§
Math.log(440/k,2) * 12
ã® mod 12 ã 0 ãªãã©ã1 ãªãã©# ã2 ãªãã·ãâ¦â¦ã11 ãªãã½#ãã¨ããæãã§ãã
ã¾ã¨ã
é³å£°ããããããæ¤åºãã MPM ã¢ã«ã´ãªãºã ã«ã¤ãã¦ããã£ãã調ã¹ãã®ã§ã¡ã¢ãã¦ãç°¡åã«æ¸ãã¦ã¿ã¾ããã
ã§ããå³ãªãã§èª¬æãã¦ãããããªãã§ãããåç»ã®æ¹ãããã¶ãåãããããã§ãã詳ããç¥ããããã°è«æã¿ã¾ããããéå¤æ¼¢ã«ãåããããã㦠self-contained ã§ã4 ãã¼ã¸ã¨çãã¢ã«ã´ãªãºã è«æã§ããã°ãããã§ãã
ããããããªè§£èª¬ãããã¢åç»ã®æ¹ãå¿
è¦ãªãã ãã©ãæ声ã¨ãå
¬éããããªãã®ã ã£ãã誰ãæã£ã¦ã