Skip to content Skip to sidebar Skip to footer

Entering A Sequence Of Notes And Have Them Played

My son and I are trying to write a program that will allow a user to input a sequence of musical notes, and save them into a list to be played back. We've come up with the followin

Solution 1:

If you are looking for other work for producing music using Python, you might find the following program be a helpful inspiration. It uses the winsound module on Windows to produce beeps of a certain duration and frequency. The program shown below is old and not maintained -- an experiment really but may give you and your son some ideas for further related work.

#! /usr/bin/env python3import msvcrt
import random
import time
import winsound

# CONSTANTS
KEYS = 'zsxcfvgbnjmk,l./\'q2we4r5t6yu8i9op-[=]'
A4 = 440
AUTHOR = '.\',zb'
NEW_SONG = ('vm',
            'zv',
            'cn',
            'vm',
            'xb',
            'cn',
            'zv')

# CONFIGURATION
NS_SP = 1
SPEED = 5
HOLD_RATIO = 0.95
TRANSPOSE = 0
PAUSE_TIME = 2
SHOW_FREQU = False# RANDOM
NEIGHBOR_RATIO = 0.9
ODD_RATIO = 0.05
SWITCH_RATIO = 0.01
WHITE_KEYS = 'zxcvbnm,./qwertyuiop[]'
BLACK_KEYS = 'sfgjkl\'245689-='

EXAMPLE_SONG_1 = [('x', 1),
                  ('x', 2),
                  ('x', 1),
                  ('x', 1),
                  ('f', 1),
                  ('g', 1),
                  ('b', 2),
                  ('b', 1),
                  ('g', 2),
                  ('x', 1),
                  ('k', 2),
                  ('k', 1),
                  ('j', 2),
                  ('g', 1),
                  ('f', 5),
                  ('x', 1),
                  ('k', 2),
                  ('k', 1),
                  ('l', 1),
                  ('.', 1),
                  ("'", 1),
                  ('j', 2),
                  ('j', 1),
                  ('g', 2),
                  ('g', 1),
                  ('b', 2),
                  ('g', 1),
                  ('f', 1),
                  ('x', 1),
                  ('f', 1),
                  ('x', 5)]

EXAMPLE_SONG_2 = [('j', 2),
                  ('j', 1),
                  ('j', 2),
                  ('.', 1),
                  ('b', 2),
                  ('j', 1),
                  ('b', 1),
                  ('g', 1.5),
                  ('f', 0.5),
                  ('g', 2),
                  ('g', 1),
                  ('g', 1),
                  ('f', 1),
                  ('x', 1),
                  ('f', 6),
                  ('j', 2),
                  ('j', 1),
                  ('j', 2),
                  ('.', 1),
                  ('b', 2),
                  ('j', 1),
                  ('b', 1),
                  ('g', 1.5),
                  ('f', 0.5),
                  ('g', 2),
                  ('g', 1),
                  ('f', 1),
                  ('x', 1),
                  ('f', 1),
                  ('x', 5),
                  ('x', 1),
                  ('k', 2),
                  ('k', 1),
                  ('l', 3),
                  ('l', 2),
                  ("'", 1),
                  ('.', 2),
                  ('.', 1),
                  ('.', 2),
                  ('.', 1),
                  ('2', 1),
                  ("'", 1),
                  ('.', 1),
                  ('j', 6),
                  ('j', 2),
                  ('j', 1),
                  ('j', 2),
                  ('.', 1),
                  ('b', 2),
                  ('j', 1),
                  ('b', 1),
                  ('g', 1.5),
                  ('f', 0.5),
                  ('g', 2),
                  ('g', 1),
                  ('f', 1),
                  ('x', 1),
                  ('f', 1),
                  ('x', 6)]

EXAMPLE_SONG_3 = [(' ', 1),
                  ('x', 0.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('j', 1),
                  ('.', 3),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('j', 3),
                  (' ', 1),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('b', 0.5),
                  ('k', 0.5),
                  ('j', 1),
                  ('x', 3),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 3),
                  (' ', 1),
                  ('x', 0.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('j', 1),
                  ('.', 3),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('j', 3),
                  (' ', 1),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('b', 0.5),
                  ('k', 0.5),
                  ('j', 1),
                  ('x', 2.5),
                  ('x', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('x', 3),
                  ('z', 0.5),
                  ('x', 0.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('j', 0.5),
                  ('k', 1),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('.', 1),
                  ('k', 2),
                  (' ', 1),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('k', 0.5),
                  ('l', 3),
                  (' ', 1),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('b', 0.5),
                  ('j', 0.5),
                  ('k', 1),
                  ('b', 2),
                  (' ', 1),
                  ('j', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('j', 3),
                  (' ', 1),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('.', 1),
                  ('k', 2),
                  ("'", 0.5),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('.', 0.5),
                  ('j', 3),
                  (' ', 1),
                  ("'", 0.5),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('.', 0.5),
                  ('j', 3),
                  (' ', 1),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('b', 0.5),
                  ('k', 0.5),
                  ('j', 1),
                  ('x', 2),
                  (' ', 1),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('x', 3)]

EXAMPLE_SONG_4 = [('j', 1.5),
                  ('j', 0.5),
                  ('j', 0.75),
                  ('b', 0.25),
                  ('g', 0.75),
                  ('b', 0.25),
                  ('j', 1),
                  ('k', 1),
                  ('j', 2),
                  ('l', 1.5),
                  ('l', 0.5),
                  ('l', 0.75),
                  ('k', 0.25),
                  ('j', 0.75),
                  ('b', 0.25),
                  ('g', 1),
                  ('k', 1),
                  ('j', 2),
                  ('j', 1.5),
                  ('j', 0.5),
                  ('j', 0.75),
                  ('b', 0.25),
                  ('g', 0.75),
                  ('b', 0.25),
                  ('j', 1),
                  ('k', 1),
                  ('j', 1),
                  ('.', 1),
                  ("'", 2),
                  ('l', 2),
                  ('.', 4),
                  ('.', 1.5),
                  ('l', 0.5),
                  ('.', 0.75),
                  ('l', 0.25),
                  ('.', 0.75),
                  ('k', 0.25),
                  ('k', 1),
                  ('j', 1),
                  ('j', 2),
                  ('l', 1.5),
                  ('k', 0.5),
                  ('l', 0.75),
                  ('k', 0.25),
                  ('l', 0.75),
                  ('k', 0.25),
                  ('j', 1),
                  ('.', 1),
                  ('.', 2),
                  ('.', 1.5),
                  ('l', 0.5),
                  ('.', 0.75),
                  ('l', 0.25),
                  ('.', 0.75),
                  ('k', 0.25),
                  ('k', 1),
                  ('j', 1),
                  ('j', 1),
                  ('.', 1),
                  ("'", 2),
                  ('l', 2),
                  ('.', 4)]

EXAMPLE_SONG_5 = [('g', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('b', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 0.5),
                  ('f', 0.5),
                  ('j', 0.5),
                  ('f', 0.5),
                  ('g', 2),
                  ('b', 0.5),
                  ('b', 0.5),
                  ('j', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('x', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 4),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('g', 0.5),
                  ('k', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('g', 1),
                  ('g', 1),
                  ('b', 0.5),
                  ('b', 0.5),
                  ('j', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('x', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 5),
                  ('j', 1),
                  ('k', 1),
                  ('l', 1),
                  ('l', 0.5),
                  ('.', 0.5),
                  ('.', 0.5),
                  ('j', 0.5),
                  ('j', 1.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('x', 0.5),
                  ('f', 0.5),
                  ('g', 1.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('b', 0.5),
                  ('j', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('.', 0.5),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('k', 0.5),
                  ('k', 0.5),
                  ('l', 0.5),
                  ('.', 0.5),
                  ("'", 1.5),
                  ("'", 0.5),
                  ('2', 0.5),
                  ('2', 0.5),
                  ('2', 0.5),
                  ("'", 0.5),
                  ("'", 0.5),
                  ('.', 0.5),
                  ('l', 0.5),
                  ('.', 0.5),
                  ('k', 0.5),
                  ('k', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('b', 1.5),
                  ('f', 0.5),
                  ('g', 0.5),
                  ('j', 0.5),
                  ('j', 0.5),
                  ('g', 0.5),
                  ('b', 0.5),
                  ('k', 0.5),
                  ('k', 0.5),
                  ('j', 0.5),
                  ('k', 2),
                  ('l', 2),
                  ('.', 4)]

EXAMPLE_SONG_6 = [('j', 2),
                  ('k', 1),
                  ('j', 2),
                  ('j', 1),
                  ('b', 2),
                  ('g', 1),
                  ('b', 0.5),
                  ('g', 0.5),
                  ('f', 2),
                  ('g', 2),
                  ('j', 1),
                  ('.', 2),
                  ('j', 1),
                  ('b', 2),
                  ('f', 1),
                  ('j', 3),
                  ('j', 2),
                  ('k', 1),
                  ('j', 2),
                  ('j', 1),
                  ('k', 2),
                  ('l', 1),
                  ('.', 1),
                  ('k', 2),
                  ('j', 2),
                  ('g', 1),
                  ('x', 2),
                  ('g', 1),
                  ('f', 2),
                  ('x', 1),
                  ('x', 3),
                  ('.', 2),
                  ("'", 1),
                  ('.', 2),
                  ('l', 1),
                  ('.', 2),
                  ("'", 1),
                  ('.', 1),
                  ('k', 2),
                  ('j', 2),
                  ('.', 1),
                  ('2', 2),
                  ('.', 1),
                  ("'", 2),
                  ('k', 1),
                  ('j', 3),
                  ('j', 1),
                  ('k', 1),
                  ('l', 1),
                  ('.', 2),
                  ('l', 1),
                  ('k', 2),
                  ('j', 1),
                  ('j', 1),
                  ('g', 2),
                  ('g', 2),
                  ('j', 1),
                  ('x', 2),
                  ('g', 1),
                  ('f', 2),
                  ('x', 1),
                  ('x', 3)]

# These next few songs were contributed by Mike Sperry.
TWINKLE_TWINKLE = [('c', 1),
                   ('c', 1),
                   ('m', 1),
                   ('m', 1),
                   (',', 1),
                   (',', 1),
                   ('m', 2),
                   ('n', 1),
                   ('n', 1),
                   ('b', 1),
                   ('b', 1),
                   ('v', 1),
                   ('v', 1),
                   ('c', 2),
                   ('m', 1),
                   ('m', 1),
                   ('n', 1),
                   ('n', 1),
                   ('b', 1),
                   ('b', 1),
                   ('v', 2),
                   ('m', 1),
                   ('m', 1),
                   ('n', 1),
                   ('n', 1),
                   ('b', 1),
                   ('b', 1),
                   ('v', 2),
                   ('c', 1),
                   ('c', 1),
                   ('m', 1),
                   ('m', 1),
                   (',', 1),
                   (',', 1),
                   ('m', 2),
                   ('n', 1),
                   ('n', 1),
                   ('b', 1),
                   ('b', 1),
                   ('v', 1),
                   ('v', 1),
                   ('c', 2)]

ABCS = [('c', 1),
        ('c', 1),
        ('m', 1),
        ('m', 1),
        (',', 1),
        (',', 1),
        ('m', 2),
        ('n', 1),
        ('n', 1),
        ('b', 1),
        ('b', 1),
        ('v', 0.5),
        ('v', 0.5),
        ('v', 0.5),
        ('v', 0.5),
        ('c', 2),
        ('m', 1),
        ('m', 1),
        ('n', 2),
        ('b', 1),
        ('b', 1),
        ('v', 2),
        ('m', 1),
        ('m', 1),
        ('n', 2),
        ('b', 1),
        ('b', 1),
        ('v', 2),
        ('c', 1),
        ('c', 1),
        ('m', 1),
        ('m', 1),
        (',', 1),
        (',', 1),
        ('m', 2),
        ('n', 1),
        ('n', 1),
        ('b', 1),
        ('b', 1),
        ('v', 1),
        ('v', 1),
        ('c', 2)]

BAH_BAH_BLACK_SHEEP = [('c', 1),
                       ('c', 1),
                       ('m', 1),
                       ('m', 1),
                       (',', 0.5),
                       (',', 0.5),
                       (',', 0.5),
                       (',', 0.5),
                       ('m', 2),
                       ('n', 1),
                       ('n', 1),
                       ('b', 1),
                       ('b', 1),
                       ('v', 1),
                       ('v', 1),
                       ('c', 2),
                       ('m', 1),
                       ('m', 0.5),
                       ('m', 0.5),
                       ('n', 1),
                       ('n', 1),
                       ('b', 1),
                       ('b', 0.5),
                       ('b', 0.5),
                       ('v', 2),
                       ('m', 1),
                       ('m', 0.5),
                       ('m', 0.5),
                       ('n', 0.5),
                       ('n', 0.5),
                       ('n', 0.5),
                       ('n', 0.5),
                       ('b', 1),
                       ('b', 0.5),
                       ('b', 0.5),
                       ('v', 2),
                       ('c', 1),
                       ('c', 1),
                       ('m', 1),
                       ('m', 1),
                       (',', 0.5),
                       (',', 0.5),
                       (',', 0.5),
                       (',', 0.5),
                       ('m', 2),
                       ('n', 1),
                       ('n', 1),
                       ('b', 1),
                       ('b', 1),
                       ('v', 1),
                       ('v', 1),
                       ('c', 2)]

HAPPY_BIRTHDAY = [('m', 0.75),
                  ('m', 0.25),
                  (',', 1),
                  ('m', 1),
                  ('/', 1),
                  ('.', 2),
                  ('m', 0.75),
                  ('m', 0.25),
                  (',', 1),
                  ('m', 1),
                  ('q', 1),
                  ('/', 2),
                  ('m', 0.75),
                  ('m', 0.5),
                  ('r', 1),
                  ('w', 1),
                  ('/', 1),
                  ('.', 1),
                  (',', 1),
                  ('n', 0.75),
                  ('n', 0.25),
                  ('b', 1),
                  ('c', 1),
                  ('v', 1),
                  ('c', 3)]

# KNOWN MUSIC
SONGS = EXAMPLE_SONG_1, \
        EXAMPLE_SONG_2, \
        EXAMPLE_SONG_3, \
        EXAMPLE_SONG_4, \
        EXAMPLE_SONG_5, \
        EXAMPLE_SONG_6, \
        TWINKLE_TWINKLE, \
        ABCS, \
        BAH_BAH_BLACK_SHEEP, \
        HAPPY_BIRTHDAY

defmain():
    print('''
MENU
====
(R)andom
(S)huffle
(P)lay
(K)eyboard
(A)uthor
(N)ew Song''')
    whileTrue:
        key = msvcrt.getwch()
        if key in'rspk': print()
        if key == 'r': menu_help(random.random)
        if key == 's': menu_help(random.shuffle)
        if key == 'p': select_song()
        if key == 'k': menu_help()
        if key == 'a': author()
        if key == 'n': new_song()

defnew_song():
    whileTrue:
        sig = 0for notes in NEW_SONG:
            sig *= 2for note in random.sample(notes, 2):
                try:
                    winsound.Beep(get_frequency(note), int(100 / float(NS_SP)))
                except:
                    passif notes[1] == note:
                sig += 1
            time.sleep((1.0 / 30) / NS_SP)
        ifnot SHOW_FREQU:
            print(sig + 1)

defselect_song():
    songs = (('EXAMPLE_SONG_1', EXAMPLE_SONG_1),
             ('EXAMPLE_SONG_2', EXAMPLE_SONG_2),
             ('EXAMPLE_SONG_3', EXAMPLE_SONG_3),
             ('EXAMPLE_SONG_4', EXAMPLE_SONG_4),
             ('EXAMPLE_SONG_5', EXAMPLE_SONG_5),
             ('EXAMPLE_SONG_6', EXAMPLE_SONG_6),
             ('TWINKLE_TWINKLE', TWINKLE_TWINKLE),
             ('ABCS', ABCS),
             ('BAH_BAH_BLACK_SHEEP', BAH_BAH_BLACK_SHEEP),
             ('HAPPY_BIRTHDAY', HAPPY_BIRTHDAY))
    for index, data inenumerate(songs):
        print('(%s) %s' % (index + 1, data[0].replace('_', ' ').lower().title()))
    whileTrue:
        try:
            index = int(input('\nSelect: '))
            assert0 < index <= len(songs)
            play(songs[index - 1][1])
        except:
            passdefmenu_help(score=None):
    ifisinstance(score, list):
        play(score)
    elif score is random.random:
        play_random()
    elif score is random.shuffle:
        play_songs()
    keyboard()

defplay(score):
    for key, duration in score:
        duration /= float(SPEED)
        bd = int(duration * HOLD_RATIO * 1000)
        sd = duration * (1 - HOLD_RATIO)
        try:
            winsound.Beep(get_frequency(key), bd)
        except:
            time.sleep(duration * HOLD_RATIO)
        time.sleep(sd)

defkeyboard():
    while msvcrt.kbhit():
        msvcrt.getwch()
    whileTrue:
        try:
            winsound.Beep(get_frequency(msvcrt.getwch()), 1000)
        except:
            passdefget_frequency(key):
    assert key[0] in KEYS
    if SHOW_FREQU:
        frequ = int((A4 * 2 ** ((KEYS.find(key[0]) + key.count('+') - (0if key[0] == '-'else key.count('-')) + TRANSPOSE) / 12.0)) + 0.5)
        print(frequ)
        return frequ
    else:
        print(key, end=' ')
        returnint((A4 * 2 ** ((KEYS.find(key[0]) + key.count('+') - (0if key[0] == '-'else key.count('-')) + TRANSPOSE) / 12.0)) + 0.5)

defplay_random():
    key = 'c'
    RANDOM_KEYS = WHITE_KEYS
    whilenot msvcrt.kbhit():
        if random.random() < SWITCH_RATIO:
            if RANDOM_KEYS is WHITE_KEYS:
                RANDOM_KEYS = BLACK_KEYS
            else:
                RANDOM_KEYS = WHITE_KEYS
            key = RANDOM_KEYS[random.randrange(len(RANDOM_KEYS))]
        if random.random() < NEIGHBOR_RATIO:
            index = RANDOM_KEYS.index(key[0]) + key.count('+') - key.count('-') + random.randrange(2) * 2 - 1if index < 0:
                key = RANDOM_KEYS[0] + '-' * (index * -1)
            elif index >= len(RANDOM_KEYS):
                key = RANDOM_KEYS[-1] + '+' * (index - len(RANDOM_KEYS) + 1)
            else:
                key = RANDOM_KEYS[index]
        else:
            key = RANDOM_KEYS[random.randrange(len(RANDOM_KEYS))]
        if random.random() < ODD_RATIO:
            if random.randrange(2):
                key += '+'else:
                key += '-'
        neg = key.count('-')
        pos = key.count('+')
        trans = pos - neg
        if trans > 0:
            key = key[0] + '+' * trans
        elif trans < 0:
            key = key[0] + '-' * (trans * -1)
        else:
            key = key[0]
        winsound.Beep(get_frequency(key), 100)

defplay_songs():
    songs = list(SONGS)
    whileTrue:
        random.shuffle(songs)
        for song in songs:
            play(song)
            time.sleep(PAUSE_TIME)

defauthor():
    for note in AUTHOR:
        winsound.Beep(get_frequency(note), 1000)
    time.sleep(1)
    while msvcrt.kbhit():
        msvcrt.getwch()
    author = random.sample(AUTHOR, len(AUTHOR))
    whilenot msvcrt.kbhit():
        for note in author:
            winsound.Beep(get_frequency(note), 100)
        last_note = author[-1]
        author = random.sample(AUTHOR, len(AUTHOR))
        while author[0] == last_note:
            author = random.sample(AUTHOR, len(AUTHOR))

if __name__ == '__main__':
    main()

Solution 2:

As an alternative, you and your son may be more interested in how sound waves are actually crafted and then written to a file. While my other answer focused on music, the code shown below is just about the generation of sound. It supports sine, square, triangle, and saw-tooth sound waves and includes the ability to adjust frequency, amplitude, mixing, and interpolation of sounds. Tests are included to generate wave files that can be played back using another program.

#! /usr/bin/env python3import math
import wave

################################################################################classWaves:

    BUFF = 1 << 20
    MAX = 127
    MID = 128def__init__(self, fps):
        self.__fps = fps
        self.__data = []

    @staticmethoddef__sin(ratio):
        return math.sin(ratio * math.pi * 2)

    @staticmethoddef__squ(ratio):
        return1 - ratio // 0.5 * 2    @staticmethoddef__tri(ratio):
        if ratio < 0.25:
            return ratio / 0.25elif ratio < 0.75:
            return1 - 4 * (ratio - 0.25)
        else:
            return (ratio - 0.75) * 4 - 1    @staticmethoddef__saw(ratio):
        return ratio / 0.5 - ratio // 0.5 * 2defadd_sine(self, freq, amp):
        self.__add(freq, amp, self.__sin)

    defadd_square(self, freq, amp):
        self.__add(freq, amp, self.__squ)

    defadd_triangle(self, freq, amp):
        self.__add(freq, amp, self.__tri)

    defadd_sawtooth(self, freq, amp):
        self.__add(freq, amp, self.__saw)

    def__add(self, freq, amp, func):
        rate = int(self.__fps / freq)
        self.__data.extend(func(pos / rate) * amp for pos inrange(rate))

    definterpolate_sine(self, freq_a, freq_b, amp_a, amp_b, seconds):
        self.__lerp(freq_a, freq_b, amp_a, amp_b, seconds, self.add_sine)

    definterpolate_square(self, freq_a, freq_b, amp_a, amp_b, seconds):
        self.__lerp(freq_a, freq_b, amp_a, amp_b, seconds, self.add_square)

    definterpolate_triangle(self, freq_a, freq_b, amp_a, amp_b, seconds):
        self.__lerp(freq_a, freq_b, amp_a, amp_b, seconds, self.add_triangle)

    definterpolate_sawtooth(self, freq_a, freq_b, amp_a, amp_b, seconds):
        self.__lerp(freq_a, freq_b, amp_a, amp_b, seconds, self.add_sawtooth)

    def__lerp(self, freq_a, freq_b, amp_a, amp_b, seconds, func):
        samples = int(seconds * (freq_a + freq_b) / 2)
        for position inrange(samples):
            b = position / samples
            a = 1 - b
            func(freq_a * a + freq_b * b, amp_a * a + amp_b * b)

    defwrite(self, name):
        file = wave.open(name, 'wb')
        file.setnchannels(1)
        file.setsampwidth(1)
        file.setframerate(self.__fps)
        self.__writeframes(file)
        file.close()

    def__writeframes(self, file):
        parts = len(self.__data) // self.BUFF
        parts += bool(len(self.__data) % self.BUFF)
        for part inrange(parts):
            index = part * self.BUFF
            buff = self.__data[index:index+self.BUFF]
            byte = self.__transform(buff)
            file.writeframes(byte)

    @classmethoddef__transform(cls, buff):
        returnbytes(int(pos * cls.MAX) + cls.MID for pos in buff)

    @classmethoddefadd(cls, *waves):
        sounds = len(waves)
        assert sounds > 1, 'Must have two or more waves to add!'
        fps = waves[0].__fps
        for wave_instance in waves[1:]:
            assert wave_instance.__fps == fps, 'Framerate is not the same!'
        result = cls(fps)
        package = map(lambda wave_instance: wave_instance.__data, waves)
        result.__data = [sum(sound) / sounds for sound inzip(*package)]
        return result

    def__add__(self, other):
        return Waves.add(self, other)

    def__mul__(self, other):
        result = Waves(self.__fps)
        result.__data = [value * other for value in self.__data]
        return result

    def__imul__(self, other):
        self.__data = [value * other for value in self.__data]
        return self

    defappend(self, other):
        assert self.__fps == other.__fps, 'Framerate is not the same!'
        self.__data.extend(other.__data)

    defaverage_amp(self):
        total = count = 0for value in self.__data:
            total += abs(value)
            count += 1return total / count

    defadjust_amp(self, value):
        self *= value / self.average_amp()

################################################################################deftest_1():
    test = Waves(96000)
    # Standard Test
    test.interpolate_sine(440, 440, 0.1, 0.1, 1)
    test.interpolate_square(440, 440, 0.1, 0.1, 1)
    test.interpolate_triangle(440, 440, 0.1, 0.1, 1)
    # Frequency Test
    test.interpolate_sine(440, 880, 0.1, 0.1, 1)
    test.interpolate_square(440, 880, 0.1, 0.1, 1)
    test.interpolate_triangle(440, 880, 0.1, 0.1, 1)
    # Amplitude Test
    test.interpolate_sine(440, 440, 0.1, 0.5, 1)
    test.interpolate_square(440, 440, 0.1, 0.5, 1)
    test.interpolate_triangle(440, 440, 0.1, 0.5, 1)
    # Frequency & Amplitude Test
    test.interpolate_sine(440, 880, 0.1, 0.5, 1)
    test.interpolate_square(440, 880, 0.1, 0.5, 1)
    test.interpolate_triangle(440, 880, 0.1, 0.5, 1)
    # Finish Test
    test.write('test_1.wav')

deftest_2():
    # Addition, Multiplication, & Append Test
    test = Waves(96000)
    # Sine -> Square
    a = Waves(96000)
    a.interpolate_sine(440, 440, 0.5, 0.0, 5)
    a = a * (0.2 / a.average_amp())
    b = Waves(96000)
    b.interpolate_square(440, 440, 0.0, 0.5, 5)
    b = b * (0.2 / b.average_amp())
    c = a + b
    test.append(c)
    # Square -> Triangle
    a = Waves(96000)
    a.interpolate_square(440, 440, 0.5, 0.0, 5)
    a = a * (0.2 / a.average_amp())
    b = Waves(96000)
    b.interpolate_triangle(440, 440, 0.0, 0.5, 5)
    b = b * (0.2 / b.average_amp())
    c = a + b
    test.append(c)
    # Triangle -> Sawtooth
    a = Waves(96000)
    a.interpolate_triangle(440, 440, 0.5, 0.0, 5)
    a = a * (0.2 / a.average_amp())
    b = Waves(96000)
    b.interpolate_sawtooth(440, 440, 0.0, 0.5, 5)
    b = b * (0.2 / b.average_amp())
    c = a + b
    test.append(c)
    # Sawtooth -> Sine
    a = Waves(96000)
    a.interpolate_sawtooth(440, 440, 0.5, 0.0, 5)
    a = a * (0.2 / a.average_amp())
    b = Waves(96000)
    b.interpolate_sine(440, 440, 0.0, 0.5, 5)
    b = b * (0.2 / b.average_amp())
    c = a + b
    test.append(c)
    # Finish Test
    test.write('test_2.wav')

deftest_3():
    # Test Sample Mixing
    sound = Waves(96000)
    sample_1 = Waves(96000)
    sample_1.interpolate_sine(220, 440, 0.5, 0.5, 10)
    sample_2 = Waves(96000)
    sample_2.interpolate_sine(330, 660, 0.2, 0.2, 10)
    sample_3 = Waves(96000)
    sample_3.interpolate_sine(440, 880, 0.2, 0.2, 10)
    sound.append(sample_1)
    sound.append(sample_1 + sample_2)
    sound.append(sample_1 + sample_2 + sample_3)
    sound.write('test_3.wav')

deftest_4():
    # Test Sound of Waveforms
    sound = Waves(96000)
    # Sine
    sample = Waves(96000)
    sample.interpolate_sine(440, 440, 0.1, 0.1, 2)
    sample.adjust_amp(0.2)
    sound.append(sample)
    # Square
    sample = Waves(96000)
    sample.interpolate_square(440, 440, 0.1, 0.1, 2)
    sample.adjust_amp(0.2)
    sound.append(sample)
    # Triangle
    sample = Waves(96000)
    sample.interpolate_triangle(440, 440, 0.1, 0.1, 2)
    sample.adjust_amp(0.2)
    sound.append(sample)
    # Sawtooth
    sample = Waves(96000)
    sample.interpolate_sawtooth(440, 440, 0.1, 0.1, 2)
    sample.adjust_amp(0.2)
    sound.append(sample)
    # Finish Test
    sound.write('test_4.wav')

################################################################################if __name__ == '__main__':
    test_1()
    test_2()
    test_3()
    test_4()

If you combine concepts from both answers, you could create a program that takes music you have created or encoded and generate music files other people can play on their devices.

Post a Comment for "Entering A Sequence Of Notes And Have Them Played"