# cpb_little_lamb.py

# Play "Mary had a Little Lamb" on the Adafruit Circuit Playground Bluefruit board.
# This program uses only onboard hardware: speaker.

# This example shows the use of Python tuples to create ad hoc data structures,
# in this case to store note value and duration pairs representing a melody.

# Please note that this example only uses simple tones, but the library supports
# audio sample playback from .mp3 and .wav files (use 22kHz mono 16-bit).

# ----------------------------------------------------------------
# Import the standard Python math library and time functions.
import math, time

# Import the board-specific input/output library.
from adafruit_circuitplayground import cp

# ----------------------------------------------------------------
# Define a function to convert MIDI note values to frequency. This applies an
# equal temperament scale.
def midi_to_freq(midi_note):
    MIDI_A0 = 21
    freq_A0 = 27.5
    return freq_A0 * math.pow(2.0, (midi_note - MIDI_A0) / 12.0)

# Define the melody as (note, duration) tuples.  Middle C is MIDI 60.
# The duration unit is the quarter note.

mary = ((64, 1), (62, 1), (60, 1), (62, 1), (64, 1), (64, 1), (64, 2), (62, 1),
        (62, 1), (62, 2), (64, 1), (67, 1), (67, 2), (64, 1), (62, 1), (60, 1), (62, 1),
        (64, 1), (64, 1), (64, 1), (64, 1), (62, 1), (62, 1), (64, 1), (62, 1), (60, 4))

# ----------------------------------------------------------------
# Initialize global variables for the main loop.
tempo = 144   # in beats per minute

# ----------------------------------------------------------------
# Enter the main event loop to play each tone in sequence.
while True:

    # Calculate the quarter note duration.
    quarter = 60.0 / tempo

    # Play each note tuple.
    for note in mary:
        freq      = midi_to_freq(note[0])
        duration  = quarter * note[1]

        # Play a single note.  The function won't return until the duration has elapsed.
        cp.play_tone(freq, 0.9*duration)

        # Articulate each note with a brief inter-note silence.
        time.sleep(0.1 * duration)

    # Pause briefly before repeating.
    time.sleep(2)

    # Speed up a little each time.
    tempo = tempo * 1.2
