トピック

音について教えてください

覚えたいこと↓ ・マイクから音(声)を入力する ・音波を描画する ・FFTの使い方(何を何に変えてくれるのか) ・音階を調べる みなつさんの音階を表示するプログラム読みましたが、コードを読んでもあまり理解できず挫折しました(´;ω;`) ぐぐった結果、??となって帰ってきました。易しく説明していただけるとありがたいです。 3号コミュですが自分は普段BIGを使っています。
7そうだね
プレイ済み
返信[1]
親投稿
みなつ tksm372
スミマセンスミマセン(/。\) わたしは、公式ページにあるFFTのさんぷるの可視化プログラムを参考にしました! FFTのマニュアルでは分からなかった部分もかなりあったので、公式サンプルお勧めです( ・∇・)
0そうだね
プレイ済み
返信[2]
親投稿
>・マイクから音(声)を入力する >・音波を描画する SmileBasic公式サイト>追加コンテンツ>高度サウンドユニット>1.エフェクターサンプル SmileToolの波形エディタ(SYS/SBWAV) なんかが参考になります。 ただし、WiiUと3DSでMICSTARTに違いがあるので、そこはリファレンスを読んでください。 >・FFTの使い方(何を何に変えてくれるのか) >・音階を調べる これに関してはそれぞれもう少しぐぐればお望みの情報にたどり着けるはずです。 「FFT 音 時間 周波数」、「周波数 音階 変換」等々… というか、質問した時点でここまできちんとご自分の課題を細分化できるのなら、 あとはそれを1つ1つ丹念に調べていけば、必ず問題は解決できますよ。
2そうだね
プレイ済み
返信[3]
親投稿
みなつ tksm372
帰省から戻ってきてPCのキーボードで書けるようになったのでちょっと解説をば(*ノノ) マイクは、3DSとWiiUでちょっと違うのですが、初期化の時 IF HARDWARE>=2 THEN 'WiiU RATE=32000 'サンプリングレート WiiUは32000Hz固定 BUFSIZE=RATE*32 'サンプリングバッファ WiiUは最大32秒 MICSTART 0,0 '0=GamePad内蔵マイク,0=ループモード ELSE RATE=32738 'サンプリングレート32768Hzに指定 BUFSIZE=RATE*32 'サンプリングバッファ最大4秒 MICSTART 3,3,0 '3=32768Hz,3=符号付16bit,0=ループモード ENDIF という感じにすれば、あとはRATEとBUFSIZEを基準に、3号とBIGで共通に処理できます!
1そうだね
プレイ済み
返信[4]
親投稿
こめのこっ!!
0そうだね
プレイ済み
返信[5]
親投稿
みなつ tksm372
あとはマイクから勝手に録音されるのですが、録音されたデータは MICSAVE 取得位置,サンプル数,配列変数 で、配列変数にコピーできます。 また、現在どこまで録音されたかがMICPOSというシステム変数から得られます。 MICSTARTでループモードにしてるので、BUFSIZE分だけ録音されると、すぐ先頭から録音が繰り返されます。 いま仮にBUFSIZEが1000だとして、内部の録音バッファを直線的に表すと |0 ... 999|0 ... 999|0 ... 999| ... とつながっているような感じです。 このとき、FFTするため、仮に64バイトずつ切り出したいとすると、面倒なのはは、999|0のとこをまたぐ時です。 (つづく)
1そうだね
プレイ済み
返信[6]
親投稿
みなつ tksm372
あ、バイトじゃなくて要素でした。 今、内部バッファの0~959まで取り出し終わっているとしましょう。そうすると、次に取り出すタイミングは、MICPOSが(959+64) MOD 1000=23以上になったときです。 このとき取り出さなければいけない範囲は960...999|0...23の40要素+24要素の64要素です。 そのため2回に分けてMICSAVEして、一つの配列にまとめる必要があります。この処理は、次に取り出すべき開始位置をL、保存先配列をBUFとするとこんな感じです! '前半 SIZE=MIN(BUFSIZE-L,64) MICSAVE L,SIZE,BUF IF SIZE<64 THEN '後半 DIM TMP[0] MICSAVE 0,64-SIZE,TMP COPY BUF,SIZE,TMP,64-SIZE ENDIF L=(L+64) MOD 1000
1そうだね
プレイ済み
返信[7]
親投稿
みなつ tksm372
続いてFFTですが、ざっくり言うと、元データの周波数成分を取り出す機能です。FFTBUFに64要素の音声データが入っているとして、 'FFT DIM FR[64],FI[64],ZERO[64] FFT FR,FI,FFTBUF,ZERO 'FFT '周波数毎のパワーP(=FR^2+FI^2)を計算 DIM P[64]: ARYOP #AOPMUL,FR,FR,FR: ARYOP #AOPMAD,P,FI,FI,FR 'パワーをデシベルに変換 FOR I=0 TO 64/2-1 D=SQR(P[I])*100 DB[I]=20*LOG(MAX(D/&H8000,0.001),10) NEXT とすると、配列DB[I]に周波数fの成分(強さ)が入ります。Iとfの関係は f=I*サンプリングレート/64 (ただし、Iは0から31(=64/2-1)まで) となります(たぶん(*ノノ)
1そうだね
プレイ済み
返信[8]
親投稿
みなつ tksm372
周波数から音階への変換については、オクターブ4のラの音を440Hzとした場合、変換したい周波数をFとすると、 DIM NOTE$[12] COPY NOTE$,@NDAT,12 @NDAT:DATA "ラ","ラ#","シ","ド","ド#","レ","レ#","ミ","ファ#","ファ","ソ","ソ#" としておき、 N=ROUND(12*LOG(F/440,2)) N12=((N MOD 12)+12) MOD 12 '0~11の範囲に変換 ?NOTE$[N12] で、表示できるそうです(≧∇≦)b また、オクターブは、 ?FLOOR((N-3)/12)+5 で表示できるそうです!
1そうだね
プレイ済み
返信[9]
親投稿
FFT「高速フーリエ変換」は波にどんな周波数が含まれているかを変換してくれます。 数学としては、いろんな周波数の正弦波を合成していくと、いろんな波を表すことができます→「フーリエ級数」 そして、その波(合成波)がどんな周波数の正弦波が含まれてるかを求めるのが「フーリエ変換」 数学は連続した波を扱うけど、デジタルで扱う波はサンプリングレート(BIGだと1/32000秒)ごとの連続してない値→「離散」 離散化された波をフーリエ変換(波から含まれてる周波数を求める)するのが「離散フーリエ変換」 離散フーリエ変換をアルゴリズムによって高速にしたのが「高速フーリエ変換」 音は波なので、FFTをすることで音に含まれてる周波数が求まって、 音階は周波数なのでFFTすると音階が求まるのです。 本格的に知りたい場合は「やる夫で学ぶディジタル信号処理」を見ると分かったり挫折したりするかもです。
1そうだね
プレイ済み
返信[10]
親投稿
みなつ tksm372
周波数成分の強さによって色を変えて表示する方法ですが、強さを色相(H)としてHSVからRGBに変換するとそれっぽくなるかも! 例えば、黒~青~緑~赤みたいな色に変換する場合は、変換したいデシベル値がXに入っているとすると、 MINDB=-50 'これ以下は黒(H=0)にする MAXDB=-10 'これ以上は赤(H=5)にする RANGE=MAXDB-MINDB H=MIN(MAX(X-MINDB,0)/RANGE,1)*5 'H:0~5 R:0,0,0,0,1,1 R=255*MIN(1,MAX(0,H-3)) 'H:0~5 G:0,0,1,1,1,0 G=255*MIN(1,MAX(0,2-ABS(H-3))) 'H:0~5 B:0,1,1,0,0,0 B=255*MIN(1,MAX(0,1.5-ABS(H-1.5))) という感じでRGBに変換できます(≧∇≦)b
0そうだね
プレイ済み
返信[11]
親投稿
FFTはわりと数学知識がちゃんと無いと挫折するくらいには数学よりな仕組みなので 下手に数学の式や理論を見るよりかは、アルゴリズムとしてのFFTのコードと動きを見た方が理解がしやすかったりも。 とはいえプチコンではFFT関数でFFTはしてくれるので、みなつさんの説明な感じで使うことで、音声録音から音階までは計算できたり。 音としてFFTやデジタルの扱をちゃんと理解するなら「C言語ではじめる 音のプログラミング」をオススメしておきます (3000円しないの図書館にお願いするよりかは個人で買うのもおすすめです、amazonにもあるし) C言語と言っても特定の処理の本の場合はあんまりC言語特化されてないので、BASICしか知らなくてもなんとなく処理が読めたりするので C言語の本もわりとおすすめです。 (「CによるフラクタルCG 」などをBASICしか知らない時代によくBASICにしてました)
0そうだね
プレイ済み
返信[12]
親投稿
みなつ tksm372
周波数成分の抽出原理について興味があれば、フーリエ変換(基底関数はsin,cosのみ)とか、ウェーブレット変換(基底関数をsin,cosに限定しない)を調べるとよいかもです が、ぶっちゃけて「感覚的に」説明しますと。。。 例えば、1.1Hzのサイン波(調べたいデータ。図の赤線。)と1Hzのサイン波(検出したい周波数。青線。)みたいに、ちょっとだけ周波数が異なる二つのサイン波があったとします。 この二つのサイン波を、掛け算(白線)しながら積分(灰色部分がX軸より上なら面積分足す、下なら引く)していき、これを「積分した時間Tで割って」みます(黄線)。 すると、値はだんだん0に収束していきます。 何故かというと、周波数が少しでもずれてると、掛け算した曲線の灰色の部分はX軸より上と下に交互に現れるので、プラスとマイナスで打ち消し合っちゃうからです。
0そうだね
プレイ済み
返信[13]
親投稿
みなつ tksm372
ところが、もし、調べたい元データの周波数と、検出したい周波数がぴったり同じだと・・・ 両者の正/負は常に一致するので、掛け算しても正の値にしかならないんですよー(ナ・・・ナンダッテー! そうすると、灰色の部分は常に正なので、これを積分していくとどんどん大きくなり、時間Tで割った値(図の黄線)も0にならず、一定の値に近づいていきます。 逆に考えると、調べたいデータに検出したい周波数の波を掛け算して、積分した値を積分時間で割り、これが0じゃなければ「調べたい周波数の成分が含まれている!」ということが分かるのですよーヽ(´▽`)ノ そして、この0じゃない値が大きいほど、調べたい周波数成分が強いというわけですにゃー! あくまで感覚的な話なので、数学的な正しさについては自信がありません(*ノノ) 図のプログラム(スクロールしてずっと表示できます): 公開キー【VZV3Y33J】
1そうだね
プレイ済み
返信[14]
親投稿
みなつ tksm372
あ、重要なことを忘れてました・・・ プチコンBIGだけだと思いますが、MICSTARTしたまま「作品公開とダウンロード」に行くとすっごく遅くなるので、そういうときは「MICSTOP」を実行しましょう(・'ω'・)
2そうだね
プレイ済み
返信[15]
親投稿
みなつさん、たんじぇさん、もーたーわーくすさん、丁寧なアドバイスありがとうございますm(__)m 今からがんばります。 したいことが出来たら報告いたします!(^-^ゞ
1そうだね
プレイ済み
返信[16]
親投稿
技術的なこととか学術的なこととかは1つの資料や情報だけじゃなくて、いろんな資料や情報を参考にすると、こっちには書いてないけど、あっちには書いてあるって情報が結構あるので、 その辺をかいつまんで、自分なりの知識にしていくといい感じですよ。 さすがにFFTを理解するにはここに書き込める量だけじゃたりないし。 ネットの情報だけがすべてじゃなくて、やっぱり本のほうが細かい説明があったりするので、 興味があるジャンルは図書館や大きい書店で立ち読みしながらほしい本を探してみるのがいいかもです。
0そうだね
プレイ済み
返信[17]
親投稿
KingKazmaD haffukun
よくわからないけど、、とにかくがんばってけんさん!!!!!いつでも応援してます!!!!!
0そうだね
未プレイ
返信[18]
親投稿
ウッさんが動画で書いていたコードをいじっていたらなんとなくそれっぽいものが出来たので公開 公開キー[8Q5LP]
0そうだね
プレイ済み
返信[19]
親投稿
上のプログラムにコメント付けて動きも改良しました。 ファイル名[KEN_MIC_B] 公開キー[DYD543D] とびこめプチコンの闇の方にも載せときます。
0そうだね
プレイ済み