我是编程和查看其他人编写的代码的新手。我找到了一个在python中生成音乐的简洁程序,我真的很想了解它在做什么(链接/信用在这里:http://davywybiral.blogspot.com.br/2010/09/procedural-music-with-pyaudio-and-numpy.html)。
具体来说,我已经挂断了属于程序开头的类的变量intervals
。这是班级:
class Scale:
def __init__(self, root, intervals):
self.root = Note(root.index, 0)
self.intervals = intervals
def get(self, index):
intervals = self.intervals
if index < 0:
index = abs(index)
intervals = reversed(self.intervals)
intervals = itertools.cycle(self.intervals)
note = self.root
for i in xrange(index):
note = note.transpose(intervals.next())
return note
def index(self, note):
intervals = itertools.cycle(self.intervals)
index = 0
x = self.root
while x.octave != note.octave or x.note != note.note:
x = x.transpose(intervals.next())
index += 1
return index
def transpose(self, note, interval):
return self.get(self.index(note) + interval)
在节目结束时,有程序播放某些和弦的说明,以下是:
scale = Scale(root, [2, 1, 2, 2, 1, 3, 1])
这是我不清楚的第二个论点;我知道程序正在循环使用这些值,但我不知道它们在控制什么。我只是知道改变它们会在最糟糕的情况下混乱。
我可以就这些线路发生的事情获得一些指导吗?
答案 0 :(得分:0)
值是笔记之间的间隔。所以在这种情况下: 2 1 2 2 1 3 1,根据您提供的链接上的说明,是谐波次要(也见wiki)。
因此,如果更改数字,则更改音符之间的距离/间隔以及音阶。
假设root是A,提供以下比例:
A B C D E F G# A Actual notes
2 1 2 2 1 3 1 The intervals between the notes
如果列表为[2 1 2 2 1 2 1],则比例将是次要的:
A B C D E F G A Actual notes
2 1 2 2 1 2 1 The intervals between the notes
因此,如果你想给它一个C大调,你应该放弃:
C D E F G A B C in a list of intervals:
2 2 1 2 2 2 1
我希望这会有所帮助。
干杯!
答案 1 :(得分:0)
此代码的核心是迭代器的概念。迭代器是&#34;指针&#34;进入列表,例如间隔,用于在列表中移动。 例如
for i in [1, 2, 3]:
print i
该代码遍历列表[1,2,3]并打印.. 1 2 3
虽然迭代器可以让你计算&#34;通过列表,如果需要迭代器,列表将自动转换为迭代器。
所以这段代码在get()的代码中交替使用了区间列表和各种迭代器,这让人很困惑。它基本上做了一堆有序的改组音符。
这大致就是它的作用(我对音乐的了解和你对编程的了解:)。看起来它听起来像巴赫。
class Scale: # class declaration.
def __init__(self, root, intervals):
"""
__init__ is the constructor. It gets called automatically
whenever a new instance is created. That is, it's called
automatically when a new Scale is made, e.g. on this line:
scale = Scale(root, [2, 1, 2, 2, 1, 3, 1])
"""
self.root = Note(root.index, 0) # the root is a note?
self.intervals = intervals # this just saves the list [2, 1,..
def get(self, index):
"""
called whenever someone goes.. scale.get(index) or within
this class it's called as self.get(index).
"""
# get a reference to the intervals (no copy is made)
# at this point we could iterate over it from the start of the
# intervals to the end of the intervals e.g. 2, 1, 2, 2, ..
intervals = self.intervals
# if the index is less than zero
if index < 0:
# get the absolute value, e.g. -5 goes to 5
index = abs(index)
# makes intervals an iterator that counts backwards
# e.g. [1, 3, 1, 2...]
# this "mirrors" the intervals if you like
intervals = reversed(self.intervals)
# makes intervals "loop forever" you can keep iterating and
# when you get to the end, loop around to the start again.
intervals = itertools.cycle(self.intervals)
# swap this note with the next index notes
note = self.root
for i in xrange(index):
note = note.transpose(intervals.next())
return note
def index(self, note):
"""
Finds the index of the next note and transposes
a bunch of them to.
"""
intervals = itertools.cycle(self.intervals)
index = 0
x = self.root
# keep trying notes until we have a different note in
# this octave
while x.octave != note.octave or x.note != note.note:
x = x.transpose(intervals.next())
index += 1
return index
def transpose(self, note, interval):
"""
Gets the note one interval away.
Which also transposes a bunch of things.
"""
return self.get(self.index(note) + interval)