A simple sound library for mbed. I use the Ring Tone Text Transfer Language (RTTTL) to play song with mbed.
Revision 0:4c9dcb64e608, committed 2013-12-11
- Comitter:
- adelino
- Date:
- Wed Dec 11 08:31:19 2013 +0000
- Child:
- 1:b0c0c7d002aa
- Commit message:
- A simple sound Library for mbed
Changed in this revision
Buzzer.cpp | Show annotated file Show diff for this revision Revisions of this file |
Buzzer.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Buzzer.cpp Wed Dec 11 08:31:19 2013 +0000 @@ -0,0 +1,561 @@ +#include "mbed.h" +#include "Buzzer.h" + +const int tab_A[]= {NOTE_A3,NOTE_A4,NOTE_A5,NOTE_A6,NOTE_A7}; + +const int tab_AS[]= {NOTE_AS3,NOTE_AS4,NOTE_AS5,NOTE_AS6,NOTE_AS7}; + +const int tab_B[]= {NOTE_B3,NOTE_B4,NOTE_B5,NOTE_B6,NOTE_B7}; + +const int tab_BS[]= {NOTE_C3,NOTE_C4,NOTE_C5,NOTE_C6,NOTE_C7}; + +const int tab_C[]= {NOTE_C3,NOTE_C4,NOTE_C5,NOTE_C6,NOTE_C7}; + +const int tab_CS[]= {NOTE_CS3,NOTE_CS4,NOTE_CS5,NOTE_CS6,NOTE_CS7}; + +const int tab_D[]= {NOTE_D3,NOTE_D4,NOTE_D5,NOTE_D6,NOTE_D7}; + +const int tab_DS[]= {NOTE_DS3,NOTE_DS4,NOTE_DS5,NOTE_DS6,NOTE_DS7}; + +const int tab_E[]= {NOTE_E3,NOTE_E4,NOTE_E5,NOTE_E6,NOTE_E7}; + +const int tab_ES[]= {NOTE_F3,NOTE_F4,NOTE_F5,NOTE_F6,NOTE_F7}; + +const int tab_F[]= {NOTE_F3,NOTE_F4,NOTE_F5,NOTE_F6,NOTE_F7}; + +const int tab_FS[]= {NOTE_FS3,NOTE_FS4,NOTE_FS5,NOTE_FS6,NOTE_FS7}; + +const int tab_G[]= {NOTE_G3,NOTE_G4,NOTE_G5,NOTE_G6,NOTE_G7}; + +const int tab_GS[]= {NOTE_GS3,NOTE_GS4,NOTE_GS5,NOTE_GS6,NOTE_GS7}; + +#define isDigit(n) (n>='0' && n <= '9') + +//------------------------------ +Note::Note(char _note,bool _isSharp,char _octave,int _duration): + myNoteChar(_note),myIsSharp(_isSharp),myOctave(_octave),myDuration(_duration) +{ + myPeriod_us=calculatePeriod_us(); +} +//-------------------------------- +Note::Note(char* str,int _duration):myDuration(_duration) +{ + parse(str); + myPeriod_us=calculatePeriod_us(); +} +//-------------------------------- +void Note::parse(const char* _str) +{ + int i=0; + + for(i=0; i<3; i++) { + switch(_str[i]) { + // + case 'R': + myNoteChar='R'; + break; + + case 'r': + myNoteChar='R'; + break; + + // + case 'A': + myNoteChar='A'; + break; + case 'a': + myNoteChar='A'; + break; + // + // + case 'B': + myNoteChar='B'; + break; + // + case 'b': + myNoteChar='B'; + break; + // + case 'C': + myNoteChar='C'; + break; + case 'c': + myNoteChar='C'; + break; + // + case 'D': + myNoteChar='D'; + break; + case 'd': + myNoteChar='D'; + break; + // + // + case 'E': + myNoteChar='E'; + break; + // + case 'e': + myNoteChar='E'; + break; + // + case 'F': + myNoteChar='F'; + break; + // + case 'f': + myNoteChar='F'; + break; + // + case 'G': + myNoteChar='G'; + break; + // + case 'g': + myNoteChar='G'; + break; + // + case '%': + myIsSharp=false; + break; + // + // + case '#': + myIsSharp=true; + break; + // + // + case '3': + myOctave=3; + break; + // + // + case '4': + myOctave=4; + break; + // + // + case '5': + myOctave=5; + break; + // + // + case '6': + myOctave=6; + break; + // + // + case '7': + myOctave=7; + break; + + default: + myNoteChar='R'; + break; + } + // + } + // + +} +//-------------------------------- +int Note::calculatePeriod_us(void) +{ + switch(myNoteChar) { + // + case 'p': + return NOTE_R; + // + case 'R': + return NOTE_R; + // + case 'r': + return NOTE_R; + // + case 'A': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_A[myOctave-3]; + } else { + return tab_AS[myOctave-3]; + } + } + break; + // + case 'a': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_A[myOctave-3]; + } else { + return tab_AS[myOctave-3]; + } + } + break; + // + case 'B': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_B[myOctave-3]; + } else { + return tab_BS[myOctave-3]; + } + } + break; + // + case 'b': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_B[myOctave-3]; + } else { + return tab_BS[myOctave-3]; + } + } + break; + // + case 'C': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_C[myOctave-3]; + } else { + return tab_CS[myOctave-3]; + } + } + break; + // + case 'c': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_C[myOctave-3]; + } else { + return tab_CS[myOctave-3]; + } + } + break; + // + // + case 'D': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_D[myOctave-3]; + } else { + return tab_DS[myOctave-3]; + } + } + break; + // + case 'd': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_D[myOctave-3]; + } else { + return tab_DS[myOctave-3]; + } + } + break; + // + case 'E': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_E[myOctave-3]; + } else { + return tab_ES[myOctave-3]; + } + } + break; + // + case 'e': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_E[myOctave-3]; + } else { + return tab_ES[myOctave-3]; + } + } + break; + // + case 'F': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_F[myOctave-3]; + } else { + return tab_FS[myOctave-3]; + } + } + break; + // + case 'f': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_F[myOctave-3]; + } else { + return tab_FS[myOctave-3]; + } + } + break; + // + case 'G': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_G[myOctave-3]; + } else { + return tab_GS[myOctave-3]; + } + } + break; + // + case 'g': + // + if(myOctave >=3 && myOctave <=7) { + if(myIsSharp==false) { + return tab_G[myOctave-3]; + } else { + return tab_GS[myOctave-3]; + } + } + break; + // + default: + break; + } + + return 0; +} +//-------------------------------- +int Note::getNotePeriod_us(void) const +{ + return this->myPeriod_us; +} +//--------------------------------- +bool Note::getIsSharp(void) const +{ + return this->myIsSharp; +} +//---------------------------------- +char Note::getNoteChar(void) const +{ + return this-> myNoteChar; +} +//---------------------------------- +char Note::getOctave(void) const +{ + return this->myOctave; +} +//--------------------------------- +int Note::getDuration(void) const +{ + return this->myDuration; +} +//---------------------------------- +void Note::toString(char* buffer) +{ + + buffer[0]= myNoteChar; + if(myIsSharp) + buffer[1]='#'; + else + buffer[1]='%'; + + buffer[2]=myOctave+'0'; + + buffer[3]='\0'; + +} +//----------------------------------- + + +Buzzer::Buzzer(PinName _pwmOut):PwmOut(_pwmOut) +{ + this->period_us(1); + this->pulsewidth_us(0); +} +//----------------------------------- +void Buzzer::tone(const Note* _note) +{ + int mperiod = _note->getNotePeriod_us(); + + int dure=_note->getDuration(); + + this->period_us(mperiod); + this->pulsewidth_us(mperiod/2); + + wait_ms(dure); + this->pulsewidth_us(0); + + + wait_ms(dure); + +} +//------------------------------------- +Buzzer::~Buzzer() +{ +} +//-------------------------------------- +Music::Music(const char* p) +{ + char defautDuree=4; + char defautOctave=6; + int bmp=63; + + int ronde=0; + int dura=0; + int num=0; + + char _note; + bool _issharp=false; + char _octave=0; + + char newOctave=0; +// + while(*p != ':') + p++; //le titre + + p++; //skip : + + //defaut duration + if(*p=='d') { + p++; + p++; //skip d= + + + while(isDigit(*p)) { + num=(num*10)+(*p++-'0'); + } + // + if(num >0) + defautDuree=num; + p++; //skip , + } + // + if(*p=='o') { + p++; + p++; //skip o= + + num=*p++ -'0'; + + if(num >=3 && num <=7) + defautOctave=num; + + p++; //skip , + + } + // + if(*p =='b') { + p++; + p++; //skip b= + num=0; + + while(isDigit(*p)) { + num=num*10+(*p++ -'0'); + } + bmp=num; + p++; //skip : + } + // + ronde=(60*500/bmp)*4; // in ms + + //les notes + while(*p) { + //ge t duration if available + num=0; + while(isDigit(*p)) { + num=(num*10)+(*p++ -'0'); + } + if(num) + dura=ronde/num; + else + dura=ronde/defautDuree; + //la note + _note=*p; + + p++; + //issharp + if(*p=='#') { + _issharp=true; + p++; + } else { + _issharp=false; + + } + //un point ? + if(*p=='.') { + dura+=dura/2; + p++; + } + // + //nouvelle octave + if(isDigit(*p)) { + newOctave =*p - '0'; + p++; + } + + if(newOctave >0) + _octave=newOctave; + + else { + _octave=defautOctave; + } + + // + if(*p==',') + { + p++; + myTabNotes.push_back(new Note(_note,_issharp,_octave,dura)); + } + + + + + } +} +//-------------------------------------- +int Music::getNumbersNotes(void) const +{ + return this->myTabNotes.size(); +} + +//-------------------------------------- +void Music::play(Buzzer* _buzzer) +{ + /* + char buffer[10]; + int duration=0; + + for(int i=0; i< myTabNotes.size(); i++) { + myTabNotes[i]->toString(buffer); + duration=myTabNotes[i]->getDuration(); + + pc.printf(" %s:%d \n\r",buffer,duration); + } + */ + + for(int i=0; i< myTabNotes.size(); i++) { + _buzzer->tone(myTabNotes[i]); + } + + +} +//-------------------------------------- +Music::~Music() +{ + for(int i=0; i< myTabNotes.size(); i++) { + delete(myTabNotes[i]); + myTabNotes[i]=0; + } +} +//-------------------------------------- + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Buzzer.h Wed Dec 11 08:31:19 2013 +0000 @@ -0,0 +1,212 @@ +#ifndef BUZZER_H +#define BUZZER_H +#include "mbed.h" +#include <vector> + +/** +This is a simple sound library for mbed.I use the RTTTL format +http://en.wikipedia.org/wiki/Ring_Tone_Transfer_Language + +Exemple + +@code +#include "Buzzer.h" + +char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6"; + +Buzzer buzzer(p21); + +Music* pMusic=0; //the song +Note la("A#4",50); //the sound + +int main() +{ + pMusic= new Music(song); + pMusic->play(&buzzer); + + buzzer.tone(&la); + delete(pMusic); +} + +*/ + +// notes definition +#define NOTE_R 0 + +//octave 3 +#define NOTE_C3 7644 +#define NOTE_CS3 7215 +#define NOTE_D3 6810 +#define NOTE_DS3 6428 +#define NOTE_E3 6067 +#define NOTE_F3 5727 +#define NOTE_FS3 5405 +#define NOTE_G3 5102 +#define NOTE_GS3 4815 +#define NOTE_A3 4545 +#define NOTE_AS3 4290 +#define NOTE_B3 4049 + +//octave 4 +#define NOTE_C4 3822 +#define NOTE_CS4 3607 +#define NOTE_D4 3405 +#define NOTE_DS4 3214 +#define NOTE_E4 3033 +#define NOTE_F4 2863 +#define NOTE_FS4 2702 +#define NOTE_G4 2551 +#define NOTE_GS4 2408 +#define NOTE_A4 2272 +#define NOTE_AS4 2145 +#define NOTE_B4 2024 + +//octave 5 +#define NOTE_C5 1911 +#define NOTE_CS5 1804 +#define NOTE_D5 1702 +#define NOTE_DS5 1607 +#define NOTE_E5 1516 +#define NOTE_F5 1432 +#define NOTE_FS5 1351 +#define NOTE_G5 1275 +#define NOTE_GS5 1204 +#define NOTE_A5 1136 +#define NOTE_AS5 1072 +#define NOTE_B5 1012 + +//octave 6 +#define NOTE_C6 956 +#define NOTE_CS6 903 +#define NOTE_D6 852 +#define NOTE_DS6 803 +#define NOTE_E6 759 +#define NOTE_F6 716 +#define NOTE_FS6 676 +#define NOTE_G6 638 +#define NOTE_GS6 602 +#define NOTE_A6 568 +#define NOTE_AS6 536 +#define NOTE_B6 506 + +//octave 7 +#define NOTE_C7 477 +#define NOTE_CS7 451 +#define NOTE_D7 426 +#define NOTE_DS7 402 +#define NOTE_E7 379 +#define NOTE_F7 358 +#define NOTE_FS7 338 +#define NOTE_G7 319 +#define NOTE_GS7 301 +#define NOTE_A7 284 +#define NOTE_AS7 268 +#define NOTE_B7 253 +//------------------------------ +class Note +{ +public: + /** Construct a Note (sound) object. + * + * @param _note the note in range (A,a,B,b,C,c,D,d,E,e,F,f) + * @param _isSharp exemple A4 or A#4 + * @param _duration the time duration + */ + + Note(char _note,bool _isSharp,char _octave,int _duration); + + /** Construct a Note (sound) object. + * + * @param str exemple "C%4" or "C#4" + * @param _duration the time duration + */ + + Note(char* str,int _duration);// exemple "C%4" or "C#4" + + +//setter + +//getter + + /// @returns the note period (PwmOutput) + int getNotePeriod_us(void)const ; + + /// @returns is Sharp + bool getIsSharp(void) const; + + /// @returns the note char + char getNoteChar(void) const; + + /// @returns the octave + char getOctave(void) const; + + /// @returns the duartion in ms + int getDuration(void) const; + + ///use in debugging + void toString(char* buffer); + + +protected: + + int calculatePeriod_us(void); + + void parse(const char* _str); + + char myNoteChar; + bool myIsSharp; + char myOctave; // 3->5 + int myPeriod_us; + int myDuration; + +}; +//---------------------------------- + + +class Buzzer:public PwmOut +{ +public: + /** Construct a Buzzer object. + * + * @param _pwmOut select the PwmOutput + */ + + Buzzer(PinName _pwmOut); + // + ~Buzzer(); + + /// The Buzzer tone a simple sound + void tone(const Note* _note); + + +protected: + +}; + + +//---------------------------------- +class Music +{ +public: + /** Construct a Music object. + * + * @param p the RTTTL song + */ + Music(const char* p); + + ~Music(); + + /// play the music + void play(Buzzer* _buzzer); + + /// @returns the music lenght + int getNumbersNotes(void) const; + +protected: + int nbNotes; + vector<Note*> myTabNotes; + + +}; + +#endif \ No newline at end of file