diff --git a/libraries/AnalogWave/examples/DACEqualTemperedScale/DACEqualTemperedScale.ino b/libraries/AnalogWave/examples/DACEqualTemperedScale/DACEqualTemperedScale.ino new file mode 100644 index 000000000..7f3383f91 --- /dev/null +++ b/libraries/AnalogWave/examples/DACEqualTemperedScale/DACEqualTemperedScale.ino @@ -0,0 +1,54 @@ +/* + Plays a tone in response to a potentiometer + formula from https://newt.phys.unsw.edu.au/jw/notes.html + and https://en.wikipedia.org/wiki/MIDI_tuning_standard: + + the MIDI protocol divides the notes of an equal-tempered scale into + 128 possible note values. Middle A is MIDI note value 69. There is + a formula for converting MIDI note numbers (0-127) to pitches. This sketch + reduces that to the notes 21 - 108, which are the 88 keys found on a piano: + + frequency = 440 * ((noteNumber - 69) / 12.0)^2 + + You can see this applied in the code below. + + circuit: + * audio amp (LM386 used for testing) input+ attached to A0 + * audio amp input- attached to ground + * 4-8-ohm speaker attached to amp output+ + * Potentiometer connected to pin A5 + + created 18 Dec 2018 + modified 3 Jul 2023 + by Tom Igoe +*/ + +// include the AnalogWave library: +#include "analogWave.h" +analogWave wave(DAC); + +// middle A is the reference frequency for an +// equal-tempered scale. Set its frequency and note value: +#define NOTE_A4 69 // MIDI note value for middle A +#define FREQ_A4 440 // frequency for middle A + +const int speakerPin = A0; // the pin number for the speaker +void setup() { + Serial.begin(9600); + wave.sine(10); +} +void loop() { + // convert sensor reading to 21 - 108 range + // which is the range of MIDI notes on an 88-key keyboard + // (from A0 to C8): + int sensorReading = analogRead(A5); + int noteValue = map(sensorReading, 0, 1023, 21, 108); + // then convert to frequency: + float frequency = FREQ_A4 * pow(2, ((noteValue - NOTE_A4) / 12.0)); + int freq = int(frequency); + // turn the speaker on: + wave.freq(freq); + Serial.print("note value: "+ String(noteValue) + " freq: "); + Serial.println(freq); + delay(500); +} diff --git a/libraries/AnalogWave/examples/DACJacques/DACJacques.ino b/libraries/AnalogWave/examples/DACJacques/DACJacques.ino new file mode 100644 index 000000000..c533e6dc0 --- /dev/null +++ b/libraries/AnalogWave/examples/DACJacques/DACJacques.ino @@ -0,0 +1,81 @@ + /* + DAC Melody player + + Generates a series of tones from MIDI note values + using the Uno R4 DAC and the AnalogWave Library. + The melody is "Frere Jacques" + +circuit: + * audio amp (LM386 used for testing) input+ attached to A0 + * audio amp input- attached to ground + * 4-8-ohm speaker attached to amp output+ + * Potentiometer connected to pin A5 + + created 13 Feb 2017 + modified 3 Jul 2023 + by Tom Igoe +*/ +#include "analogWave.h" +analogWave wave(DAC); + +#define NOTE_A4 69 // MIDI note value for middle A +#define FREQ_A4 440 // frequency for middle A + +// the tonic, or first note of the key signature for the song: +int tonic = 65; +// the melody sequence. Note values are relative to the tonic: +int melody[] = {1, 3, 5, 1, + 1, 3, 5, 1, + 5, 6, 8, 5, 6, 8, + 8, 10, 8, 6, 5, 1, + 8, 10, 8, 6, 5, 1, + 1, -4, 1, + 1, -4, 1 + }; +// the rhythm sequence. Values are 1/note, e.g. 4 = 1/4 note: +int rhythm[] = {4, 4, 4, 4, + 4, 4, 4, 4, + 4, 4, 2, + 4, 4, 2, + 8, 8, 8, 8, 4, 4, + 8, 8, 8, 8, 4, 4, + 4, 4, 2, + 4, 4, 2 + }; +// which note of the melody to play: +int noteCounter = 0; + +int bpm = 120; // beats per minute +// duration of a beat in ms +float beatDuration = 60.0 / bpm * 1000; + +void setup() { +// start the sine wave generator: + wave.sine(10); +} + +void loop() { + // current note is an element of the array: + int currentNote = melody[noteCounter] + tonic; + // play a note from the melody: + // convert MIDI note number to frequency: + float frequency = FREQ_A4 * pow(2, ((currentNote - NOTE_A4) / 12.0)); + + // all the notes in this are sixteenth notes, + // which is 1/4 of a beat, so: + float noteDuration = beatDuration * (4.0 / rhythm[noteCounter]); + // turn the note on: + wave.freq(frequency); + // tone(speakerPin, frequency, noteDuration * 0.85); + // keep it on for the appropriate duration: + delay(noteDuration * 0.85); + wave.stop(); + delay(noteDuration * 0.15); + // turn the note off: + // noTone(speakerPin); + // increment the note number for next time through the loop: + noteCounter++; + // keep the note in the range from 0 - 32 using modulo: + noteCounter = noteCounter % 32; + +}