Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SoundSPI.cpp Source File

SoundSPI.cpp

00001 /***********************************************************************/
00002 /*                                                                     */
00003 /*    Sound.cpp                                                        */
00004 /*                                                                     */
00005 /* misoOutput - digtalOutput de sound syuturyoku suru library           */
00006 /***********************************************************************/
00007 #define _SOUND_C
00008 
00009 #include "types.h"
00010 #include "mbed.h"
00011 #include "math.h"
00012 #include "SoundSPI.h"
00013 
00014 LocalFileSystem local("local");
00015 
00016 /*******************************************************************
00017 * syokika
00018 *******************************************************************/
00019 Sound::Sound(PinName pwm, PinName kijun) : _pwm(pwm, NC, NC), _kijun(kijun){
00020     /***********************
00021     * kido ji no yobidasi
00022     ***********************/
00023    sound_timer.attach_us(this, &Sound::pulseCheck, Z_pulseCheckSyuuki);     // oto no hakei syuturyoku check time
00024     
00025     hatuon_jikan.start();   // 1tu no oto no hatuon jikan kakunin
00026     
00027     _pwm.format(Z_pwmBunkaino, 0);     
00028 //    _pwm.frequency((1000000 /Z_pwmSyuuki) * 16);
00029     _pwm.frequency(1500000);
00030     
00031     _pwm.write(0x0000);
00032     _kijun = 0;
00033 
00034 
00035     keikajikan = 0;  // 1tu no oto no keikajikan
00036 
00037     F_pwmSet = 0;    // 0:zenhan hansyuuki 1:kohan hansyuuki  wo request
00038     C_syuukiKeika = 0;
00039     f_muonSet = 0;           // muon ji no sound_out() syori wo kurikaesu no wo fusegu
00040     
00041 }
00042 
00043 
00044 
00045 /*****************************************
00046 * analog output
00047 * siji : syuturyoku siji (0.0 - 1.0) absolute
00048 * fugo : syuturyoku fugo 0:+ 1:-
00049 *****************************************/
00050 void Sound::sound_out(float siji, int8_t fugo){
00051 
00052     // siji no atai wo fugo ga minus no toki hanten
00053     if(fugo == 1){siji = 1.0 - siji;}
00054     _kijun = fugo;
00055    
00056    // pwm sijichi no henkan    siji:float(0.0 - 1.0) kara sijibit:uint8_t(0 - 16), siji_miso:uint16_t(0x0000, 0x0001, 0x0003, ... ,0xFFFE, 0xFFFF) 
00057     uint8_t sijibit = uint8_t(siji * Z_pwmBunkaino);    // 0.0 - 1.0 wo 0 - 16(Z_pwmBunkaino) ni henkan
00058     uint16_t siji_miso = 0;
00059     for(uint8_t i = 0; i < sijibit; i++){
00060         siji_miso = siji_miso << 1;
00061         siji_miso |= 0x0001;
00062     }        
00063     
00064     D_SPIpwm = siji_miso;    
00065 //    _pwm.write(siji_miso);   // 2tuizyo sound out settei site ,interrupt no nakade renzoku de pwm set wo suruto bousou suru.
00066 
00067 }
00068 /*****************************************
00069 * sound hakei pwm output
00070 * time interrupt
00071 *****************************************/
00072 void Sound::pulseCheck(void) {
00073 
00074 //    uint32_t static C_syuukiKeika = 0;
00075 //    uint8_t static f_muonSet = 0;           // muon ji no sound_out() syori wo kurikaesu no wo fusegu
00076 //    uint8_t static F_pwmSet = 0;    // 0:zenhan hansyuuki 1:kohan hansyuuki  wo request
00077     
00078     float D_soundOut;   // syuturyoku suru sinpuku chi (0.0 - 1.0)
00079 
00080     if (O_sound.syuuki != 0) {
00081         f_muonSet = 1;
00082         // sound ari
00083         if (C_syuukiKeika < (O_sound.syuuki / 2.0)) {
00084             // zenhan han syuuki
00085             if (F_pwmSet == 0) {
00086                 F_pwmSet = 1;
00087                 
00088                 D_soundOut = (float)pow(((double)O_sound.envelope / O_sound.shokichienvelope), 2.0);
00089                 sound_out(D_soundOut, 0);
00090             }
00091             C_syuukiKeika += Z_pulseCheckSyuuki;
00092         } else if (C_syuukiKeika < O_sound.syuuki) {
00093             // kohan han syuuki
00094             if (F_pwmSet == 1) {
00095                 F_pwmSet = 2;
00096                 
00097                 D_soundOut =  (float)pow(((double)O_sound.envelope / O_sound.shokichienvelope) , 2.0);
00098                 sound_out(D_soundOut, 1);
00099             }
00100             C_syuukiKeika += Z_pulseCheckSyuuki;
00101 
00102 
00103         } else {
00104             // jikai syuuki settei
00105             F_pwmSet = 0;
00106             C_syuukiKeika = 0;
00107         }
00108 
00109         // envelope jikan no kosin
00110         if (O_sound.envelope > Z_pulseCheckSyuuki) {
00111             O_sound.envelope -= Z_pulseCheckSyuuki;
00112         } else {
00113             O_sound.envelope = 0;
00114             sound_out(0.0, 0);
00115         }
00116     }
00117     else{
00118     sound_out(0.0, 0);
00119 
00120   
00121 
00122     }
00123     
00124     _pwm.write(D_SPIpwm);   // 2tuizyo sound out settei site ,interrupt no nakade renzoku de pwm set wo suruto bousou suru.
00125     
00126     //*************************************************
00127     // 1ms syuuki syori
00128     //*************************************************
00129     C_1msProcess++;
00130     if((C_1msProcess * Z_pulseCheckSyuuki) > 1000){
00131         C_1msProcess = 0;
00132         sound_ensoSyori();
00133     }
00134 }
00135 
00136 
00137 /******************************************************************************
00138 Name           : sound_sound() 
00139 Parameters     : sound_t    .hanon
00140                :            .onkai
00141                :            .time : hatuon jikan(1/1 [ms]/count)
00142                :            .envelope : yoin (1/1 [ms]/count)
00143 Returns        : none
00144 Description    : hitotu no oto no syuturyoku
00145 ******************************************************************************/
00146 //*************************
00147 // oto jyotai check
00148 //      ture : oto ari  chu
00149 //      false: oto nasi chu
00150 //*************************
00151 bool Sound::sound_sound(void){
00152     if (hatuon_jikan.read_ms() < keikajikan){
00153         return(true);
00154     }
00155     else{
00156         return(false);
00157     }
00158 }
00159 
00160 //*************************
00161 // oto syuturyoku
00162 //*************************
00163 void Sound::sound_sound(sound_t data) {
00164 
00165     uint8_t onkai;
00166     uint8_t okutabu;
00167     uint8_t kaicho;
00168 
00169 // oto no frequency                 //    do              re          mi          fa          so          ra          si
00170 const uint16_t DT_onkaiHzN[3][7] = {//    C1              D1          E1          F1          G1          A1          B1        // frequency (1/1 [Hz]/count)
00171                                     {30.8677,        34.6478,    38.8909,    41.2034,    46.2493,    51.9131,    58.2705},    // b
00172                                     {32.7032,        36.7081,    41.2034,    43.6535,    48.9994,    55.0000,    61.7354},    // nomal
00173                                     {34.6478,        38.8909,    43.6535,    46.2493,    51.9131,    58.2705,    65.4064},    // #
00174                                 };
00175 
00176 
00177     // onkai data kara DT_onkaiHzN[][koko] "koko" no number ni henkan
00178     //                                  0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    A,    B,    C,    D,    E,    F
00179     const uint8_t DT_onkaiTrans[16] =  {0,    0,    0,    0,    0,    0,    0,    0,    0,    4,    5,    6,    0,    1,    2,    3};
00180 
00181 
00182         // tugi no hatuon siji
00183         onkai = data.onkai;
00184 
00185         okutabu  = onkai & 0x0f;
00186         kaicho   = DT_onkaiTrans[(onkai & 0xf0) >> 4];
00187 
00188         switch (onkai) {
00189             case 0x00:
00190                 // enso chu (tugi no hatuon nasi settei)
00191                 // case 0xff to onaji syori
00192             case 0xff:
00193                 // enso syuryo
00194                 O_sound.syuuki = 0;      // muon
00195                 break;
00196             default:
00197                 // enso chu & tugi no hatuon settei)
00198                 O_sound.syuuki = 1000000 / (DT_onkaiHzN[data.hanon][kaicho] * (pow(2.0, ((double)okutabu - 1))));
00199                 O_sound.envelope = data.envelope * 1000;
00200                 O_sound.shokichienvelope = data.envelope * 1000;
00201                 break;
00202         }
00203         
00204         // oto no syuturyoku jikan timer restart
00205         hatuon_jikan.reset();
00206         keikajikan = data.time;
00207 }
00208 
00209 /******************************************************************************
00210 Name           : sound_ensoSyori()
00211 Parameters     : none
00212 Returns        : none
00213 Description    : enso ji no tugino onpu data syutoku
00214 ******************************************************************************/
00215 void Sound::sound_ensoSyori(void) {
00216     
00217     // enso data settei
00218     if((sound_sound() == false)     // oto no syuturyoku jikan hantei
00219     && (onpu != NULL)                // enso chu ka wo kakunin          // 120115 bug fix
00220      ){
00221         // tugi no onpu data syutoku
00222         sound_t data = *onpu;
00223         if(data.onkai == 0xff){
00224             onpu = NULL;
00225         }
00226         else{
00227             // tugi no hatuon siji
00228             sound_sound(data);
00229             onpu++;
00230         }
00231     
00232     }
00233 
00234 }
00235 
00236 
00237 
00238 
00239 /******************************************************************************
00240 Name           : sound_enso()
00241 Parameters     : -
00242 Returns        : -
00243 Description    : -
00244 ******************************************************************************/
00245 //***********************************************************
00246 // load enso data(mbed drive) 
00247 //      Parameter : "/local/enso.txt"  (data name = enso.txt)
00248 //***********************************************************
00249 bool Sound::sound_enso(char *path) {
00250     int32_t ans;
00251 
00252     // file open
00253     FILE *stm = fopen(path,"r");
00254     if(stm == NULL){
00255         return (false);
00256     }
00257  
00258     // enso data set
00259     uint8_t i = 0;
00260     do{
00261         ans = fscanf(stm, "%x%d%d", &enso[i].onkai, &enso[i].time, &enso[i].envelope);
00262         i++;
00263        
00264     }while((ans != EOF) & (i < 100));
00265  
00266     fclose(stm);
00267 
00268      ensoDataTable = enso;
00269      
00270      return (true);
00271 }
00272 
00273 //***********************************************************************
00274 // load enso data(program data table)
00275 //      Parameter : (Sound::sound_t*)DEMEKIN (data table name = DEMEKIN)
00276 //***********************************************************************
00277 void Sound::sound_enso(Sound::sound_t* onpudata) {
00278     ensoDataTable = onpudata;
00279 }
00280 
00281 
00282 //*************************
00283 // enso jyotai check
00284 //      ture : enso chu
00285 //      false: enso syuryo
00286 //*************************
00287 bool Sound::sound_enso(void) {
00288     bool ans;
00289 
00290     if(onpu != NULL){
00291         ans = true;
00292     }
00293     else{
00294         ans = false;
00295     }
00296     return (ans);
00297 }
00298 
00299 //*******************
00300 // enso start / stop 
00301 //      true : start
00302 //      false: stop
00303 //*******************
00304 void Sound::sound_enso(bool siji){
00305     if(siji == true){
00306         hatuon_jikan.reset();               // 120108 bug fix
00307         keikajikan = 0;                     // 120115 bug fix
00308         onpu = (sound_t*)ensoDataTable;
00309     }
00310     else{
00311         onpu = NULL;   
00312     }
00313 }
00314 
00315 
00316 
00317 
00318 
00319 /******************************************************************************
00320 Name           : enso data sample
00321 Parameters     : -
00322 Returns        : -
00323 Description    : -
00324 ******************************************************************************/
00325 /*
00326 //------------------------------
00327 // "demekin no uta" merody data
00328 //------------------------------
00329     const sound_t DEMEKIN[] =     {
00330     //  onkai,hatuon jikan[ms]
00331         {1,0xC5,600,500},     // de
00332         {1,0xE5,600,500},     // me
00333         {1,0x95,600,500},     // kin
00334         {1,0x00,600,500},
00335 
00336         {1,0xC5,600,500},     // de
00337         {1,0xE5,600,500},     // me
00338         {1,0x95,600,500},     // kin
00339         {1,0x00,600,500},
00340 
00341         {1,0xC5,600,500},     // de
00342         {1,0xE5,600,500},     // me
00343         {1,0x95,600,500},     // kin
00344         {1,0x95,600,500},     // no
00345         {1,0x95,150,500},     // shi
00346         {1,0x00,900,500},
00347         {1,0xE5,750,500},     // po
00348         {1,0x00,450,500},
00349 
00350         {1,0xC5,600,500},     // de
00351         {1,0xE5,600,500},     // me
00352         {1,0x95,600,500},     // kin
00353         {1,0x00,600,500},
00354 
00355         {1,0xC5,600,500},     // de
00356         {1,0xE5,600,500},     // me
00357         {1,0x95,600,500},     // kin
00358         {1,0x00,600,500},
00359 
00360         {1,0x95,600,500},     // ju
00361         {1,0xE5,600,500},     // go
00362         {1,0xD5,600,500},     // n
00363         {1,0xC5,600,500},     // no
00364         {1,0xE5,150,500},     // shi
00365         {1,0x00,900,500},
00366         {1,0xC5,750,500},     // po
00367         {1,0x00,1350,500},
00368 
00369         {1,0xFF,0,0},    // end
00370 
00371     };
00372 
00373 //---------------------------------
00374 // "westminster chime" merody data
00375 //---------------------------------
00376     const sound_t WESTMINSTER[] =     {
00377     //  onkai,hatuon jikan[ms]
00378         {1,0xA4,1200,1000},
00379         {1,0xF4,1200,1000},
00380         {1,0x94,1200,1000},
00381         {1,0xC4,2400,1000},
00382 
00383         {1,0xC4,1200,1000},
00384         {1,0x94,1200,1000},
00385         {1,0xA4,1200,1000},
00386         {1,0xF4,2400,1000},
00387  
00388         
00389         {1,0xFF,0,0},    // end
00390     };
00391 
00392 //------------------------------
00393 // "ramen chime" merody data
00394 //------------------------------
00395     const sound_t RAMEN[] =     {
00396     //  onkai,hatuon jikan[ms]
00397         {1,0xC5,300,500},
00398         {1,0xD5,300,500},
00399         {1,0xE5,1200,500},
00400         {1,0xD5,600,500},
00401         {1,0xC5,1200,500},
00402 
00403         {1,0xC5,300,500},
00404         {1,0xD5,300,500},
00405         {1,0xE5,300,500},
00406         {1,0xD5,300,500},
00407         {1,0xC5,300,500},
00408         {1,0xD5,1800,500},
00409 
00410         
00411         {1,0xFF,0,0},    // end
00412     };
00413 */
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467