This is a simple sound library for mbed. This sound library uses a Ticker to simulate a 50% duty cycle pwm signal on any pin. The frequency of this signal can be varied to allow sound to be created by any piezoelectric device that is connected to that pin.

Dependents:   SuperMbedBall Tono

About

This library allows for a buzzer (or piezoelectric device) to output sound based on any inputted frequency. The library provides predefined note frequencies which make song writing convenient. These definitions can be found here. Some pins may not be able to drive output such as the AnalogIn pins on the LPC11U24 model. Only pin 21 seemed to work well so far on this model.

Hardware

One wire from a buzzer is connected to any pin on the mbed and the other wire is connected directly to ground. To reduce the volume of the buzzer, an optional resistor can be connected in series as shown. /media/uploads/mdu7078/buzzer001.png

Circuit diagram constructed using CircuitLab.

Usage

A music object is constructed in the following way:

Constructor

#include "Music.h"

music ms(p21);

This code snipped attaches a frequency modulating Ticker to the specified pin.

This frequency can be modified by setting:

Frequency

ms.freq(240);

To allow more complex behavior, a parsing function is included that can take in strings of formatted input and turn them into songs. This input must be formatted as specified below:

  • A capital letter must be present to specify the note, or R to specify a rest (Only letters A-G, and R are valid)
  • An octave must be specified which is any integer from 0 to 8 inclusive
  • An optional sharp sign ( # ) can be added to augment the note a half step
  • A colon ( : ) must separate the octave and note from the duration
  • The duration must be an integer greater than 0, and less than or equal to 64
  • To separate notes, a semicolon ( ; ) must be used

Furthermore, the length of the string must be specified in order for the entire string to be parsed and a tempo must be provided (beats per minute). An example of this is shown below:

Play a Song

/* This is a test song */
char s1[] = "E4:8; E4:8; R:8; E4:8; R:8; C4:8; E4:4; G4:4; R:4; G3:4; R:4;";
int len = 61;

/* Set up music pin on pin 21 */
music m1(p21);
double tempo = 180;

m1.play(s1,tempo,len);

This code plays the familiar 7-note opening to the Super Mario Brothers theme song. The possibilities for music creation are limited only by the hard memory limits of the mbed.

Committer:
mdu7078
Date:
Tue Apr 30 03:49:24 2013 +0000
Revision:
2:c33ed3d85f97
Parent:
1:51cf7b1a96bd
All functions finalized and working!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mdu7078 1:51cf7b1a96bd 1 /* * * * * * * * * * * * * * * * * * * * * * * * * * *
mdu7078 1:51cf7b1a96bd 2 * This is a definitions class for music notes and *
mdu7078 1:51cf7b1a96bd 3 * their frequencies. *
mdu7078 1:51cf7b1a96bd 4 * *
mdu7078 1:51cf7b1a96bd 5 * Created by: Michael Dushkoff (mad1841@rit.edu) *
mdu7078 1:51cf7b1a96bd 6 * * * * * * * * * * * * * * * * * * * * * * * * * * */
mdu7078 1:51cf7b1a96bd 7
mdu7078 1:51cf7b1a96bd 8 #include "mbed.h"
mdu7078 1:51cf7b1a96bd 9 #include "Notes.h"
mdu7078 1:51cf7b1a96bd 10
mdu7078 1:51cf7b1a96bd 11 // Initialize local note arrays for indexing
mdu7078 1:51cf7b1a96bd 12 double _A[] = {NOTE_A0, NOTE_A1, NOTE_A2, NOTE_A3, NOTE_A4,
mdu7078 1:51cf7b1a96bd 13 NOTE_A5, NOTE_A6, NOTE_A7};
mdu7078 1:51cf7b1a96bd 14 double _AS[] = {NOTE_AS0, NOTE_AS1, NOTE_AS2, NOTE_AS3, NOTE_AS4,
mdu7078 1:51cf7b1a96bd 15 NOTE_AS5, NOTE_AS6, NOTE_AS7};
mdu7078 1:51cf7b1a96bd 16 double _B[] = {NOTE_B0, NOTE_B1, NOTE_B2, NOTE_B3, NOTE_B4,
mdu7078 1:51cf7b1a96bd 17 NOTE_B5, NOTE_B6, NOTE_B7};
mdu7078 1:51cf7b1a96bd 18 double _BS[] = {NOTE_C0, NOTE_C1, NOTE_C2, NOTE_C3, NOTE_C4,
mdu7078 1:51cf7b1a96bd 19 NOTE_C5, NOTE_C6, NOTE_C7, NOTE_C8};
mdu7078 1:51cf7b1a96bd 20 double _C[] = {NOTE_C0, NOTE_C1, NOTE_C2, NOTE_C3, NOTE_C4,
mdu7078 1:51cf7b1a96bd 21 NOTE_C5, NOTE_C6, NOTE_C7, NOTE_C8};
mdu7078 1:51cf7b1a96bd 22 double _CS[] = {NOTE_CS0, NOTE_CS1, NOTE_CS2, NOTE_CS3, NOTE_CS4,
mdu7078 1:51cf7b1a96bd 23 NOTE_CS5, NOTE_CS6, NOTE_CS7, NOTE_CS8};
mdu7078 1:51cf7b1a96bd 24 double _D[] = {NOTE_D0, NOTE_D1, NOTE_D2, NOTE_D3, NOTE_D4,
mdu7078 1:51cf7b1a96bd 25 NOTE_D5, NOTE_D6, NOTE_D7, NOTE_D8};
mdu7078 1:51cf7b1a96bd 26 double _DS[] = {NOTE_DS0, NOTE_DS1, NOTE_DS2, NOTE_DS3, NOTE_DS4,
mdu7078 1:51cf7b1a96bd 27 NOTE_DS5, NOTE_DS6, NOTE_DS7, NOTE_DS8};
mdu7078 1:51cf7b1a96bd 28 double _E[] = {NOTE_E0, NOTE_E1, NOTE_E2, NOTE_E3, NOTE_E4,
mdu7078 1:51cf7b1a96bd 29 NOTE_E5, NOTE_E6, NOTE_E7};
mdu7078 1:51cf7b1a96bd 30 double _ES[] = {NOTE_F0, NOTE_F1, NOTE_F2, NOTE_F3, NOTE_F4,
mdu7078 1:51cf7b1a96bd 31 NOTE_F5, NOTE_F6, NOTE_F7};
mdu7078 1:51cf7b1a96bd 32 double _F[] = {NOTE_F0, NOTE_F1, NOTE_F2, NOTE_F3, NOTE_F4,
mdu7078 1:51cf7b1a96bd 33 NOTE_F5, NOTE_F6, NOTE_F7};
mdu7078 1:51cf7b1a96bd 34 double _FS[] = {NOTE_FS0, NOTE_FS1, NOTE_FS2, NOTE_FS3, NOTE_FS4,
mdu7078 1:51cf7b1a96bd 35 NOTE_FS5, NOTE_FS6, NOTE_FS7};
mdu7078 1:51cf7b1a96bd 36 double _G[] = {NOTE_G0, NOTE_G1, NOTE_G2, NOTE_G3, NOTE_G4,
mdu7078 1:51cf7b1a96bd 37 NOTE_G5, NOTE_G6, NOTE_G7};
mdu7078 1:51cf7b1a96bd 38 double _GS[] = {NOTE_GS0, NOTE_GS1, NOTE_GS2, NOTE_GS3, NOTE_GS4,
mdu7078 1:51cf7b1a96bd 39 NOTE_GS5, NOTE_GS6, NOTE_GS7};
mdu7078 1:51cf7b1a96bd 40
mdu7078 1:51cf7b1a96bd 41 /*
mdu7078 1:51cf7b1a96bd 42 * This is a lookup function to provide the correct
mdu7078 1:51cf7b1a96bd 43 * frequency given a note and an octave
mdu7078 1:51cf7b1a96bd 44 *
mdu7078 1:51cf7b1a96bd 45 * note - The given note character [A - G]
mdu7078 1:51cf7b1a96bd 46 * sharp - Whether the note is sharp (1) or not (0)
mdu7078 1:51cf7b1a96bd 47 * octave - The given octave [0 - 8]
mdu7078 1:51cf7b1a96bd 48 */
mdu7078 1:51cf7b1a96bd 49 double notes::get_freq(char note, int sharp, int octave) {
mdu7078 1:51cf7b1a96bd 50 switch(note){
mdu7078 1:51cf7b1a96bd 51 case 'A':
mdu7078 1:51cf7b1a96bd 52 //A Note
mdu7078 1:51cf7b1a96bd 53 if (octave>=0 && octave <=7){
mdu7078 1:51cf7b1a96bd 54 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 55 return _A[octave];
mdu7078 1:51cf7b1a96bd 56 }
mdu7078 1:51cf7b1a96bd 57 else{
mdu7078 1:51cf7b1a96bd 58 return _AS[octave];
mdu7078 1:51cf7b1a96bd 59 }
mdu7078 1:51cf7b1a96bd 60 }
mdu7078 1:51cf7b1a96bd 61 break;
mdu7078 1:51cf7b1a96bd 62 case 'B':
mdu7078 1:51cf7b1a96bd 63 //B Note
mdu7078 1:51cf7b1a96bd 64 if (octave>=0 && octave <=7){
mdu7078 1:51cf7b1a96bd 65 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 66 return _B[octave];
mdu7078 1:51cf7b1a96bd 67 }
mdu7078 1:51cf7b1a96bd 68 else{
mdu7078 1:51cf7b1a96bd 69 return _BS[octave];
mdu7078 1:51cf7b1a96bd 70 }
mdu7078 1:51cf7b1a96bd 71 }
mdu7078 1:51cf7b1a96bd 72 break;
mdu7078 1:51cf7b1a96bd 73 case 'C':
mdu7078 1:51cf7b1a96bd 74 //C Note
mdu7078 1:51cf7b1a96bd 75 if (octave>=0 && octave <=8){
mdu7078 1:51cf7b1a96bd 76 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 77 return _C[octave];
mdu7078 1:51cf7b1a96bd 78 }
mdu7078 1:51cf7b1a96bd 79 else{
mdu7078 1:51cf7b1a96bd 80 return _CS[octave];
mdu7078 1:51cf7b1a96bd 81 }
mdu7078 1:51cf7b1a96bd 82 }
mdu7078 1:51cf7b1a96bd 83 break;
mdu7078 1:51cf7b1a96bd 84 case 'D':
mdu7078 1:51cf7b1a96bd 85 //D Note
mdu7078 1:51cf7b1a96bd 86 if (octave>=0 && octave <=8){
mdu7078 1:51cf7b1a96bd 87 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 88 return _D[octave];
mdu7078 1:51cf7b1a96bd 89 }
mdu7078 1:51cf7b1a96bd 90 else{
mdu7078 1:51cf7b1a96bd 91 return _DS[octave];
mdu7078 1:51cf7b1a96bd 92 }
mdu7078 1:51cf7b1a96bd 93 }
mdu7078 1:51cf7b1a96bd 94 break;
mdu7078 1:51cf7b1a96bd 95 case 'E':
mdu7078 1:51cf7b1a96bd 96 //E Note
mdu7078 1:51cf7b1a96bd 97 if (octave>=0 && octave <=7){
mdu7078 1:51cf7b1a96bd 98 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 99 return _E[octave];
mdu7078 1:51cf7b1a96bd 100 }
mdu7078 1:51cf7b1a96bd 101 else{
mdu7078 1:51cf7b1a96bd 102 return _ES[octave];
mdu7078 1:51cf7b1a96bd 103 }
mdu7078 1:51cf7b1a96bd 104 }
mdu7078 1:51cf7b1a96bd 105 break;
mdu7078 1:51cf7b1a96bd 106 case 'F':
mdu7078 1:51cf7b1a96bd 107 //F Note
mdu7078 1:51cf7b1a96bd 108 if (octave>=0 && octave <=7){
mdu7078 1:51cf7b1a96bd 109 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 110 return _F[octave];
mdu7078 1:51cf7b1a96bd 111 }
mdu7078 1:51cf7b1a96bd 112 else{
mdu7078 1:51cf7b1a96bd 113 return _FS[octave];
mdu7078 1:51cf7b1a96bd 114 }
mdu7078 1:51cf7b1a96bd 115 }
mdu7078 1:51cf7b1a96bd 116 break;
mdu7078 1:51cf7b1a96bd 117 case 'G':
mdu7078 1:51cf7b1a96bd 118 //G Note
mdu7078 1:51cf7b1a96bd 119 if (octave>=0 && octave <=7){
mdu7078 1:51cf7b1a96bd 120 if (sharp == 0){
mdu7078 1:51cf7b1a96bd 121 return _G[octave];
mdu7078 1:51cf7b1a96bd 122 }
mdu7078 1:51cf7b1a96bd 123 else{
mdu7078 1:51cf7b1a96bd 124 return _GS[octave];
mdu7078 1:51cf7b1a96bd 125 }
mdu7078 1:51cf7b1a96bd 126 }
mdu7078 1:51cf7b1a96bd 127 break;
mdu7078 1:51cf7b1a96bd 128 }
mdu7078 1:51cf7b1a96bd 129 return 0;
mdu7078 1:51cf7b1a96bd 130 }