2011年12月31日 星期六

Netduino--播放音樂

聲音如何產生 ?

聲音是音頻振動的效果,音頻的範圍是20Hz到200kHz,

人耳可辨識的範圍約是200Hz到20kHz。喇叭或蜂鳴器可將電器信號轉換成聲音,一般音響電路是以正弦波信號驅動喇叭,以產生悅耳音樂。

clip_image002

在數位電路裡,則是以脈波信號驅動蜂鳴器,產生聲音。

clip_image004

如何讓喇叭發出聲音呢 ?

將電池電源正負極分別接到喇叭的兩端,就會聽到”喀、喀”,那是電流通過線圈產生磁力,與中央帶有磁性的鐵塊產生互斥(或相吸),帶動黑色的喇叭紙盆前後震動所發出的聲音

clip_image006 clip_image008

如果要發出特定音調(例如低音 Do 頻率是262Hz),只要利用程式控制某個輸出腳位的輸出電壓不斷的0、1 變化(也就是0V、5V變化),若變化的頻率與低音Do相同,就可以聽到了。

如何控制輸出腳位產生0、1 變化,讓喇叭發出音調 ?

clip_image010

例如下列程式片段可以控制第9號輸出腳位,產生周期為1000us=1ms=0.001秒的方波(相當於頻率為1 / 0.001=1000Hz),約等於中音Si。

    static PWM speaker = new PWM(Pins.GPIO_PIN_D9);

    speaker.SetPulse(1000,500);   // (全週期, 半週期)

 

 

實驗線路圖如下

clip_image013[4]

 

程式如下,可以演奏一小段旋律

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace MyMusic
{
    public class Program
    {

        static PWM speaker = new PWM(Pins.GPIO_PIN_D9);

        static char[] music = "geefddcdefggg geefddceggc ".ToCharArray();  //音樂簡譜
        static int[] beats = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 0,   //音樂節拍表
                               1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 4, 8 };
        static int tempo = 300;  //單一拍的時間長度

        /// <summary>
        /// 控制喇叭發出聲音
        /// </summary>
        /// <param name="tone">音調半周期時間</param>
        /// <param name="duration">聲音長度</param>
        static void mTone(int tone, int time)
        {   // SetPulse (uint period_ns, unit hightime_ns);
            speaker.SetPulse((uint)( tone * 2), (uint) tone);  // (全週期, 半週期)
            Thread.Sleep(time);
        }

        /// <summary>
        /// 控制喇叭發出聲音
        /// </summary>
        /// <param name="note">音調符號</param>
        /// <param name="duration">聲音長度</param>
        static void mTone(char ch, int time)
        {
            int tone;
            switch (ch) {  //定義聲音PWM的半周期時間(ns)
                case 'c': tone = 1915; break;
                case 'd': tone = 1700; break;
                case 'e': tone = 1519; break;
                case 'f': tone = 1432; break;
                case 'g': tone = 1275; break;
                case 'a': tone = 1136; break;
                case 'b': tone = 1014; break;
                case 'C': tone =  956; break;
                default: tone = 0; break;
            }
            mTone(tone, time);
        }

        //播放音樂
        public static void Main()
        {
            while (true)
            {
                for (int i=0; i<music.Length; i++)
                {
                    mTone(music[i], beats[i] * tempo);
                    mTone(0, tempo/10);  //每音符之後斷音一下子
                }
            }
        }
    }
}

 

沒有留言:

張貼留言