So-net無料ブログ作成
検索選択
理系的音楽道 ブログトップ

フーリエ級数 [理系的音楽道]

理系の大学の2年か3年で習う数学にフーリエ級数というものがあります。どんな波形でも高校で習うサイン、コサインで表せるという便利なものです。もちろん音波もフーリエ級数で表せます。ちょっと公式を書いてみますね。

f1.jpg

こんな感じです。たとえばピアノの音は三角波に似ているという話[1]になってましたが、三角波は式では

f2.jpg

とかけます。これを公式に入れると三角波をサインとコサインで次のように書けることがわかります。

f3.jpg

無限項の総和はコンピュータでは無理ですが、少ないですがはじめの2項をとれば、次のような波形を得ます。

f4.jpg

赤色が今回の波形で、黒がピアノの波形です。見た目には似てます。しかしながら、今回の波形は2種類の波であるのに対して、ピアノの音は何種類もの周波数の波の重ねあわせです。もし、フーリエ級数の総和を10項程度取ったら、本当に先のとがった三角波になってしまいます。いつもでしたら、音を聞いてもらうところですが、現在、新しいPCの録音機能が動きません。それで本日は音なしです。すみません。これでは単なる退屈な記事です。

今まであえて使わなかったことがあります。今日の話題のフーリエ級数のちょっとだけ発展させた理論でフーリエ変換です。波形にどのような周波数が含まれるかを調べる方法です。通常の理系の人間が音を扱うときはフーリエ変換から入るのが常識です。そこをまげて、趣味なのでフーリエ変換を使わずに来ました。今日の記事を書いてみて、やはりフーリエ変換をしなければならないのかなあという感想を持ちました。普通になりますかね。

[関連情報]
[1] 三角波, 10/04/08


2010-06-06 00:00  nice!(12)  コメント(23)  トラックバック(0) 
共通テーマ:音楽

MIDIファイルの内部を見る [理系的音楽道]

ピアノの演奏をScore Editorで作る作業を行っていますが、最後は結局MIDIファイルにして、電子ピアノで演奏させています。しかし、MIDI規格やMIDIファイル自体は私は理解していない状況です。また、これまでも「理系的音楽道」のカテゴリーでいろいろな人工的な音を発生させてきましたが、単にAの音を出すだけで曲の演奏には至っていません。曲を演奏させるにはMIDIファイルを読み込まなければなりません。

そこで今回の記事は、MIDIファイルを自作プログラムに読み込んで中に何が書かれているかを読み解くという企画です。このプログラムを作成することによりMIDI規格を理解することができました。これが最大の成果です。今回公開のプログラムは実はMIDIファイルが読み込み何をしているか画面に書くだけで、演奏はしてくれません。つまり役立たずですが、勉強の一過程とお考えください。それからこのプログラムは、私が作っているMIDIファイルを理解できるソフトであり、MIDI規格の全て文法に対応したものではありません。あくまで途中経過であり、使えないと思いますので、使ってみることはお薦めしません。でもMIDI規格を勉強する上ではこのソースコードは有用かも知れません。

感想ですが、MIDIファイルは古い規格なので今から見ると容量圧縮に無駄なエネルギーを使ってます。例えば可変長変数などです。つまりコンピュータが使う数値形式と違う方法で数値が格納されています。プログラミングをするとなるとそれなりのエネルギーが必要でした。

/****************************************************************** ・本ソースファイル名はmidiread100505.cです。 ・本プログラムの著作権はyablinskyに属します。 ・本プログラムで作ったファイルの著作権はwavファイルの作成者にあります。 ・本プログラムのコピー・改変は自由です。 ただし、改変されたプログラムは個人で楽しむ以外に使う場合、 例えば、wavデータやそれを変換したデータをブログやホームページに アップロードする場合はソースコードも公開しなければならない。 version 10.05.02 MIDI dataの読み込み <a href="http://desktop-piano.blog.so-net.ne.jp" target="_blank">http://desktop-piano.blog.so-net.ne.jp</a> Copyright 2010 yablinsky All rights reserved. Presented by yablinsky *******************************************************************/ #include <stdio.h> #include <math.h> #include <stdlib.h> #include <malloc.h> void midiread(char **argv); void write_error(char *c); int getdata(FILE *fpi,int *num,int counter); void main(int argc,char *argv[]) { int i,N,sampling; struct LR *sound; if (argc!=2) { printf("midiread000000 input_data_file_name(*.mid)\n"); exit(1); } midiread(argv); } // wavデータをキャラクタデータへ変換 void midiread(char **argv) { int headsize=0,format=0,tracknumber=0,deltatime=0,counter=0, datasize=0,midichannel=0,num,i,tempo,port,flag=0,sequence=0,st; unsigned int DT=0; char n,dd,cc,bb,sf,mi; unsigned char c0,c1,nn; FILE *fpi; fpi=fopen(argv[1],"rb"); // header fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'M') write_error("R"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'T') write_error("I"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'h') write_error("F"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'd') write_error("F"); printf("%c\n",c1); counter=getbytedata(4,fpi,&headsize,counter); printf("headsize=%d\n",headsize); counter=0; counter=getbytedata(2,fpi,&format,counter); printf("format=%d [%d]\n",format,counter); counter=getbytedata(2,fpi,&tracknumber,counter); printf("tracknumber=%d [%d]\n",tracknumber,counter); counter=getbytedata(2,fpi,&deltatime,counter); printf("deltatime=%d [%d]\n",deltatime,counter); if (counter!=headsize) {printf("error\n"); exit(1);} // data fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'M') write_error("M"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'T') write_error("T"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'r') write_error("r"); printf("%c",c1); fread(&c1,sizeof(char),(size_t)1,fpi); if (c1 != 'k') write_error("k"); printf("%c\n",c1); counter=getbytedata(4,fpi,&datasize,counter); printf("datasize=%d\n",datasize); counter=0; do { DT=0; counter=getdata(fpi,&DT,counter); printf("[DT=%d]",DT); counter=getonebyte(fpi,&c0,counter); if (c0!=0xFF && (c0<0x80 || c0>0x8F) && (c0<0x90 || c0>0x9F) && (c0<0xB0 || c0>0xBF) && (c0<0xC0 || c0>0xCF) && c0!=0xF0) { flag=1; c1=c0; c0=st; } if (flag==0) printf("[%x]",c0); if (c0==0xFF) { if (flag==0) counter=getonebyte(fpi,&c1,counter); printf("(%x)",c1); switch (c1) { case 0x00: counter=getonebyte(fpi,&n,counter); if (n!=2) printf("error",n); sequence=0; for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%d ",c1); sequence=(sequence << 8) + c1; } printf("sequence number=%d\n",sequence); break; case 0x02: counter=getonebyte(fpi,&n,counter); printf("(copyright length=%d)",n); for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%c",c1); } printf("\n"); break; case 0x03: counter=getonebyte(fpi,&n,counter); printf("(sequence name length=%d)",n); for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%c",c1); } printf("\n"); break; case 0x04: counter=getonebyte(fpi,&n,counter); printf("(instrument length=%d)",n); for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%c",c1); } printf("\n"); break; case 0x08: counter=getonebyte(fpi,&n,counter); printf("(program name length=%d)",n); for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%c",c1); } printf("\n"); break; case 0x20: counter=getonebyte(fpi,&c1,counter); printf("(%x)",c1); if (c1!=1) {printf("error\n"); exit(1);} counter=getdata(fpi,&midichannel,counter); printf("midichannel=%d\n",midichannel); break; case 0x21: counter=getonebyte(fpi,&c1,counter); printf("(%x)",c1); if (c1!=1) {printf("error\n"); exit(1);} counter=getdata(fpi,&port,counter); printf("port=%d\n",port); break; case 0x2F: counter=getonebyte(fpi,&c1,counter); printf("(end of track %x)\n",c1); if (c1!=0) {printf("error\n"); exit(1);} break; case 0x51: counter=getonebyte(fpi,&n,counter); printf("(tempo length=%d) ",n); tempo=0; for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%d ",c1); tempo=(tempo << 8) + c1; } printf("tempo=%d\n",tempo); break; case 0x54: counter=getonebyte(fpi,&n,counter); printf("(SMPTE length=%d) ",n); for (i=1;i<=n;++i) { counter=getonebyte(fpi,&c1,counter); printf("%d ",c1); } printf("\n"); break; case 0x58: counter=getonebyte(fpi,&n,counter); printf("(takt length=%d) ",n); counter=getonebyte(fpi,&nn,counter); printf("%d/",nn); counter=getonebyte(fpi,&dd,counter); printf("%d ",(int)pow(2,dd)); counter=getonebyte(fpi,&cc,counter); printf("midiclock=%d ",cc); counter=getonebyte(fpi,&bb,counter); printf("4 / 32=%d\n",bb); break; case 0x59: counter=getonebyte(fpi,&n,counter); printf("(key signature length=%d) ",n); counter=getonebyte(fpi,&sf,counter); if (sf>=0) printf("(# x %d) ",sf); if (sf<0) printf("(b x %d) ",-sf); counter=getonebyte(fpi,&mi,counter); if (mi==0) printf("major\n"); if (mi==1) printf("minor\n"); break; default: printf("error\n"); exit(1); } }else if (c0>=0x80 && c0<=0x8F) { if (flag==0) counter=getonebyte(fpi,&c1,counter); printf("[note OFF](note number=%d) ",c1); counter=getonebyte(fpi,&c1,counter); printf("(velocity=%d)\n",c1); }else if (c0>=0x90 && c0<=0x9F) { if (flag==0) counter=getonebyte(fpi,&c1,counter); printf("[note ON](note number=%d) ",c1); counter=getonebyte(fpi,&c1,counter); printf("(velocity=%d)\n",c1); }else if (c0>=0xB0 && c0<=0xBF) { if (flag==0) counter=getonebyte(fpi,&c1,counter); printf("(control number=%d) ",c1); if (c1>=121 && c1<=127) { printf("(reserved)"); }else if (c1==0 || c1==32) { printf("(bank select)"); }else if (c1==6 || c1==38) { printf("(data entry)"); }else if (c1==7) { printf("(channel volume)"); }else if (c1==10) { printf("(panpot)"); }else if (c1==11) { printf("(expression)"); }else if (c1==64) { printf("(Pedal)"); }else if (c1==91) { printf("(reverb)"); }else if (c1==93) { printf("(chorus)"); }else if (c1==94) { printf("(celeste)"); }else if (c1==98 || c1==99) { printf("(NRPN)"); }else if (c1==100 || c1==101) { printf("(RPN)"); }else{ printf("(unknown control)"); } counter=getonebyte(fpi,&c1,counter); printf("(%d)\n",c1); }else if (c0>=0xC0 && c0<=0xCF) { if (flag==0) counter=getonebyte(fpi,&c1,counter); printf("(program change=%d)\n",c1); }else if (c0==0xf0) { if (flag==0) { num=0; counter=getdata(fpi,&num,counter); } printf("(SysEx length=%d)",num); for (i=1;i<=num;++i) { counter=getonebyte(fpi,&nn,counter); printf("%x ",nn); } printf("\n"); }else{ printf("error B\n"); exit(1); } st=c0; flag=0; }while(counter<=datasize); fclose(fpi); } void write_error(char *c) { printf("%s\n",c); exit(1); } int getonebyte(FILE *fpi,char *a,int counter) { char c1; fread(&c1,sizeof(char),(size_t)1,fpi); ++counter; *a=c1; return counter; } int getbytedata(int N,FILE *fpi,int *num,int counter) { int a=0,i; char c1; for (i=1;i<=N;++i) { fread(&c1,sizeof(char),(size_t)1,fpi); a=(a<<8) + (int)c1; ++counter; } *num=a; return counter; } int getdata(FILE *fpi,int *num,int counter) { unsigned char c1,flag; fread(&c1,sizeof(char),(size_t)1,fpi); ++counter; flag=c1 & 0b10000000; if (flag==0) { *num = *num + c1; }else{ *num = (*num << 7) + (c1 - 0b10000000); counter=getdata(fpi,num,counter); } return counter; }


2010-05-20 00:00  nice!(11)  コメント(18)  トラックバック(0) 
共通テーマ:音楽

ピアノのアタック音 [理系的音楽道]

かなり前になってしまいましたが、3月21日の記事[2]でピアノの音は三角波に似ていることが分かりました。また、4月8日[1]に三角波の減衰音をピアノの音と比べてみて、減衰した音は少しは似ている感じになっているが、アタック音(始めの打鍵直後の音)は全く違っていることが分かりました。[2]でも紹介したピアノの波形をもう一度描けば
Apiano-ALL.JPG
という感じでした。そこで本日はアタック音の部分を見て見ます。いつものように真ん中のAの音です。
attack1.jpg
意外に一気に音が立ち上がるのでなく、だらだらと大きくなっているようです。音波には分散関係がないことが分かっていますので、これは音の伝播中の起こったものではないはずです。では、なぜでしょう。とりあえず分かりません。ハンマーが弦に当たっている時間でしょうか?それから、赤で描いたとおりうなりとまでは言えませんが、ある特定の周波数のみにうなっているようにも見えます。これは何でしょうか。それから始めの大きな固まりがいわゆるアタック音でしょうが、なぜここだけ周りより大きいのでしょうか。謎だらけです。

もう少し拡大してみます。
attack2.jpg
ここは鳴り始めの部分ですが、概ね、三角波っぽい感じはしますね。アタック音、なかなか理解できません。きっと昔、電子ピアノを作った人はこの道を通ったのでしょうね。最後にピアノの音に似せて人工的に音を作って見ました。



まだまだピアノとは言えません。どのように悪戦苦闘してこのような音を作るかは次回の理系的音楽道で紹介します。

[関連情報]
[1] 三角波, 10/04/08
[2] ピアノの波形を見る, 10/03/21


2010-05-02 00:00  nice!(13)  コメント(18)  トラックバック(0) 
共通テーマ:音楽

三角波 [理系的音楽道]

前回のカテゴリー:理系的音楽道では電子ピアノの音を録音し、それをテキストデータ化して、グラフに書き観察しました。その結果、ピアノの音は概ね三角波であることが分かりました[1]。そこで今回は三角波ってどんな音か聞いて見たくなり、プログラミングしてみることにしました。今回は[2]のプログラムの波形関数を変えただけです。

// 発生する音の波形 f:周波数 double sound_wave(double f,double t) { double T=1/f,tt; int n=(int)(t/T); tt=t-n*T; if (tt<T/4) { return exp(-2*t)*4/T*tt; }else if (T/4<=tt && tt<=3*T/4) { return -exp(-2*t)*4/T*(tt-T/2); }else{ return exp(-2*t)*4/T*(tt-T); } }
[1]のプログラムを使ってグラフを書けば
triangular.jpg
という波形で、これまで同様440Hzすなわちラの音です。では三角波とピアノの音、そして正弦波を聞き比べて見ましょう。

三角波


ピアノの録音[1]


正弦波(前にアップロードしたもの)[2]


正弦波は本当にコンピュータの音と言う感じですが、三角波はピアノの音に少し近づいた感じはします。しかし、まだまだ似ていません。特にアタック音(最初の強い音)が似てません。その後、2つの音は幾分似てますが、最終な残響音は似てないようです。いやーピアノの音は深いですね。まだまだ調査は続きます。

[関連情報]
[1] ピアノの波形を見る, 10/03/21
[2] 周波数当てクイズ, 10/02/24


2010-04-08 23:00  nice!(12)  コメント(11)  トラックバック(0) 
共通テーマ:音楽

ピアノの波形を見る [理系的音楽道]

理系的音楽道の5回目です。[1]で作ったプログラムは人工的に作った波形を音(wavファイル)にして聞けるプログラムでした。今回はその逆で、wavファイルをデータにするプログラムです。将来、ピアノの音を分析するもっとも基礎的な機能です。とりあえず、本日はピアノのA(ラ)の音をPCに取り込み、その波形を目で見てみる企画です。電子ピアノはメーカが理想的な音響室でグランドピアノの音を採音したもので、これを使わない手はありません。さっそく、手持ちのソフトsound itを使って、 wavファイルとして録音し、本日のプログラムでそのwavファイルを取り込み、テキストデータとして書き込み、今月、フリーソフト化されたばかりのngraph[3]で波形を書いてみました。まず、全体状況は
Apiano-ALL.JPG
です。横軸は時間で0.5秒付近で打鍵し、音が減衰していることがわかります。波形が込み入っているので、かいつまんで拡大してみましょう。まず、打鍵してすぐ0.5秒から0.51秒の様子を見てみましょう。
Apiano-1.JPG
本[2]にも載っているような典型的なピアノの波形です。でも本と違って上下非対称ですね。では次に0.6秒から0.61秒の波形を見て見ましょう。
Apiano-2.JPG
0.5秒付近波形の小さな振動がなまって来ているのが観察されます。次に0.7秒から0.71秒の様子をみましょう。
Apiano-3.JPG
なんだか正弦波ではなく、三角形の波形に変わって来ました。では0.8秒から0.81秒を見て見ましょう。
Apiano-4.JPG
頂点がとがっていたのが、まるくなって来ました。総じて印象は

1,時間の経過とともに波形は変化する。
2,他の楽器の波形[2]と比べると単純な波形で、おおむね正弦波的である。でもよく見れば、正弦波というより三角波である。

というものです。皆さんはどのような感想でしょうか。プログラムに興味のある方は下の「プログラムはこちら」を押してみてください。

[1] 周波数当てクイズ, 10/02/24
[2] 楽器の物理学, 10/03/20
[3] ngraph, http://www2e.biglobe.ne.jp/~isizaka/

プログラムはこちら


2010-03-21 23:00  nice!(7)  コメント(13)  トラックバック(0) 
共通テーマ:音楽

うなり [理系的音楽道]

「理系的音楽道」の4回目です。うなりは理系の大学学部、特に工学系ではほとんど習うのではないでしょうか。そのうなり(beat)の音を実際に聞きたくなり、前に作ったプログラム[1]で試して見ましたので報告します。

うなりとは、2つの近い周波数の振動があったとき、それよりかなりゆっくりした周期でブーンブーンと振動する現象です。昔はバスの外板などが、よくうなっていました。あれは外板が持っているもっとも振動しやすい周波数(固有周波数)とエンジンの周波数が近いときに生じていたのでしょう。いまのバスではできが良いのでほとんど経験できません。この例では共振と区別しにくいのでもっと良い例があると良いのですが思いつきません。教えてください。うなりの典型的な波形は
unari1.jpg
のようなものです。この図を見れば短い周期の振動がもっと大きな周期の振動に乗っているように見えます。これがうなりです。

同じことが、音の場合も起こりますが、音は周波数が大きいので、上図のようにわかりやすくはありません。まず、
sound_beat_eq1.jpg
の音波を[1]のプログラムで発生させます。A(ラ)の音ですが、わずか2Hz違う440Hzと442Hzの音波が同時に出ます。ではさっそくその音を聞いてみましょう。


いかがですか。まるで調律くるったピアノのようです。この場合2つの弦は2Hzの違いですが、実際の調律では0.1Hz程度の違いに調整するとか。詳しくは知りません。さて、この音を波形でみると
sound_beat.jpg
となり、うなりの周期と比べて440Hzは速いので塗りつぶしになってしまします。しかし、良くうなっている様子がグラフからもわかります。次に高校で習う三角関数の公式を使って、2つの近い周波数の波形の重ね合わせの式を変形してみます。
sound_beat_eq2.jpg
このようにその波形は2つの周波数の中間周波数の振動が、2つの周波数の違いの半分の周波数でうなっていることが式の上でもはっきりわかります。すなわちA(t)という振幅を表す関数が、Δfの周期で変化します(うなります)。

PS:このプログラムのお遊びはこのくらいで次のフェーズに行かなければ・・・

[関連情報]
[1] 周波数当てクイズ, 10/02/24


2010-03-13 00:00  nice!(6)  コメント(13)  トラックバック(0) 
共通テーマ:音楽

440Hzと442Hz再び [理系的音楽道]

同じカテゴリの記事が続くのは良くないと思うのですが、先日の記事[1]で440Hzと442Hzの違いは、ほとんど判別が付かないと書き、区別がつかないというコメントも多く頂きました。また、区別が付くというコメントも頂きましたが、特別な訓練をしていない人は区別できないのが、普通ではないでしょうか。

このブログはピアノに関するブログなので、先日の記事では減衰音を発生させましたが、どうもこれがいけなかったようです。減衰音にすれば、それなりに聞きやすい音に成りますが、減衰せず440Hzと442Hzを続けて演奏すれば区別が付きやすくなるようです。

今日はクイズではありません。次の音は
eq100227.jpg
の音が

440Hz,442Hz,440Hz,442Hz,440Hz,442Hz,440Hz,442Hz

と並んでいます。ただし、切れ目はありません。減衰させていませんので、まさにコンピュータの不快な音そのものです。



いかがですか。私にも区別ができるのですから、こうすると皆さんも区別がつきますよね。区別できなかった人はもう一度きいてみてください。ちなみにプログラムは[1]の記事と同じ物を使いました。

結論的には人間は「440Hz付近の周波数に於いては2Hzの周波数の違いを感じることができる」というものです。たぶん1Hzでも判別可能でしょう。

どうも減衰音は特別な効果があるのかもしれません。実際はどの程度の減衰がある時に判別が難しくなるかなど調べればいろいろあるのでしょうが、音響は専門でないし、仕事でなく、趣味なので、いい加減な調査で終わろうと思います。

[関連情報]
[1] 周波数当てクイズ, 10/02/24


2010-02-27 00:00  nice!(9)  コメント(17)  トラックバック(0) 
共通テーマ:音楽

周波数当てクイズ [理系的音楽道]

 A(ラ)の音が440Hzか442Hzかと言う話題[1]が、Enriqueさんや江州石亭さんのブログでも取り上げられています。そもそも、440Hzと442Hzではどの程度の違いがあるのか試したくなりました。まず、クイズです。

[クイズ]
今から8つの音を出しますが、どのように並んでいるでしょうか。

[A] 440Hz 440Hz 440Hz 440Hz 442Hz 442Hz 442Hz 442Hz
[B] 442Hz 442Hz 442Hz 442Hz 440Hz 440Hz 440Hz 440Hz
[C] 440Hz 440Hz 442Hz 442Hz 440Hz 440Hz 442Hz 442Hz
[D] 442Hz 442Hz 440Hz 440Hz 442Hz 442Hz 440Hz 440Hz
[E] 440Hz 442Hz 440Hz 442Hz 440Hz 442Hz 440Hz 442Hz
[F] 442Hz 440Hz 442Hz 440Hz 442Hz 440Hz 442Hz 440Hz



なんだか、飛行機のシートベルトサインの音を思い出しませんか。答えは後ほど。

これからのことも考え、いろいろ音の実験をするために、プログラムを組んでみました。プログラミング言語はC言語を選びました。C++が良かったかどうかまだ迷っていますが、のちのち、CPU時間が必要そうな予感もあり、OpenMP(並列処理するためのもの)やCUDA(グラフィックボードで計算するもの)をにらみとりあえずC言語です。最も現時点ではとても軽いプログラムです。ちなみにコンパイラ(C言語をマシン語に翻訳するソフト)はgccを使用しています。

プログラムはプログラミングを知っている人には単純なもので、

eq100224.jpg

の周波数の減衰正弦波をCDのサンプリングレート44.1kHzでwavファイルとして書き出すものです。wavファイルの規格はネットで検索すれば、出てきました。本当はmp3なら、かっこいいのですが、規格が難しそうです。趣味ではプログラミングにそれほど時間がかけられませんので、wavファイルをsound itでmp3に変換しました。ちなみにwavファイル自体もメディアプレイヤで再生できます。またmp3化したときに音質低下していて区別が付かなくなっている可能性もあります。

私の感想としては、基本的に440Hzと442Hzは私には区別が付きません。よくよく聞けば音のはじめの違いを感じることができるが、これは答えを知っているためか、本当に分かるのか疑わしいという程度です。絶対音感を持つうちの子ども初号はこの音がA4(国際規格)であることは分かりましたが、実は2種類の音だと言わないと2つの音の違いは分かりませんでした。

[関連情報]
[1] 音階と周波数, 10/02/17

さて、クイズの答えは以下を押して頂ければ出てきますが、仕事と違い趣味なのでプログラムも公開しますので、プログラムをみるとアレルギーの出る方には危険ですから、押さない方がいいかも知れませんね。

プログラムつきで答えが出ます。


2010-02-24 00:00  nice!(5)  コメント(21)  トラックバック(0) 
共通テーマ:音楽

音階と周波数 [理系的音楽道]

 私が理系であることは以前の記事でばれてしましまたが[1]、本日から新しいカテゴリー「理系的音楽道」を始めます。数式やプログラミング言語は理系の人間の言葉です。数式で書くと納得できたりします。芸術家や文系の方が、どどどっと引かれていく音も聞こえるのですが、数式を見るとジンマシンがでる方は、今回はとばして、次回の通常の記事をお読みください。

 さて、今回は音階です。MIDI規格にはNote Numberというものが決まっていて、鍵盤の左が小さい数で、右に行くに従って増えていきます。鍵盤中央の「ラ」または「A」が69と決まっているようです。
..........
60=ド, C
61=ド#, Cis
62=レ, D
63=レ#, Dis
64=ミ, E
65=ファ, F
66=ファ#, Fis
67=ソ, G
68=ソ#, Gis
69=ラ, A
70=ラ#, Ais
71=シ, H
72=ド, C
........
 このNote NumberをNとすると、国際的にN=69は440Hzと決まっているそうです。ただし、ホールなどで固有のAの周波数と言うものがあるようで、必ずしも440Hzである訳ではないようです。ではこの音の周波数とNの関係式は

freqN.jpg

と表すことができます。上式からN-1の周波数からNの周波数は等比級数として求められるのです。

freqN2.jpg

これを初めて知ったのは昨年の夏ですが、いやー感動です。なぜ感動かと言えば、何となく、音階は等差数列と思っていたからです。さらにはじめの式を変形すれば

freqN3.jpg

となるのです。この式も感動的です。Nは鍵盤に相当するので音階です。その周波数は何と対数軸なのです。対数など人類が知らない太古から音楽はあったはずですが、人間の感覚が対数軸だったことに感動です。また数学のこの宇宙における普遍性を感じ感動してしまいます。たぶん、人間は通常使う周波数当たりをよく区別し、あまり使わない高い音は区別する必要がなかったため、対数軸の感覚を持つように進化したのではないでしょうか。

そうなるといろいろ試したくなります。例えば、等差数列で音階を作ると音楽はどのように聞こえるか。十二平均律でなく、十平均律ならどのように聞こえるのだろうか。このようなことも数式で書いていれば、それほど難しくなく試して見ることができるはずです。たぶん、世界でいろいろな人が試しているでしょうが、興味がわきます。しかし、本日は長くなったので、これまでとしましょう。おかしな音楽の世界に最後までおつきあい頂きありがとうございます。

postscript: ちょっと式でかすぎです。次回は小さくします。

[関連情報]
[1] ピアノに音色はない!?, 10/01/27


2010-02-17 00:00  nice!(12)  コメント(26)  トラックバック(0) 
共通テーマ:音楽

理系的音楽道 ブログトップ

このブログの更新情報が届きます

すでにブログをお持ちの方は[こちら]


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。

×

この広告は1年以上新しい記事の更新がないブログに表示されております。