A class to play notes on a speaker using analog out See https://mbed.org/users/4180_1/notebook/using-a-speaker-for-audio-output/

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
4180_1
Date:
Mon Jan 21 03:37:11 2013 +0000
Commit message:
ver 1.0

Changed in this revision

Speaker.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Speaker.h	Mon Jan 21 03:37:11 2013 +0000
@@ -0,0 +1,52 @@
+class Speaker
+{
+public:
+    Speaker(PinName pin) : _pin(pin) {
+// _pin(pin) means pass pin to the Speaker Constructor
+// precompute 32 sample points on one sine wave cycle
+// used for continuous sine wave output later
+        for(int k=0; k<32; k++) {
+            Analog_out_data[k] = int (65536.0 * ((1.0 + sin((float(k)/32.0*6.28318530717959)))/2.0));
+            // scale the sine wave to 16-bits - as needed for AnalogOut write_u16 arg
+        }
+
+    }
+// class method to play a note based on AnalogOut class
+    void PlayNote(float frequency, float duration, float volume) {
+        // scale samples using current volume level arg
+        for(int k=0; k<32; k++) {
+            Analog_scaled_data[k] = Analog_out_data[k] * volume;
+        }
+        // reset to start of sample array
+        i=0;
+        // turn on timer interrupts to start sine wave output
+        Sample_Period.attach(this, &Speaker::Sample_timer_interrupt, 1.0/(frequency*32.0));
+        // play note for specified time
+        wait(duration);
+        // turns off timer interrupts
+        Sample_Period.detach();
+        // sets output to mid range - analog zero
+        this->_pin.write_u16(32768);
+
+    }
+private:
+// sets up specified pin for analog using AnalogOut class
+    AnalogOut _pin;
+    // set up a timer to be used for sample rate interrupts
+    Ticker Sample_Period;
+
+    //variables used by interrupt routine and PlayNote
+    volatile int i;
+    short unsigned Analog_out_data[32];
+    short unsigned Analog_scaled_data[32];
+
+// Interrupt routine
+// used to output next analog sample whenever a timer interrupt occurs
+    void Sample_timer_interrupt(void) {
+        // send next analog sample out to D to A
+        this->_pin.write_u16(Analog_scaled_data[i]);
+        // increment pointer and wrap around back to 0 at 32
+        i = (i+1) & 0x01F;
+    }
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jan 21 03:37:11 2013 +0000
@@ -0,0 +1,22 @@
+#include "mbed.h"
+// Audio output demo for speaker
+// Speaker Class demo - plays a note on the analog output pin
+// 32 data points on one sine wave cycle are precomputed,
+// scaled, stored in an array and
+// continuously output to the Digital to Analog convertor
+
+// add Speaker class and PlayNote
+// PlayNote args are frequency in hz (<=5000), duration in secs , and volume(0.0..1.0)
+#include  "Speaker.h"
+
+int main()
+{
+// setup instance of new Speaker class, mySpeaker
+// the pin must be the AnalogOut pin - p18
+    Speaker mySpeaker(p18);
+    // loops forever playing two notes on speaker using analog samples
+    while(1) {
+        mySpeaker.PlayNote(969.0, 0.5, 1.0);
+        mySpeaker.PlayNote(800.0, 0.5, 1.0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Jan 21 03:37:11 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/0480438fc29c
\ No newline at end of file