A simple sound library for mbed. I use the Ring Tone Text Transfer Language (RTTTL) to play song with mbed.

Dependents:   acd52832_buzzer

Files at this revision

API Documentation at this revision

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