Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 输入一系列音符并播放_Python_Python 3.x_Pyaudio - Fatal编程技术网

Python 输入一系列音符并播放

Python 输入一系列音符并播放,python,python-3.x,pyaudio,Python,Python 3.x,Pyaudio,我儿子和我正试图编写一个程序,允许用户输入一系列的音符,并将它们保存到一个列表中以便回放。我们得出以下结论: import math #import needed modules import pyaudio #sudo apt-get install python-pyaudio def playnote(char): octave = int(char[1]) if char[0] == 'c': frequency = 16.35*o

我儿子和我正试图编写一个程序,允许用户输入一系列的音符,并将它们保存到一个列表中以便回放。我们得出以下结论:

import math        #import needed modules
import pyaudio     #sudo apt-get install python-pyaudio

def playnote(char):
    octave = int(char[1])
    if char[0] == 'c':
        frequency = 16.35*octave+1
    elif char[0] =='C':
        frequency = 17.32*octave+1
    elif char[0] =='d':
        frequency = 18.35*octave+1
    elif char[0] == 'D':
        frequency = 19.45*octave+1
    elif char[0] =='e':
        frequency = 20.6*octave+1
    elif char[0] == 'f':
        frequency = 21.83*octave+1
    elif char[0] =='F':
        frequency = 23.12*octave+1
    elif char[0] == 'g':
        frequency = 24.5*octave+1
    elif char[0] == 'G':
        frequency = 25.96*octave+1
    elif char[0] == 'a':
        frequency = 27.5*octave+1
    elif char[0] == 'A':
        frequency = 29.14*octave+1
    elif char[0] == 'b':
        frequency = 30.87*octave+1
    elif char[0] == 'p':
        del song[-1]

    PyAudio = pyaudio.PyAudio     #initialize pyaudio

    #See https://en.wikipedia.org/wiki/Bit_rate#Audio
    bitrate = 256000     #number of frames per second/frameset.      

#    frequency = 220     #Hz, waves per second, 261.63=C4-note.
    LENGTH = 1     #seconds to play sound

    if frequency > bitrate:
        bitrate = frequency+100

    frames = int(bitrate * LENGTH)
#    RESTFRAMES = frames % bitrate
    wavedata = ''    

    #generating waves
    for x in range(frames):
     wavedata = wavedata+chr(int(math.sin(x/((bitrate/frequency)/math.pi))*127+128))    

#    for x in range(RESTFRAMES): 
#     wavedata = wavedata+chr(128)

    p = PyAudio()
    stream = p.open(format = p.get_format_from_width(1), 
                    channels = 1, 
                    rate = bitrate, 
                    output = True)

    stream.write(wavedata)
    stream.stop_stream()
    stream.close()
    p.terminate()

song = []
while True:
    try:
        note = str(input('''Enter note (A-G) (capital for sharp)
        and an octave (0-8) or any other key to play: '''))
        playnote(note)
        song.append(note)


    except:
        for note in song:
            playnote(note)
        break
它可以作为一个起点,但音符听起来不太“音乐化”

从这里,我们想知道:

  • 现有的Python脚本或模块是否有类似的功能

  • 有没有办法修改波形以模拟不同的仪器


  • 几乎可以肯定的是,有很多合成器或程序可以做这样的事情。然而,你自己做这件事有很多乐趣和价值,老实说,我不能给你指出任何具体的东西。对于您的任务,您可以通过添加额外的谐波来创建方波和正弦波,根据模式添加额外的谐波(正如我在下面的一些案例中所做的),或者更改起始、相位、振幅或任何其他方面来修改波形

    import math  # import needed modules
    import pyaudio  # sudo apt-get install python-pyaudio
    
    
    scale_notes = {
        # pitch standard A440 ie a4 = 440Hz
        'c': 16.35,
        'C': 17.32,
        'd': 18.35,
        'D': 19.45,
        'e': 20.6,
        'f': 21.83,
        'F': 23.12,
        'g': 24.5,
        'G': 25.96,
        'a': 27.5,
        'A': 29.14,
        'b': 30.87
    }
    
    
    def playnote(note, note_style):
    
        octave = int(note[1])
        frequency = scale_notes[note[0]] * (2**(octave + 1))
    
        p = pyaudio.PyAudio()  # initialize pyaudio
    
        # sampling rate
        sample_rate = 22050
    
        LENGTH = 1  # seconds to play sound
    
        frames = int(sample_rate * LENGTH)
    
        wavedata = ''
    
        # generating waves
        stream = p.open(
            format=p.get_format_from_width(1),
            channels=1,
            rate=sample_rate,
            output=True)
        for x in range(frames):
            wave = math.sin(x / ((sample_rate / frequency) / math.pi)) * 127 + 128
    
            if note_style == 'bytwos':
                for i in range(3):
                    wave += math.sin((2 + 2**i) * x /
                                     ((sample_rate / frequency) / math.pi)) * 127 + 128
                wavedata = (chr(int(wave / 4)
                                ))
    
            elif note_style == 'even':
                for i in range(3):
                    wave += math.sin((2 * (i + 1)) * x /
                                     ((sample_rate / frequency) / math.pi)) * 127 + 128
                wavedata = (chr(int(wave / 4)
                                ))
    
            elif note_style == 'odd':
                for i in range(3):
                    wave += math.sin(((2 * i) + 1) * x /
                                     ((sample_rate / frequency) / math.pi)) * 127 + 128
                wavedata = (chr(int(wave / 4)
                                ))
    
            elif note_style == 'trem':
                wave = wave * (1 + 0.5 * math.sin((1 / 10)
                                                  * x * math.pi / 180)) / 2
                wavedata = (chr(int(wave)))
    
            else:
                wavedata = (chr(int(wave))
                            )
    
            stream.write(wavedata)
    
        stream.stop_stream()
        stream.close()
        p.terminate()
    
    
    song = []
    while True:
        song_composing = True
        note = ''
        while note != 'p':
            note = str(input(
                '''Enter note (a-G) (capital for sharp) and an octave (0-8) or any other key to play: '''))
            if note[0] in scale_notes:
                note_style = str(
                    input('''Enter style (bytwos, even, odd, trem): '''))
                song.append((note, note_style))
                playnote(note, note_style)
    
        for notes in song:
            playnote(notes[0], notes[1])
        break
    
    一旦你尝试了不同的声音,你就可以开始研究这些声音是如何结合在一起产生真正的乐器声音的。例如,吉他或钢琴的衰变不同,但不像木管乐器那样不同。鼓通常没有太多的和声结构的目的,小提琴是为了突出非常愉快的和声泛音。网上有一个很好的音乐交流问题


    我建议使用缓冲区而不是一次性方法来计算下一个值。在下一个音频样本到期之前,您要完成的过程的能力将阻碍您生成良好的声音(并应用更复杂的算法)。我认为这超出了这个特定问题的范围,但是在这个应用程序中使用pyaudio的回调方法也可能是很好的:

    如果您正在寻找使用Python制作音乐的其他工作,您可能会发现下面的程序是一个很有帮助的灵感。它使用Windows上的
    winsound
    模块来产生特定持续时间和频率的蜂鸣音。下面显示的程序很旧,没有维护——这是一个真正的实验,但可能会给你和你儿子一些进一步相关工作的想法

    #! /usr/bin/env python3
    import 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
    
    def main():
        print('''
    MENU
    ====
    (R)andom
    (S)huffle
    (P)lay
    (K)eyboard
    (A)uthor
    (N)ew Song''')
        while True:
            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()
    
    def new_song():
        while True:
            sig = 0
            for notes in NEW_SONG:
                sig *= 2
                for note in random.sample(notes, 2):
                    try:
                        winsound.Beep(get_frequency(note), int(100 / float(NS_SP)))
                    except:
                        pass
                if notes[1] == note:
                    sig += 1
                time.sleep((1.0 / 30) / NS_SP)
            if not SHOW_FREQU:
                print(sig + 1)
    
    def select_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 in enumerate(songs):
            print('(%s) %s' % (index + 1, data[0].replace('_', ' ').lower().title()))
        while True:
            try:
                index = int(input('\nSelect: '))
                assert 0 < index <= len(songs)
                play(songs[index - 1][1])
            except:
                pass
    
    def menu_help(score=None):
        if isinstance(score, list):
            play(score)
        elif score is random.random:
            play_random()
        elif score is random.shuffle:
            play_songs()
        keyboard()
    
    def play(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)
    
    def keyboard():
        while msvcrt.kbhit():
            msvcrt.getwch()
        while True:
            try:
                winsound.Beep(get_frequency(msvcrt.getwch()), 1000)
            except:
                pass
    
    def get_frequency(key):
        assert key[0] in KEYS
        if SHOW_FREQU:
            frequ = int((A4 * 2 ** ((KEYS.find(key[0]) + key.count('+') - (0 if key[0] == '-' else key.count('-')) + TRANSPOSE) / 12.0)) + 0.5)
            print(frequ)
            return frequ
        else:
            print(key, end=' ')
            return int((A4 * 2 ** ((KEYS.find(key[0]) + key.count('+') - (0 if key[0] == '-' else key.count('-')) + TRANSPOSE) / 12.0)) + 0.5)
    
    def play_random():
        key = 'c'
        RANDOM_KEYS = WHITE_KEYS
        while not 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 - 1
                if 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)
    
    def play_songs():
        songs = list(SONGS)
        while True:
            random.shuffle(songs)
            for song in songs:
                play(song)
                time.sleep(PAUSE_TIME)
    
    def author():
        for note in AUTHOR:
            winsound.Beep(get_frequency(note), 1000)
        time.sleep(1)
        while msvcrt.kbhit():
            msvcrt.getwch()
        author = random.sample(AUTHOR, len(AUTHOR))
        while not 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()
    
    #/usr/bin/env蟒蛇3
    导入msvcrt
    随机输入
    导入时间
    导入winsound
    #常数
    键='zsxcfvgbnjmk,l./\'q2we4r5t6yu8i9op-[=]
    A4=440
    作者='.\',zb'
    新歌=('vm',
    “zv”,
    “cn”,
    “vm”,
    "xb",,
    “cn”,
    ‘zv’)
    #配置
    NS_SP=1
    速度=5
    持有率=0.95
    转置=0
    暂停时间=2
    SHOW_FREQU=False
    #随机的
    邻接比=0.9
    奇数比=0.05
    开关比=0.01
    白键='zxcvbnm,./qwertyuiop[]
    黑色按键='sfgjkl'245689-='
    示例_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)]
    示例_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)]
    示例_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),
    
    #! /usr/bin/env python3
    import math
    import wave
    
    ################################################################################
    
    class Waves:
    
        BUFF = 1 << 20
        MAX = 127
        MID = 128
    
        def __init__(self, fps):
            self.__fps = fps
            self.__data = []
    
        @staticmethod
        def __sin(ratio):
            return math.sin(ratio * math.pi * 2)
    
        @staticmethod
        def __squ(ratio):
            return 1 - ratio // 0.5 * 2
    
        @staticmethod
        def __tri(ratio):
            if ratio < 0.25:
                return ratio / 0.25
            elif ratio < 0.75:
                return 1 - 4 * (ratio - 0.25)
            else:
                return (ratio - 0.75) * 4 - 1
    
        @staticmethod
        def __saw(ratio):
            return ratio / 0.5 - ratio // 0.5 * 2
    
        def add_sine(self, freq, amp):
            self.__add(freq, amp, self.__sin)
    
        def add_square(self, freq, amp):
            self.__add(freq, amp, self.__squ)
    
        def add_triangle(self, freq, amp):
            self.__add(freq, amp, self.__tri)
    
        def add_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 in range(rate))
    
        def interpolate_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)
    
        def interpolate_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)
    
        def interpolate_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)
    
        def interpolate_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 in range(samples):
                b = position / samples
                a = 1 - b
                func(freq_a * a + freq_b * b, amp_a * a + amp_b * b)
    
        def write(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 in range(parts):
                index = part * self.BUFF
                buff = self.__data[index:index+self.BUFF]
                byte = self.__transform(buff)
                file.writeframes(byte)
    
        @classmethod
        def __transform(cls, buff):
            return bytes(int(pos * cls.MAX) + cls.MID for pos in buff)
    
        @classmethod
        def add(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 in zip(*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
    
        def append(self, other):
            assert self.__fps == other.__fps, 'Framerate is not the same!'
            self.__data.extend(other.__data)
    
        def average_amp(self):
            total = count = 0
            for value in self.__data:
                total += abs(value)
                count += 1
            return total / count
    
        def adjust_amp(self, value):
            self *= value / self.average_amp()
    
    ################################################################################
    
    def test_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')
    
    def test_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')
    
    def test_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')
    
    def test_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()
    
    from winsound import Beep
    
    # Beep(frequency, duration) Frequency in Hertz, duration in ms
    
    Beep(480,200)
    Beep(1568,200)
    Beep(1568,200)
    Beep(1568,200)
    Beep(740,200)
    Beep(784,200)
    Beep(784,200)
    Beep(784,200)
    Beep(370,200)
    Beep(392,200)
    Beep(370,200)
    Beep(392,200)
    Beep(392,400)
    Beep(196,400)