基本音乐理论在〜200行Python中

2021-04-19 22:11:39

我是多年来的自学吉他手,就像很多自学音乐家一样,令人窒息的是(西部)音乐理论。

本文介绍了蟒蛇大约200段中西方音乐理论的基础知识。

我们将首先查看西方音乐理论中的音符,使用它们在给定密钥中获得TheComom刻度,然后将其与漫长的常见尺度和和弦相结合。

最后,我们将看看模式,这些模式是常见的尺度的全系列系列,可用于唤起更加微妙的情绪和大气的悲伤二分尺寸提供的快乐和群体。

西方音乐的音乐字母表由一个通过G,而且他们是不同的音符。

但是,这些笔记在其频率上没有均匀间隔。为了在音高之间获得Moreeven间距,我们有以下十二篇注意:

notes_basic = [[' a'],['#&#39 ;,' bb'],[B'],[' C'],[' c#',db'],[' d'],[' d#&#39 ;,&#39 ; EB'],[' E'],[' f'],[' f#&#39 ;,' gb'],[ ' g'],[' g#&#39 ;,' ab'],],],]

这里有四件事要注意:首先,每个音符都是半步半音分开,第二,所代表的方式是通过可选的特定符号(称为意外)来表示半步提升(夏普,♯)或者基本音符的半动力(平坦,♭),第三,上面的笔记只需环回并重新开始,但在更高的Octave [1]。

最后,您将注意到这些概述由包含多个名称的列表表示:这些是增强臂等同物,这是一个奇特的方式说,同一笔记可以具有不同的“拼写”。因此,例如上面的笔记一半的步骤A是A1,但它也可以认为在B下方的半步,并且因此可以被称为B♭。对于历历,Notes B / C和E / F之间没有锐利或公寓。

关于为什么我们需要这些等同物的关键是,当我们开始推导普通尺度(主要,次要和模式)时,连续的笔记必须以连续字母开头。使用不同字母表的Having Angarmonic等价物允许我们正确地衍生级别。

实际上,对于某些键,上述增强臂票据不足以满足“不同字母连续备注规则”,我们最终必须使用升高或降低笔记的锐利和双平面完整的阶梯。这些尺度通常具有不需要这些DoubleAciental的等同物,而是完整性,我们可以通过重写我们的笔记来包括所有可能的增强队员按照:

注意= [' b#'' c'' dbb'],[' b ##&#39 ;,' c#&# 39;' db'],[' c ##&#39 ;,' d&#39 ;,' ebb'],[' d#& #39 ;,' Eb&#39 ;,' fbb'],[' d ##&#39 ;,' e&#39 ;,' fb&# 39;],[' e#&#39 ;,' f&#39 ;,' gbb'],[' e ##&#39 ;,' f#' f#' f#& #39 ;,' gb'],[' f ##'' g&#39 ;,' abb'],[' g#',' ab'],[' g ##&#39 ;,' a&#39 ;,' bbb'],[&#39 ;一个#&#39 ;,' bb'' cbb'],[' a ##&#39 ;,' b&#39 ;,' CB'],]

色度是最简单的规模,并且只需由给定密钥的八度音阶之间的所有(十二个)的半音组成(规模中的主要注释,辅助补品)。

我们可以非常容易地为任何给定的键生成色标:(i)在我们的列表中找到索引的索引,然后(ii)左转旋转多次列表。

让我们编写一个简单的函数来找到此列表中的特定注释:

def(scale,search_note):'''鉴于规模,找到特定注释的索引'''对于索引,请注意枚举(刻度):#处理我们有一个列表的invarmonic#等同物列表,以及仅为单一的笔记和str。如果类型(note)==列表:如果在注释:返回index elif类型(note)== str:如果search_note ==注意:返回索引

()函数用作参数一系列Notes(),以及用于搜索()的注释,并通过简单的线性搜索返回索引。我们在循环中处理两种情况:(i)所提供的包括单个票据(如上面的列表),或(ii)由其组成的,其中包含了增强乐队等同物列表(如我们或上面的名单)。该方法是如何该功能适用​​于:

>>> find_note_index(笔记,' a')#notes是lists9>>> find_note_index(字母表,' a')#phallabet是音符0列表

def(scale,n):'''左旋转尺寸为n位置。 '''返回规模[n:] + scale [:n]

我们将列表切片位置并交换两半。这是旋转我们列出的三个地方的示例(将注意事项带来前面):

>>>字母[' A&#39 ;,' b&#39 ;,' c&#39 ;,' d&#39 ;,' e&#39 ;,&#39 ; f&#39 ;,' g']>>旋转(字母,3)[' d'' e&#39 ;,' f&#39 ;,' g&#39 ;,' a&#39 ;,' b&#39 ;,' c']

我们现在可以通过旋转数组来编写为给定键生成色彩扫描的()函数:

def(键):'''在给定密钥中生成色度。 ''' #弄清楚旋转笔记列表并返回#旋转的版本。 num_rotations = find_note_index(notes,key)返回旋转(notes,num_rootations)

上面的()函数查找列表中提供的键的索引(使用我们的()函数),然后通过该量旋转它来将其带到前面(使用我们的()函数)。这是一个实例,用于消除D彩色尺度:

>>>导入p打印>>> pprint.pprint(' c#39; c ##'' d',' eBB'],['' #39; D#'' EB&#39 ;,' fbb'],[' d ##&#39 ;,' e&#39 ;,' 39; fb'],[' e#'' f&#39 ;,' gbb'],[' e ##',& #39; f#&#39 ;,' gb'],[' f ##'' g&#39 ;,' abb'],[ ' g#'' ab'],[' g ##&#39 ;,' a&#39 ;,' bbb'], ['#&#39 ;,' bb&#39 ;,' cbb'],[' a ##&#39 ;,' B&#39 ;, ' cb'],[' b#'' c&#39 ;,' dbb'],[' b ##' ,' c#&#39 ;,' db']]

对于彩色尺度,一个通常使用Sharwhen升序和平面。然而,现在,我们留下了螺旋桨等同物;我们会觉得稍后选择正确的注释。

基于距Tonic或root注意的相对距离来给出色度的音符。下面是每个音符的标准名称,已ordedIndident到列表中的索引:

间隔= [[' p1'' d2'],#完美的齐声减少了第二个[' m2&#39 ;,#39; a1'],#minor第二个增强统一[' m2&#39 ;,#39; d3'],#主要第二次减少第三次[' m3&#39 ;,' a2'],#minor第三个增强第二次[' m3&#39 ;,' d4'],#主要第三减少第四次[' p4'' a3'],#完美第四个增强第三[' d5'' a4'],#5分,第五个增强第四次[' p5&#39 ;,#39; d6'],#完美第五5分六[' m6'' a5'],#minar第六增强第五[' m6&#39 ;,#39; d7'],#主要第六次减少了第七[' m7&#39 ;,' a6'],#次要第七个增强六[' m7&#39 ;,#39; d8'],#主要第七减少了八度音乐[' p8'' a7'],#完美八度音高增添了第七七]

同样,相同的音符可以具有不同的间隔名称。例如,根注意可以被认为是完美的统一或一个微调2 nd。

给定给定密钥中的色标,以及AboveArray中的间隔名称,我们可以引脚指向要使用的确切注意(并从Setof Columonic等价物中过滤掉)。让我们来看看这件事的基本方法。

作为一个例子,让我们来看看如何从色度刻度找到对应的音符或主要的第三间隔。

从我们的间隔数组来看,我们可以看到我们发现的索引是4.那是' m3'间隔[4] == true。

现在我们看看我们的D彩色刻度相同的指数(模数其长度)。我们发现(' d')是音符列表[' e ##'' f#'' gb']。

(即,3)中的数字表示我们需要使用的字母表,1表示根字母表。例如,对于d,= d,= e,= f,= g,= a,= b,= c,= d ...等的键。所以我们需要在我们的票据列表中查找一个注释([' e ##'' f#' gb'])包含字母。那是笔记F#。

我们可以编写一个相对简单的功能来编程为我们应用此逻辑,并为我们提供一个DICT将所有间隔名称映射到给定密钥中的右侧注释:

def(key):#我们标记为的notes映射间隔名称为notes标签= {}#步骤1:在我们所需的密钥Chromatic_scale =校准中生成色标= Chromatic(key)#从提供的键开始的字母和#39; s字母表alphabet_key =旋转(字母,find_note_index(字母表,key [0]))#迭代index的所有间隔(列表列表),inumerate中的interval_list(间隔):#步骤2:查找通过基于学位搜索的注释_to_search = Chromatic_scale [index%len(chromatic_scale)] for intervall_list中的interval_name:#获取间隔度度= int(interval_name [1]) - 1# m3 - > 3,M7 - > 7#获取字母表以查找alphabet_to_search = alphabet_key [degete%len(alphabet_key)] try:note = [for x在notes x中,如果x [0] == alphabet_to_search] [0]除:note = notes_to_search [0]标签[Interval_name] =注意返回标签

>>>导入p打印>>> pprint.pprint(make_intervals_standard(' c'),sort_dicts = false){' p1&#39 ;:' c&#39 ;,' d2&#39 ;:&# 39; dbb&#39 ;,' m2&#39 ;:' db&#39 ;,' a1&#39 ;:' c#&#39 ;,' m2&#39 ;' d&#39 ;,' d3&#39 ;:' ebb&#39 ;,' m3&#39 ;:' eb&#39 ;,&#39 ; A2&#39 ;:' d#&#39 ;,' m3&#39 ;:' e&#39 ;,' d4&#39 ;:' fb' ,' p4&#39 ;:' f&#39 ;,' a3&#39 ;:' e#&#39 ;,' d5&#39 ;:' GB&#39 ;,' a4&#39 ;:' f#'' p5&#39 ;:' g'' d6&#39 ;: ' abb&#39 ;,' m6&#39 ;:#39; ab&#39 ;,' a5&#39 ;:' g#&#39 ;,' m6& #39 ;:'一个&#39 ;,' d7&#39 ;:' bbb'' m7&#39 ;:' bb'& #39; A6&#39 ;:'一个#&#39 ;,' m7&#39 ;:' b&#39 ;,' d8&#39 ;:' cb&# 39;' p8&#39 ;:' c&#39 ;,' a7&#39 ;:' b#'}

我们现在可以使用间隔名称指定公式或笔记组,并且能够将它们映射到我们想要的任何键:

def(公式,标记):'''给定逗号分隔的间隔公式,以及密钥中的一组标记值,返回公式的说明。 '''返回公式中x的[标记[x] .split(',')]

我们可以使用它来轻松为不同键生成主要规模,如下所示:

>>>对于字母表中的关键:>>> print(key,make_formula(formulate_intervals_standard(key))c [' c&#39 ;,' d&#39 ;,' e&#39 ;,' f&#39 ;,' g&#39 ;,' a&#39 ;,' b&#39 ;,' c'] d [' d&#39 ;, #39; E&#39 ;,' f#&#39 ;,' g&#39 ;,' a&#39 ;,' b&#39 ;,' c#&# 39;' D'] E [' E&#39 ;,' f#&#39 ;,' g#'' a&#39 ;, ' B&#39 ;,' c#&#39 ;,' d#&#39 ;,' e'] f [' f&#39 ;,&#39 ; G'' a&#39 ;,' bb&#39 ;,' c&#39 ;,' d&#39 ;,' E' ,' f'] g [' g'' a&#39 ;,' b&#39 ;,' c&#39 ;,&# 39; D&#39 ;,' e&#39 ;,' f#&#39 ;,' g'] [' a' b' b& #39 ;,' c#&#39 ;,' d&#39 ;,' e&#39 ;,' f#&#39 ;,' g#&#39 ;, #39; a'] b [' b&#39 ;,' c#&#39 ;,' d#&#39 ;,' e&#39 ;,' F#&#39 ;,' g#&#39 ;,' a#&#39 ;,' b']

让我们快速编写一个函数以以更好的方式打印尺度:

def(刻度,分离器=''):'''漂亮打印比例的音符。取代Unicode平面和锐利符号的B和#字符。 '''返回分隔符.join([' {:< 3s}' x规模x的格式(x)))\ .replace(' b'' \ u266d' \ u266d& #39;)\ .replace('#'' \ u266f')

>>>对于字母表中的关键:>>> scale = make_formula(公式,make_intervals_standard(key))>>>打印(' {}:{}} FG:Gabcdef♯ga:Abc♯def♯gìb:bc♯d♯ef♯g♯a♯b

命名公式的另一种方法是基于主要规模的音符。如果您熟悉其主要规模,则在播放仪器时播放仪器时,播放仪器时更容易。

间隔_major = [[' 1'' bb2'],[' b2&#39 ;,'#1'],[' 2& #39 ;,' bb3&#39 ;,' 9'],[' b3&#39 ;,'#2'],[39; 3& #39;,' b4'],[' 4&#39 ;,'#3&#39 ;,#39; 11'],[' b5& #39 ;,'#4&#39 ;,'#11'],[' 5&#39 ;,' bb6'],[' B6&#39 ;,'#5'],[' 6&#39 ;,' bb7&#39 ;,' 13'],[' B7&#39 ;,'#6'],[' 7&#39 ;,' b8'],[' 8&#39 ;,' #7'],]

我还添加了更复杂的和弦(第9个,第11号和第13个)的常见间隔。这些基本上缠绕在模数八。因此,例如,第9个只是第二个,但八度音高更高。

def(key,stinkal_type ='标准'):...用于索引,inumerate中的interval_list(间隔):... intins =间隔如果interval_type =='标准' else internals_major for intervall_name是间隔的:#获取间隔度,如果intervall_type =='标准' deacture = int(stinkal_name [1]) - 1#。 m3 - > 3,M7 - > 7 Elif Interval_type =='主要&#39 ;:学位= int(re.sub(' [b#]''''' idental_name)) - 1 .. 。退货标签

上面,我们刚刚向()函数添加了一个新的参数(interval_type),并在内循环中计算不同的方式。如果Interval_type指定为'主要'我们只需删除所有和字符,然后转换为整数以获得学位。

公式= {#比例公式' scales&#39 ;: {#主要规模,其模式和小规模'主要&#39 ;:' 1,2,3,4,5,6 ,7',' minor&#39 ;:' 1,2,b3,4,5,b6,b7',#melodic minor及其模式' melodic_minor' :' 1,2,b3,4,5,7,7',#谐波未成年人和其模式' houronic_minor&#39 ;:' 1,2,b3,5 ,b6,7',#blues scales' major_blues&#39 ;:' 1,2,b3,5,6&#39 ;,' minor_blues&#39 ;:&# 39; 1,B3,4,B5,5,B7',#晨瞳秤' pentatonic_major&#39 ;:' 1,2,3,5,6&#39 ;,' pentatonic_minor&#39 ;:' 1,b3,5,2,b7&#39 ;,' pentatonic_blues&#39 ;:' 1,b3,4,b5,5,b7', },'和弦&#39 ;: {#major'主要&#39 ;:' 1,3,5&#39 ;,' major_6&#39 ;:' 1 ,3,5,6&#39 ;,' major_6_9&#39 ;:' 1,3,5,6,9'' major_7&#39 ;:' 1 ,3,5,7&#39 ;,' mosit_9&#39 ;:' 1,3,5,7,9&#39 ;,' major_13&#39 ;:' 1 ,3,5,7,9,11,13&#39 ;,' major_7_#11&#39 ;:' 1,3,5,7,#11',#minor&#3 9;次要&#39 ;:' 1,b3,5&#39 ;,' minor_6&#39 ;:' 1,b3,5,6&#39 ;,' minor_6_9&# 39 ;:' 1,B3,5,6,9&#39 ;,' minor_7&#39 ;:' 1,b3,5,b7&#39 ;,' minor_9' 39 ;:' 1,b3,5,b7,9&#39 ;,' minor_11&#39 ;:' 1,b3,5,b7,9,11&#39 ;,&# 39; minor_7_b5&#39 ;:' 1,b3,b5,b7',#imonant' dominant_7&#39 ;:' 1,3,5,b7'&# 39; Dominant_9&#39 ;:' 1,3,5,B7,9&#39 ;,' Dominant_11&#39 ;:' 1,3,5,B7,9,11&#39 ;,' Dominant_13&#39 ;:' 1,3,5,B7,9,11,13&#39 ;,' Dominant_7_#11&#39 ;:' 1,3 ,5,b7,#11',#减少'减少&#39 ;:' 1,b3,b5&#39 ;,' diminised_7&#39 ;:' 1, B3,B5,BB7'' diminised_7_half&#39 ;:' 1,b3,b5,b7',#augmented'增强&#39 ;:' 1, 3,#5',#supended' sus2&#39 ;:' 1,2,5&#39 ;,' sus4&#39 ;:' 1,4,5 #39 ;,' 7Sus2&#39 ;:' 1,2,5,B7&#39 ;,' 7SUS4&#39 ;:' 1,4,5,B7&#39 ;,},}

以下是在C的键中生成所有这些尺度和和弦时的输出:

intins = make_intervals(' c'' majory')for formulas中的ftype:print(ftype)的名称,公式中的公式[ftype] .items():v = make_formula(公式,intins)打印(' \ t {}:{}'格式(名称,转储(v)))

尺度专业:CDEFGAB次要:CDE♭FGA♭B♭Melodic_minor:CDE♭FGABHONOC_MINOR:CDE♭FGA♭Bmajor_blues:CDE♭egaminar_blues:CE♭fg♭gb♭pentatonic_major:cdega pentatonic_minor:c cda fgb♭pentatonic_blues:ce♭ FG♭GB♭和弦专业:CEG MOST_6:CEGA MOISS_6_9:CEGB MOST_7:CEGBD MASS_13:CEGBDFA MAJIC_7_7_#11:CEGBF♯次要:CE♭GMINER_6:CE♭GADMINER_6_9:CE♭GB♭ minor_9:ce♭gb♭d minor_11:ce♭gb♭df minor_7_b5:ce♭g♭b♭dominant_7:cegb♭dominant_11:cegb♭df dominant_13:cegb♭dfa dominant_7_#11:cegb♭f♯减少:CE♭g♭diminished_7:ce♭g♭b♭♭diminished_7_half:ce♭g♭b♭增强:CEGαSUS2:CDG SUS4:CFG 7SUS2:CDGB第7Sus4:CFGB♭

值得注意的是,由于旋转后的根注意变化,因此产生的旋转尺度或模式在不同的键中。

对于每个密钥,根据所应用的左旋转数量,主要规模齐全的七种模式,每个都有特定名称:

major_mode_rotations = {'爱奥尼亚&#39 ;: 0,' dorian&#39 ;: 1,'菲尼亚&#39 ;: 2,'莉迪亚&#39 ;: 3,&#39 ; Mimolydian&#39 ;: 4,' Aeolian&#39 ;: 5,'洛杉矶&#39 ;: 6,}

使用此,我们现在可以为任何给定密钥生成主要规模的模式。这是C重大规模的一个例子:

intins = make_intervals(' c'' major')c_major_scale = make_formula(公式[' scales'] ['主要'],intins)对于m在major_mode_rootations:v = mode(c_major_cale,major_mode_rootations [m])打印(' {} {}:{}' format(dump([v [0]),m,dump( v))))

C IONIAN:C D E F G A BD DORIAN:D E F G A B CE DF Lydian:F G A B C D EG:G A B C D E FA AEOLIAN:A B C D E F GB LOCIRIAN:B C D E F G A

上面,我们正在寻找从给定比例得出的模式。但是,在实践中,您关心的是给定密钥的模式。所以给出了C的关键,我们想知道C离子,C Dorian,C Mimolydian等。

另一个方法是“C Mimololidian”,例如,与“C的混偶尼斯”不同。前者意味着一种混合型刻度,其中根部注释是C.后者意味着C重大比例的混偶(即,来自上述G Mixolydian)。

键= [' b#&#39 ;,#39; c&#39 ;,' c#&#39 ;,' db&#39 ;,' d&#39 ;,&# 39; d#&#39 ;,' eb&#39 ;,' e&#39 ;,' fb&#39 ;,' e#&#39 ;,' f&#39 ;,' f#&#39 ;,' gb&#39 ;,' g&#39 ;,' g#&#39 ;,' ab&#39 ;,&#39 ;一个&#39 ;,'一个#&#39 ;,' bb&#39 ;,' b&#39 ;,' cb',] modes = {}键键:intins = make_intervals(key,' major')c_major_scale = make_formula(公式[' scales'] [' major'],invs)在major_mode_rooting: v = mode(c_major_cale,major_mode_rotations [m])如果v [0]不是模式:模式[v [0]] = {}模式[v [0]] [m] = v

上面,我们通过每个密钥,并在我们遇到它们时建立一个包含每个键模式的DICT(通过检查模式的第一个音符)。

{' aneolian#39 ;: [和#39; c&#39 ;,' d&#39 ;,#39; ......