このライブラリでは、単音とメロディの出力が可能です。 In this library, you can output a single tone and melody. mbedのpwmOutとDigitalOutを使ってスピーカや圧電ブザーを直接駆動します。 directly drive speaker or buzzer and DigitalOut pwmOut using the mbed. メロディデータは、mbedのローカルにtxtファイルとして保存するか、プログラム中に配列データとして保存してください。 Melody data is either stored in a txt file on the local mbed, save it as a data array in the program.
Dependents: kitchenTimer_Clock SoundLibraryExample_Melody_ProgramData M3PI_SuiviLigne
Sound.cpp
- Committer:
- suupen
- Date:
- 2012-01-15
- Revision:
- 11:c342b5349740
- Parent:
- 10:059d4df77110
- Child:
- 12:66e192fc663e
File content as of revision 11:c342b5349740:
/***********************************************************************/ /* */ /* 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; sound_out(0.0, 0); } } else{ sound_out(0.0, 0); /* // O_sound.syuuki == 0 then sound nasi if(f_muonSet == 1){ f_muonSet = 0; sound_out(0.0, 0); } */ } //************************************************* // 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 // 120115 bug fix ){ // 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){ hatuon_jikan.reset(); // 120108 bug fix 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 }; */