音の出力

先の「アナログ出力」は一定時間間隔で出力するパルスの幅を変える機能でした。パルスの幅でなくパルスの間隔を変えると音程(音の高さ)の異なる音を出すことができます。これらは、MPUの「タイマー機能」を利用しています。

  1. 音階

     音階は「ドレミ」で表現しますが、低い「ド」から次の「ド」になると周波数は倍になります。「平均率」の音階は、この1オクターブを周波数の比が一定になるよう12等分します。従って、前の音の周波数を1にすると、次の音の周波数は、前の音の約 2^(1/12) = 1.06倍になります(ここで ^ はべき乗の演算子とします)。「ミ」と「ファ」および、「シ」と「ド」以外には半音が入ります。これはピアノ鍵盤の黒鍵に相当します。「ド#」 は「ド」の半音上の音で、これは、「レ」の半音下の「 レ♭」の音と同じです。
     五線譜のラの音の周波数はちょうど 440 ヘルツになりますから、1オクターブ低い「ラ」の音までの周波数は次の表のようになります。 A,B,C..はドイツ音階表記です。A(ラ)の音はきれいな整数値なので、よく楽器の音あわせに利用されます。また、440Hzはラジオの時報の高い音に相当します。
    ドイツ音階 A A# B C C# D D# E F F# G G# A
    ラ# ド# レ# ファ ファ# ソ#
    周波数 220.0 233.1 246.9 261.6 277.2 293.7 311.1 329.6 349.2 369.9 391.9 415.3 440.0
    周波数比 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1 1.1
    周期(mS) 4.5 4.3 4.1 3.8 3.6 3.4 3.2 3.0 2.9 2.7 2.6 2.4 2.3
             音階と周波数

  2. tone 命令

     arduino では端子と周波数と長さを指定してHIGH−LOWを変化させる(パルス出力する) tone関数が利用できます。PWM を利用しますから、PWM用の端子を指定する必要があります。
      tone(出力端子、周波数、長さ);
    音階を周波数に、長さを音符(4分、8分音符)に対応させると、楽譜を演奏することができます。noTone()で音は停止します。長さの時間が経過する前に次の音を指定すると、前の音が消えます。また、異なる端子に別の音を出すことはできません。

      パルス信号

  3. スピーカ

     ここでは10mA程度の電流で音が出る小型のスピーカ-を利用します。圧電式スピーカーは、圧電素子を利用しています。圧電素子はセラミックの1種で、電圧をかけると変形し、逆に機械的圧力をかけると電圧を発生します(ピエゾ効果と呼ばれます)。コイルによる磁力を利用したスピーカーもあります(ダイナミック型とも呼ばれます)。大型(数W以上)のスピーカーの多くはダイナミック型です。
     大型のスピーカーは、大きな電力を必要としますから、「アンプ」と呼ばれる音声信号の増幅回路が必要となります。ここでは、数W(ワット)以下の小型のスピーカーを利用します。
        
       圧電式スピーカー      ダイナミックスピーカー

     一般的にはダイナミックスピーカーの方が良い音になりますが、音の大きさは小さくなります。

  4. スピーカ接続回路

     スピーカーに出力する信号は変化する信号(交流)のみで、平均的な電圧を0とする必要があります。音の信号は PWM 端子から出力できますが、これには直流成分が含まれます。そこで、コンデンサーを用いて直流成分を削除します。また、電流を制限するため、直列に100Ω程度の抵抗を入れます。
     コンデンサーは直流電圧をかけると一定の電力を蓄積し、容量いっぱいになるとそれ以上流れなくなります。電流を水と考えるとコンデンサーは貯水するダムの役割になります。
     コンデンサーには容量 C を定めて製作されます。コンデンサー に V の電圧をかけると Q = C・V の電荷(電気量)が蓄積されます。C の単位は F(ファラッド) で、ここでは 音声レベルの低い周波数を通過させる必要があるため、10μF 程度の電界型コンデンサーを利用します。
     下図は左から、セラミック、タンタル、電解型のコンデンサーで、容量は0.1、1、10μF程度です。電解コンデンサーには極性(プラスとマイナスの区別)があります。長い端子が + です。コンデンサーは局所的な電源補給や、直流分の通過阻止などに利用されます。

       各種コンデンサ                スピーカ接続回路

  5. 音階の配列

     プログラムの先頭で音階の周波数をdefineで定義します。音階は「 ド」から順に C,D,E,F,G,A,H で表します。音階の後に数字をつけて オクターブ の番号を指定します。記号の後にS(#)が付くのは、半音上げの指示です。 ト音記号のオクターブは3、その上を4とします。したがって、C3が低いド、C4が高いドになり、C4はC3の倍の周波数になります。この前に NOTE_ をつけて音階を示します。また、0 は休符になります。
     演奏するメロディーの配列は、次のように、こ音階記号で指定します。
       int melody[] = {NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3,NOTE_C4};
     これは  ドソソラソ シド になります。
     また、各音符の長さを、配列 duration[] に記録します。四分音符は4、8分音符は8、とし、実際の長さは秒をこの数値で割った値(duration)とします。また、音符と音符の間には少し音の無い区間を作ります。ここでは、duration を1.3倍したpause を音符と音符の間隔とします。
    int noteDurations[] = { 4,8,8,4,4,4,4,4 };

  6. 音階演奏プログラム

     melody[] とduration[] 配列の楽譜を演奏します。
     音符の長さは4分音符の場合 4、8分音符の場合8、になります。
    //音階演奏
    #define NOTE_G2  98  //ソ
    #define NOTE_GS2 104 //ソ#
    #define NOTE_A2  110 //ラ
    #define NOTE_AS2 117
    #define NOTE_B2  123
    #define NOTE_C3  131 //ド
    #define NOTE_CS3 139
    #define NOTE_D3  147
    #define NOTE_DS3 156
    #define NOTE_E3  165
    #define NOTE_F3  175
    #define NOTE_FS3 185
    #define NOTE_G3  196
    #define NOTE_GS3 208
    #define NOTE_A3  220
    #define NOTE_AS3 233
    #define NOTE_B3  247
    #define NOTE_C4  262 //ド
    #define NOTE_CS4 277
    #define NOTE_D4  294
    #define NOTE_DS4 311
    #define NOTE_E4  330
    #define NOTE_F4  349
    #define NOTE_FS4 370
    #define NOTE_G4  392
    
    //音符の高さ
    //ドソソラソシド
    int melody[] = {
      NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
    //音符の長さ
    //  4:4分音符, 8:8分音符, etc.:
    int noteDurations[] = { 4,8,8,4,4,4,4,4 };
    
    void setup() {
    
    }
    
    void loop() {
    
       for (int thisNote = 0; thisNote < 8; thisNote++) {
        //発音時間を定める
        int duration = 1000/noteDurations[thisNote];
        tone(8, melody[thisNote],duration);
        //音符の間で時間をあける
        int pause = duration * 1.30;
        delay(pause);
        //演奏停止、なくてもよい
        noTone(8);
      }
      delay(1000);
    }

  7. 発展

     
    1. 音色を変更できませんか?

       波形の強さの包絡線(エンベロープ)で音色が決まります。PWMでもある程度の変化はつけられますが、細かい制御は DA 変換が望まれます。DA変換は 「アナログ出力」の節を参照ください。

    2. 和音の演奏はできませんか?

       和音を合成するには、複数の音の合成が必要です。tone( )命令は、一つの音しか出すことができません。波形テーブルと包絡線を利用した和音合成の方法は、別の本で紹介する予定です。
    3. もっと大きな音を出すには?

       通常オーディオアンプを接続利用します、オーディオアンプはPWMの波形には対応していません。DAコンバーターを利用して、アナログ型の音を合成する必要があります。