以前のLibraryでは、スピーカ出力にPWM,DigitalOutを使いましたが、これは、両方ともPWMにしたものです。LPC1114FN28ではDigitalOutにノイズが乗ることがありその対応です。

Dependents:   kitchenTimer LPC1114FN28_kitchenTimer_Clock

Fork of Sound by suu pen

Revision:
0:e3f005984c2a
Child:
9:5385907711e0
Child:
13:cd42abff5173
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sound.cpp	Wed Nov 16 12:03:27 2011 +0000
@@ -0,0 +1,453 @@
+/***********************************************************************/
+/*                                                                     */
+/*    Sound.cpp                                                        */
+/*                                                                     */
+/* pwmOutput - digtalOutput de sound syuturyoku suru library           */
+/***********************************************************************/
+#define _SOUND_C
+
+#include "types.h"
+#include "mbed.h"
+#include "math.h"
+#include "Sound.h"
+
+LocalFileSystem local("local");
+
+/*******************************************************************
+* syokika
+*******************************************************************/
+Sound::Sound(PinName pwm, PinName kijun) : _pwm(pwm), _kijun(kijun){
+    /***********************
+    * kido ji no yobidasi
+    ***********************/
+   sound_timer.attach_us(this, &Sound::pulseCheck, Z_pulseCheckSyuuki);     // oto no hakei syuturyoku check time
+    
+    hatuon_jikan.start();   // 1tu no oto no hatuon jikan kakunin
+         
+    _pwm.period_us(Z_pwmSyuuki);
+    
+    _pwm.write(0.0);
+    _kijun = 0;
+
+
+    keikajikan = 0;  // 1tu no oto no keikajikan
+
+    F_pwmSet = 0;    // 0:zenhan hansyuuki 1:kohan hansyuuki  wo request
+    C_syuukiKeika = 0;
+    f_muonSet = 0;           // muon ji no sound_out() syori wo kurikaesu no wo fusegu
+    
+}
+
+
+
+/*****************************************
+* analog output
+* siji : syuturyoku siji (0.0 - 1.0) absolute
+* fugo : syuturyoku fugo 0:+ 1:-
+*****************************************/
+void Sound::sound_out(float siji, int8_t fugo){
+
+    // siji no atai wo fugo ga minus no toki hanten
+    if(fugo == 1){siji = 1.0 - siji;}
+    _kijun = fugo;
+      
+    _pwm.write(siji);   // 2tuizyo sound out settei site ,interrupt no nakade renzoku de pwm set wo suruto bousou suru.
+
+}
+/*****************************************
+* sound hakei pwm output
+* time interrupt
+*****************************************/
+void Sound::pulseCheck(void) {
+
+//    uint32_t static C_syuukiKeika = 0;
+//    uint8_t static f_muonSet = 0;           // muon ji no sound_out() syori wo kurikaesu no wo fusegu
+//    uint8_t static F_pwmSet = 0;    // 0:zenhan hansyuuki 1:kohan hansyuuki  wo request
+    
+    float D_soundOut;   // syuturyoku suru sinpuku chi (0.0 - 1.0)
+
+    if (O_sound.syuuki != 0) {
+        f_muonSet = 1;
+        // sound ari
+        if (C_syuukiKeika < (O_sound.syuuki / 2.0)) {
+            // zenhan han syuuki
+            if (F_pwmSet == 0) {
+                F_pwmSet = 1;
+                
+                D_soundOut = (float)pow(((double)O_sound.envelope / O_sound.shokichienvelope), 2.0);
+                sound_out(D_soundOut, 0);
+            }
+            C_syuukiKeika += Z_pulseCheckSyuuki;
+        } else if (C_syuukiKeika < O_sound.syuuki) {
+            // kohan han syuuki
+            if (F_pwmSet == 1) {
+                F_pwmSet = 2;
+                
+                D_soundOut =  (float)pow(((double)O_sound.envelope / O_sound.shokichienvelope) , 2.0);
+                sound_out(D_soundOut, 1);
+            }
+            C_syuukiKeika += Z_pulseCheckSyuuki;
+
+
+        } else {
+            // jikai syuuki settei
+            F_pwmSet = 0;
+            C_syuukiKeika = 0;
+        }
+
+        // envelope jikan no kosin
+        if (O_sound.envelope > Z_pulseCheckSyuuki) {
+            O_sound.envelope -= Z_pulseCheckSyuuki;
+        } else {
+            O_sound.envelope = 0;
+        }
+    }
+    else{
+    // O_sound.syuuki == 0 then sound nasi
+    
+        if(f_muonSet == 0){
+            f_muonSet = 1;
+            sound_out(0.0, 0);      // 5us
+        }
+    }
+    
+    //*************************************************
+    // 1ms syuuki syori
+    //*************************************************
+    C_1msProcess++;
+    if((C_1msProcess * Z_pulseCheckSyuuki) > 1000){
+        C_1msProcess = 0;
+        sound_ensoSyori();
+    }
+}
+
+
+/******************************************************************************
+Name           : sound_sound() 
+Parameters     : sound_t    .hanon
+               :            .onkai
+               :            .time : hatuon jikan(1/1 [ms]/count)
+               :            .envelope : yoin (1/1 [ms]/count)
+Returns        : none
+Description    : hitotu no oto no syuturyoku
+******************************************************************************/
+//*************************
+// oto jyotai check
+//      ture : oto ari  chu
+//      false: oto nasi chu
+//*************************
+bool Sound::sound_sound(void){
+    if (hatuon_jikan.read_ms() < keikajikan){
+        return(true);
+    }
+    else{
+        return(false);
+    }
+}
+
+//*************************
+// oto syuturyoku
+//*************************
+void Sound::sound_sound(sound_t data) {
+
+    uint8_t onkai;
+    uint8_t okutabu;
+    uint8_t kaicho;
+
+// oto no frequency                 //    do              re          mi          fa          so          ra          si
+const uint16_t DT_onkaiHzN[3][7] = {//    C1              D1          E1          F1          G1          A1          B1        // frequency (1/1 [Hz]/count)
+                                    {30.8677,        34.6478,    38.8909,    41.2034,    46.2493,    51.9131,    58.2705},    // b
+                                    {32.7032,        36.7081,    41.2034,    43.6535,    48.9994,    55.0000,    61.7354},    // nomal
+                                    {34.6478,        38.8909,    43.6535,    46.2493,    51.9131,    58.2705,    65.4064},    // #
+                                };
+
+
+    // onkai data kara DT_onkaiHzN[][koko] "koko" no number ni henkan
+    //                                  0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    A,    B,    C,    D,    E,    F
+    const uint8_t DT_onkaiTrans[16] =  {0,    0,    0,    0,    0,    0,    0,    0,    0,    4,    5,    6,    0,    1,    2,    3};
+
+
+        // tugi no hatuon siji
+        onkai = data.onkai;
+
+        okutabu  = onkai & 0x0f;
+        kaicho   = DT_onkaiTrans[(onkai & 0xf0) >> 4];
+
+        switch (onkai) {
+            case 0x00:
+                // enso chu (tugi no hatuon nasi settei)
+                // case 0xff to onaji syori
+            case 0xff:
+                // enso syuryo
+                O_sound.syuuki = 0;      // muon
+                break;
+            default:
+                // enso chu & tugi no hatuon settei)
+                O_sound.syuuki = 1000000 / (DT_onkaiHzN[data.hanon][kaicho] * (pow(2.0, ((double)okutabu - 1))));
+                O_sound.envelope = data.envelope * 1000;
+                O_sound.shokichienvelope = data.envelope * 1000;
+                break;
+        }
+        
+        // oto no syuturyoku jikan timer restart
+        hatuon_jikan.reset();
+        keikajikan = data.time;
+}
+
+/******************************************************************************
+Name           : sound_ensoSyori()
+Parameters     : none
+Returns        : none
+Description    : enso ji no tugino onpu data syutoku
+******************************************************************************/
+void Sound::sound_ensoSyori(void) {
+    
+    // enso data settei
+    if((sound_sound() == false)     // oto no syuturyoku jikan hantei
+    & (onpu != NULL)                // enso chu ka wo kakunin
+     ){
+        // tugi no onpu data syutoku
+        sound_t data = *onpu;
+        if(data.onkai == 0xff){
+            onpu = NULL;
+        }
+        else{
+            // tugi no hatuon siji
+            sound_sound(data);
+            onpu++;
+        }
+    
+    }
+
+}
+
+
+
+
+/******************************************************************************
+Name           : sound_enso()
+Parameters     : -
+Returns        : -
+Description    : -
+******************************************************************************/
+//***********************************************************
+// load enso data(mbed drive) 
+//      Parameter : "/local/enso.txt"  (data name = enso.txt)
+//***********************************************************
+bool Sound::sound_enso(char *path) {
+    int32_t ans;
+
+    // file open
+    FILE *stm = fopen(path,"r");
+    if(stm == NULL){
+        return (false);
+    }
+ 
+    // enso data set
+    uint8_t i = 0;
+    do{
+        ans = fscanf(stm, "%x%d%d", &enso[i].onkai, &enso[i].time, &enso[i].envelope);
+        i++;
+       
+    }while((ans != EOF) & (i < 100));
+ 
+    fclose(stm);
+
+     ensoDataTable = enso;
+     
+     return (true);
+}
+
+//***********************************************************************
+// load enso data(program data table)
+//      Parameter : (Sound::sound_t*)DEMEKIN (data table name = DEMEKIN)
+//***********************************************************************
+void Sound::sound_enso(Sound::sound_t* onpudata) {
+    ensoDataTable = onpudata;
+}
+
+
+//*************************
+// enso jyotai check
+//      ture : enso chu
+//      false: enso syuryo
+//*************************
+bool Sound::sound_enso(void) {
+    bool ans;
+
+    if(onpu != NULL){
+        ans = true;
+    }
+    else{
+        ans = false;
+    }
+    return (ans);
+}
+
+//*******************
+// enso start / stop 
+//      true : start
+//      false: stop
+//*******************
+void Sound::sound_enso(bool siji){
+    if(siji == true){
+        onpu = (sound_t*)ensoDataTable;
+    }
+    else{
+        onpu = NULL;   
+    }
+}
+
+
+
+
+
+/******************************************************************************
+Name           : enso data sample
+Parameters     : -
+Returns        : -
+Description    : -
+******************************************************************************/
+/*
+//------------------------------
+// "demekin no uta" merody data
+//------------------------------
+    const sound_t DEMEKIN[] =     {
+    //  onkai,hatuon jikan[ms]
+        {1,0xC5,600,500},     // de
+        {1,0xE5,600,500},     // me
+        {1,0x95,600,500},     // kin
+        {1,0x00,600,500},
+
+        {1,0xC5,600,500},     // de
+        {1,0xE5,600,500},     // me
+        {1,0x95,600,500},     // kin
+        {1,0x00,600,500},
+
+        {1,0xC5,600,500},     // de
+        {1,0xE5,600,500},     // me
+        {1,0x95,600,500},     // kin
+        {1,0x95,600,500},     // no
+        {1,0x95,150,500},     // shi
+        {1,0x00,900,500},
+        {1,0xE5,750,500},     // po
+        {1,0x00,450,500},
+
+        {1,0xC5,600,500},     // de
+        {1,0xE5,600,500},     // me
+        {1,0x95,600,500},     // kin
+        {1,0x00,600,500},
+
+        {1,0xC5,600,500},     // de
+        {1,0xE5,600,500},     // me
+        {1,0x95,600,500},     // kin
+        {1,0x00,600,500},
+
+        {1,0x95,600,500},     // ju
+        {1,0xE5,600,500},     // go
+        {1,0xD5,600,500},     // n
+        {1,0xC5,600,500},     // no
+        {1,0xE5,150,500},     // shi
+        {1,0x00,900,500},
+        {1,0xC5,750,500},     // po
+        {1,0x00,1350,500},
+
+        {1,0xFF,0,0},    // end
+
+    };
+
+//---------------------------------
+// "westminster chime" merody data
+//---------------------------------
+    const sound_t WESTMINSTER[] =     {
+    //  onkai,hatuon jikan[ms]
+        {1,0xA4,1200,1000},
+        {1,0xF4,1200,1000},
+        {1,0x94,1200,1000},
+        {1,0xC4,2400,1000},
+
+        {1,0xC4,1200,1000},
+        {1,0x94,1200,1000},
+        {1,0xA4,1200,1000},
+        {1,0xF4,2400,1000},
+ 
+        
+        {1,0xFF,0,0},    // end
+    };
+
+//------------------------------
+// "ramen chime" merody data
+//------------------------------
+    const sound_t RAMEN[] =     {
+    //  onkai,hatuon jikan[ms]
+        {1,0xC5,300,500},
+        {1,0xD5,300,500},
+        {1,0xE5,1200,500},
+        {1,0xD5,600,500},
+        {1,0xC5,1200,500},
+
+        {1,0xC5,300,500},
+        {1,0xD5,300,500},
+        {1,0xE5,300,500},
+        {1,0xD5,300,500},
+        {1,0xC5,300,500},
+        {1,0xD5,1800,500},
+
+        
+        {1,0xFF,0,0},    // end
+    };
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+