Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Copyright 2012 Justas Sadzevicius
- # Licensed under the MIT license: http://www.opensource.org/licenses/MIT
- # Notes library for Finch buzzer
- #("Middle C" is C4 )
- frequencies = {
- 'C0': 16.35,
- 'C#0': 17.32,
- 'Db0': 17.32,
- 'D0': 18.35,
- 'D#0': 19.45,
- 'Eb0': 19.45,
- 'E0': 20.6,
- 'F0': 21.83,
- 'F#0': 23.12,
- 'Gb0': 23.12,
- 'G0': 24.5,
- 'G#0': 25.96,
- 'Ab0': 25.96,
- 'A0': 27.5,
- 'A#0': 29.14,
- 'Bb0': 29.14,
- 'B0': 30.87,
- 'C1': 32.7,
- 'C#1': 34.65,
- 'Db1': 34.65,
- 'D1': 36.71,
- 'D#1': 38.89,
- 'Eb1': 38.89,
- 'E1': 41.2,
- 'F1': 43.65,
- 'F#1': 46.25,
- 'Gb1': 46.25,
- 'G1': 49.0,
- 'G#1': 51.91,
- 'Ab1': 51.91,
- 'A1': 55.0,
- 'A#1': 58.27,
- 'Bb1': 58.27,
- 'B1': 61.74,
- 'C2': 65.41,
- 'C#2': 69.3,
- 'Db2': 69.3,
- 'D2': 73.42,
- 'D#2': 77.78,
- 'Eb2': 77.78,
- 'E2': 82.41,
- 'F2': 87.31,
- 'F#2': 92.5,
- 'Gb2': 92.5,
- 'G2': 98.0,
- 'G#2': 103.83,
- 'Ab2': 103.83,
- 'A2': 110.0,
- 'A#2': 116.54,
- 'Bb2': 116.54,
- 'B2': 123.47,
- 'C3': 130.81,
- 'C#3': 138.59,
- 'Db3': 138.59,
- 'D3': 146.83,
- 'D#3': 155.56,
- 'Eb3': 155.56,
- 'E3': 164.81,
- 'F3': 174.61,
- 'F#3': 185.0,
- 'Gb3': 185.0,
- 'G3': 196.0,
- 'G#3': 207.65,
- 'Ab3': 207.65,
- 'A3': 220.0,
- 'A#3': 233.08,
- 'Bb3': 233.08,
- 'B3': 246.94,
- 'C4': 261.63,
- 'C#4': 277.18,
- 'Db4': 277.18,
- 'D4': 293.66,
- 'D#4': 311.13,
- 'Eb4': 311.13,
- 'E4': 329.63,
- 'F4': 349.23,
- 'F#4': 369.99,
- 'Gb4': 369.99,
- 'G4': 392.0,
- 'G#4': 415.3,
- 'Ab4': 415.3,
- 'A4': 440.0,
- 'A#4': 466.16,
- 'Bb4': 466.16,
- 'B4': 493.88,
- 'C5': 523.25,
- 'C#5': 554.37,
- 'Db5': 554.37,
- 'D5': 587.33,
- 'D#5': 622.25,
- 'Eb5': 622.25,
- 'E5': 659.26,
- 'F5': 698.46,
- 'F#5': 739.99,
- 'Gb5': 739.99,
- 'G5': 783.99,
- 'G#5': 830.61,
- 'Ab5': 830.61,
- 'A5': 880.0,
- 'A#5': 932.33,
- 'Bb5': 932.33,
- 'B5': 987.77,
- 'C6': 1046.5,
- 'C#6': 1108.73,
- 'Db6': 1108.73,
- 'D6': 1174.66,
- 'D#6': 1244.51,
- 'Eb6': 1244.51,
- 'E6': 1318.51,
- 'F6': 1396.91,
- 'F#6': 1479.98,
- 'Gb6': 1479.98,
- 'G6': 1567.98,
- 'G#6': 1661.22,
- 'Ab6': 1661.22,
- 'A6': 1760.0,
- 'A#6': 1864.66,
- 'Bb6': 1864.66,
- 'B6': 1975.53,
- 'C7': 2093.0,
- 'C#7': 2217.46,
- 'Db7': 2217.46,
- 'D7': 2349.32,
- 'D#7': 2489.02,
- 'Eb7': 2489.02,
- 'E7': 2637.02,
- 'F7': 2793.83,
- 'F#7': 2959.96,
- 'Gb7': 2959.96,
- 'G7': 3135.96,
- 'G#7': 3322.44,
- 'Ab7': 3322.44,
- 'A7': 3520.0,
- 'A#7': 3729.31,
- 'Bb7': 3729.31,
- 'B7': 3951.07,
- 'C8': 4186.01,
- 'C#8': 4434.92,
- 'Db8': 4434.92,
- 'D8': 4698.64,
- 'D#8': 4978.03,
- 'Eb8': 4978.03,
- }
- class Command(object):
- octave = 4
- note = ''
- duration = 0
- sym = ''
- def reset(self):
- self.note = ''
- self.duration = 0
- self.sym = ''
- def emit(self):
- if not self.note or not self.duration:
- return None
- if self.note == '-':
- return (0, self.duration)
- ref = self.note.upper()+self.sym+str(self.octave)
- frequency = frequencies.get(ref)
- if not frequency:
- return None
- return (frequency, self.duration)
- def parse(sheet, speed=0.25):
- """Parse a sheet of notes to a sequence of (duration, frequency) commands.
- speed is a duration of a "tick" in seconds.
- Each *symbol* in the sheet takes up one tick.
- Valid notes are C, D, E, F, G, A, B and - (which means silence).
- Sheet can also contain semitones: C#, Eb, etc.
- You can change active octave with numbers 0-8.
- Here are some examples:
- To play Do for four ticks and then Re for eight ticks, pass:
- 'C D '
- To play Do for two ticks, then silence for two ticks, then Do again:
- 'C - C '
- To play Do Re Mi, but octave higher:
- 'C5D E '
- parse('C3E G E ', speed=0.25)
- will play C major chord over 2 seconds
- parse('C3 Eb G Eb ', speed=0.125)
- will play C minor chord over 2 seconds also
- """
- sheet = list(sheet)
- commands = []
- next = Command()
- while sheet:
- #pop off a token
- token = sheet.pop(0)
- #if next note is reached, append the current note onto the commands
- if (token in 'CDEFGAB-' and next.note):
- entry = next.emit()
- if entry:
- commands.append(entry)
- next.reset()
- #set the next note equal to the token
- next.note = token
- #special case for the first note
- if (token in 'CDEFGAB-' and not next.note):
- next.note = token
- #handle octaves
- elif token.isdigit():
- next.octave = int(token)
- next.duration -= speed
- #handle flats and sharps
- elif ((token == '#' or token == 'b') and next.note):
- next.sym = token
- next.duration -= speed
- #rhythm
- next.duration += speed
- #append the last note into the commands
- entry = next.emit()
- if entry:
- commands.append(entry)
- next.reset()
- return commands
- def sing(finch, sheet, speed=0.05):
- """Sing a melody.
- sheet - a string of notes. For the format see parse method in notes.py
- speed - speed of a single tick in seconds.
- Example: sing('C D E F G A B C5', speed=0.1)
- """
- music = parse(sheet, speed=speed)
- for freq, duration in music:
- if duration:
- finch.buzzer_with_delay(duration, int(freq))
Advertisement