Jim*_*616 5 python pyaudio python-3.x
我和我的儿子正在尝试编写一个程序,允许用户输入一系列音符,并将它们保存到要播放的列表中。我们提出了以下方案:
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
Run Code Online (Sandbox Code Playgroud)
作为一个起点,它工作得很好,但音符听起来不太“音乐”。
从这里,我们想知道:
是否有任何现有的 Python 脚本或模块可以执行类似的操作?
有没有办法修改波形以模拟不同的仪器?
小智 3
几乎可以肯定有大量的合成器或程序可以做类似这样的各种事情。然而,自己做这件事有很多乐趣和价值,老实说我无法向您指出任何具体的事情。对于您的任务,您可以通过添加额外的谐波来创建方波和正弦波、根据模式添加额外的谐波(正如我在下面的某些情况下所做的那样)或改变起始、相位等操作来修改波形。 、振幅或您想要的任何其他方面。
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
Run Code Online (Sandbox Code Playgroud)
Once you experiment with different sounds, you can start looking into how these go together to make real instrument sounds. For instance, guitar or piano decay differently, but not as different as they'd be to woodwinds. Drums generally lack much harmonic structure on purpose, a violin is designed to highlight very pleasant harmonic overtones. There is a good music stackexchange question on the characteristics of instruments.
One thing I would suggest is using a buffer instead of the one-off approach to calculating the next value. Being able to generate a good sound (and apply more complicated algorithms) will be impeded by the ability of your process to complete before the next audio sample is due. I think that's outside the scope of this particular question, but it would also probably be good to use the call back method from pyaudio for this application: https://people.csail.mit.edu/hubert/pyaudio/docs/#example-callback-mode-audio-i-o
| 归档时间: |
|
| 查看次数: |
2739 次 |
| 最近记录: |