Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Dependents: PwmSpeaker-Example
Speaker.cpp
00001 #include "Speaker.h" 00002 00003 static int notes[] = {0, 00004 NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4, 00005 NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5, 00006 NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6, 00007 NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7 00008 }; 00009 00010 /** 00011 * Set output frequency of the speaker. 00012 * 00013 * \param frequency The frequency to set 00014 */ 00015 void Speaker::set_frequency(uint32_t frequency) { 00016 _pwm.period(1.0/frequency); 00017 } 00018 00019 /** 00020 * Enable or disable speaker output. 00021 * 00022 * \param enable Whether to enable or disable the speaker 00023 */ 00024 void Speaker::enable(bool enable) { 00025 *this = enable; 00026 } 00027 00028 /** 00029 * Enable or disable the speaker output. 00030 * 00031 * \param setting 0 to disable speaker, other values to enable speaker. 00032 */ 00033 Speaker& Speaker::operator=(int setting) { 00034 if (setting) { 00035 _pwm = 0.5; 00036 } else { 00037 _pwm = 1; 00038 } 00039 return *this; 00040 } 00041 00042 /** 00043 * Play an old-school ringtone in RTTTL language. 00044 * 00045 * \param p Char array in RTTTL format 00046 */ 00047 void Speaker::play_rtttl(char * p) { 00048 // Absolutely no error checking in here 00049 00050 uint8_t default_dur = 4; 00051 uint8_t default_oct = 6; 00052 int bpm = 63; 00053 int num; 00054 long wholenote; 00055 long duration; 00056 uint8_t note; 00057 uint8_t scale; 00058 00059 // format: d=N,o=N,b=NNN: 00060 // find the start (skip name, etc) 00061 00062 while(*p != ':') p++; // ignore name 00063 p++; // skip ':' 00064 00065 // get default duration 00066 if(*p == 'd') 00067 { 00068 p++; p++; // skip "d=" 00069 num = 0; 00070 while(isdigit(*p)) 00071 { 00072 num = (num * 10) + (*p++ - '0'); 00073 } 00074 if(num > 0) default_dur = num; 00075 p++; // skip comma 00076 } 00077 00078 printf("ddur: %d\n", default_dur); 00079 00080 // get default octave 00081 if(*p == 'o') 00082 { 00083 p++; p++; // skip "o=" 00084 num = *p++ - '0'; 00085 if(num >= 3 && num <=7) default_oct = num; 00086 p++; // skip comma 00087 } 00088 00089 printf("doct: %d\n", default_oct); 00090 00091 // get BPM 00092 if(*p == 'b') 00093 { 00094 p++; p++; // skip "b=" 00095 num = 0; 00096 while(isdigit(*p)) 00097 { 00098 num = (num * 10) + (*p++ - '0'); 00099 } 00100 bpm = num; 00101 p++; // skip colon 00102 } 00103 00104 printf("bpm: %d\n",bpm); 00105 00106 // BPM usually expresses the number of quarter notes per minute 00107 wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) 00108 00109 printf("wn: %d\n", wholenote); 00110 00111 00112 // now begin note loop 00113 while(*p) 00114 { 00115 // first, get note duration, if available 00116 num = 0; 00117 while(isdigit(*p)) 00118 { 00119 num = (num * 10) + (*p++ - '0'); 00120 } 00121 00122 if(num) duration = wholenote / num; 00123 else duration = wholenote / default_dur; // we will need to check if we are a dotted note after 00124 00125 // now get the note 00126 note = 0; 00127 00128 switch(*p) 00129 { 00130 case 'c': 00131 note = 1; 00132 break; 00133 case 'd': 00134 note = 3; 00135 break; 00136 case 'e': 00137 note = 5; 00138 break; 00139 case 'f': 00140 note = 6; 00141 break; 00142 case 'g': 00143 note = 8; 00144 break; 00145 case 'a': 00146 note = 10; 00147 break; 00148 case 'b': 00149 note = 12; 00150 break; 00151 case 'p': 00152 default: 00153 note = 0; 00154 } 00155 p++; 00156 00157 // now, get optional '#' sharp 00158 if(*p == '#') 00159 { 00160 note++; 00161 p++; 00162 } 00163 00164 // now, get optional '.' dotted note 00165 if(*p == '.') 00166 { 00167 duration += duration/2; 00168 p++; 00169 } 00170 00171 // now, get scale 00172 if(isdigit(*p)) 00173 { 00174 scale = *p - '0'; 00175 p++; 00176 } 00177 else 00178 { 00179 scale = default_oct; 00180 } 00181 00182 scale += _offset; 00183 00184 if(*p == ',') 00185 p++; // skip comma for next note (or we may be at the end) 00186 00187 // now play the note 00188 00189 if(note) 00190 { 00191 //printf("\027\033H"); 00192 //printf("Playing: %d %d (%d) %d\n", scale, note, notes[(scale - 4) * 12 + note], duration); 00193 set_frequency(notes[(scale - 4) * 12 + note]); 00194 enable(true); 00195 wait_ms(duration); 00196 enable(false); 00197 } 00198 else 00199 { 00200 //printf("Pausing: %d\n", duration); 00201 wait_ms(duration); 00202 } 00203 } 00204 }
Generated on Wed Jul 20 2022 21:53:52 by
