1 为什么是音乐与编程?
欢迎阅读《用 Python 入门数字音乐:通过代码学习音乐》。本书专为热爱音乐且对音乐与编程的交叉领域感兴趣的人设计。或许你是一位有抱负的音乐家或音乐制作人,想了解更多关于编程及其能实现的功能;或许你已经懂一点编程,想拓展自己的音乐创作视野;又或许你在这两方面都是纯新手。无论你的起点如何,本书都能帮助你将音乐与编程作为相辅相成的技能来学习。代码为我们提供了一种优雅的语言来思考音乐理念,而音乐则为代码提供了一个有意义且能立即发挥作用的场景。二者结合,形成了一种强大的新音乐创作方式,这种方式将与未来的数字制作工具紧密相连。
越来越多的代码被用于制作音乐、创作音乐,甚至为现场观众表演音乐。像 Logic、Reason、Pro Tools、FL Studio 和 Ableton Live 这样的数字制作工具,都是由庞大的软件工程师团队编写数百万行代码打造的复杂软件应用。借助这些工具,你可以编写代码来创建自定义插件和效果。除了制作工具,现场编程是一种新兴的音乐表演艺术形式,信息时代的 DJ 通过编写计算机代码为现场观众实时生成音乐。
在其他方面,我们正处于利用代码创作音乐的方式发生彻底变革的开端。音乐创新的历史始终与技术创新紧密相连。无论是 19 世纪的弗朗茨·李斯特,他基于钢琴的技术突破开创了现代音乐大师的形象,还是 20 世纪的库尔·赫克 DJ(DJ Kool Herc),他在布朗克斯用两台唱片机和一箱放克唱片开创了嘻哈音乐,技术都为音乐表达创造了新机会,挑战了现状并催生了新流派。我们尚未出现编程领域的弗朗茨·李斯特或库尔·赫克,但假以时日,未来的编程大师必将拓展音乐创作、制作和表演的可能性边界。
1.1 什么是 Python?
在本书中,你将学习如何使用一种名为 Python 的计算机编程语言来创作自己的数字音乐。如果你不熟悉编程语言,Python 是一种通用语言,于 20 世纪 90 年代首次发布,如今已成为世界上使用最广泛的语言之一。Python 设计初衷是易于读写,这使其成为初学者的热门选择。它功能齐全且强大,是数据科学、网页开发、艺术和视频游戏开发等多个领域专业人士的理想选择。由于 Python 已经存在了数十年,它可以在所有主要计算机操作系统上运行。本书中的示例甚至使用了一个可直接在网页浏览器中运行的 Python 版本,无需安装任何特殊软件。
与许多其他常见的入门编程语言不同,Python 是“基于文本的”,这意味着你需要在编辑器中输入代码,而不是在电脑屏幕上拖动代码块。这使得 Python 比其他入门语言稍难学习,但也极大地扩展了你的能力范围。当你读完这本书时,你应该能轻松编写简短的 Python 程序,并拥有自行探索更多内容所需的概念工具。
1.2 本书不是什么
在我们深入探讨一小段代码能实现什么具体功能之前,先简要说明一下本书不是什么。本书并非 Python 编程的全面指南。有许多优秀的书籍和教程专为初学者设计,其中一些还是免费的。2
本书也不是音乐理论或西方音乐记谱法的全面指南。我们会涉及节奏、和声、旋律和作曲背后的核心思想,但同样,对于想要深入学习的初学者来说,还有许多其他资源可供选择。我们提供的是一种不同的方法,将音乐学习与代码学习同等结合。
1.3 本书是什么
我们将带你直观理解音乐与编程背后的基本概念。代码和音乐都是高度技术性的技能,充满了晦涩的符号和术语,似乎天生就是为了吓退初学者。在本书中,我们会立即运用核心概念来创作音乐。你可以按照自己的节奏探索想法,在将想法付诸实践时获得即时反馈。我们暂时跳过大部分技术术语和细枝末节——这些可以稍后再学。相反,我们专注于培养你的信心和理解能力。重要的是,本书介绍的技能、工具和思维方式也将广泛适用于许多其他领域。你将使用 Python 代码,但变量、函数、循环、条件逻辑和类等核心结构在许多编程语言中都是相同的,包括 JavaScript、Java、C、C++ 和 C#。学会一种编程语言后,再学其他语言就会容易得多。
1.4 TunePad 和 EarSketch
本书使用两个结合了音乐与 Python 编程的免费在线平台。第一个是 TunePad(https://tunepad.com),由芝加哥西北大学的研究团队开发。TunePad 允许你创建简短的音乐循环,并通过简单的数字音频工作站(DAW)界面将它们分层组合。第二个平台是 EarSketch(https://earsketch.gatech.edu),由亚特兰大佐治亚理工学院的研究人员创建。EarSketch 使用 Python 代码将样本和循环编排成完整长度的作品。这两个平台都是基于浏览器的应用程序,因此你只需一台电脑(平板电脑或 Chromebook 也可以)、互联网连接和 Chrome 或 Firefox 等网页浏览器即可开始使用。外接扬声器或耳机虽好,但不是必需的。这两个平台已经存在多年,被从中学到大学及以上的成千上万名学生使用过。TunePad 和 EarSketch 主要设计为学习平台,但如果你想进一步深入,也有简单的方法将作品导出到专业制作软件中。
1.5 一个简单示例
下面是一个 Python 编程的简单示例。这个程序在 TunePad 中运行,用于创建简单的节拍模式,其变体已在数千首歌曲中使用,如 The Weeknd 的《Blinding Lights》和 SAINt JHN 的《Roses》。
playNote(1) # play a kick drum sound
playNote(2) # play a snare drum sound
playNote(1)
playNote(2)
rewind(4) # rewind 4 beats
for i in range(4):
rest(0.5)
playNote(4, beats = 0.5) # play hat for a half beat
这 8 行 Python 代码告诉 TunePad 播放一段包含底鼓、军鼓和踩镲的节奏。大多数行都是 playNote 指令,正如你可能猜到的,这些指令告诉 TunePad 播放括号中数字所指示的音乐声音。这个示例在第 6 行还包含一个名为“循环”(loop)的结构。暂时不必担心细节,但循环是一种重复执行一系列操作的简单方法。在这个例子中,循环告诉 Python 连续重复执行第 7 行和第 8 行四次。截图(图 1.1)显示了它在 TunePad 中的样子。你可以通过以下链接亲自尝试这个示例:https://tunepad.com/examples/roses。
1.6 学习编程的五个理由
既然你已经看到了几行 Python 代码能实现的功能,如果你仍有疑虑,以下是我们推荐学习编程与音乐结合的五大理由。
1.6.1 理由 1:无论你喜不喜欢,音乐已经由代码定义
纵观现代音乐领域,很明显音乐已经由代码定义。几乎所有流行流派的现代音乐都有一个最大的共同点:一切都经过复杂的计算机软件编辑,甚至完全由这些软件创作。很难高估这类软件对 21 世纪音乐声音的塑造作用。相对便宜的数字音频工作站(DAW)应用程序和无数跨平台通用插件,在音乐行业产生了颠覆性和民主化的影响。想想像 Auto-Tune(自动调音)、混响这样的效果插件,或者不改变速度而改变样本音高的功能。这些效果都是由复杂的软件生成的。曾经像小办公室那么大、价值数十万美元的录音棚设备,现在可以装在一台笔记本电脑里,任何有热情、能上网且预算不高的有志制作人都能拥有。转向数字制作工具的原因很明显。计算机已经发展到足够便宜、足够快且存储足够大,能够进行实时音频编辑。我们可以将声波转换为可编辑的数字信息,精度达到微秒级,然后实时听到修改后的效果。这些数字音频工作站并非凭空出现。它们是由庞大的软件工程师团队编写数百万行代码构建而成的。例如,TunePad 是由超过 150 万行代码构建的,使用了十多种计算机语言,如 Python、HTML、JavaScript、CSS 和 Dart。无论你对现代音乐的数字化有何看法,这种趋势都不会消失。学习编程将帮助你更了解这一切背后的工作原理。更重要的是,制作人编写自己的代码来处理声音的情况越来越普遍。例如,在 Logic 中,你可以编写 JavaScript 代码来处理输入的 MIDI(音乐设备数字接口)数据,以创建自定义琶音器等。学习编程可以给你更多控制权,帮助拓展你的创作潜力(图 1.2)。
1.6.2 理由 2:代码是创作音乐的强大工具
我们通常不会这样想,但音乐本质上是算法性的——它充满了数学关系、逻辑结构和递归模式。巴洛克赋格曲的美感,在某种程度上反映了其背后数学和计算思想的美感。我们称巴赫为天才,不仅因为他的音乐令人着迷,还因为他能够在脑海中构建复杂的算法,然后使用我们称为西方音乐记谱法的表示系统将其转录到纸上。换句话说,音乐记谱法是一种记录创作过程输出的语言,而不是捕捉创作过程本身算法本质的语言。
另一方面,代码是一种专门设计用于捕捉数学关系、逻辑结构和递归模式的语言。例如,陷阱音乐(trap music)的一个标志性特征是断断续续的踩镲模式。下面几行 Python 代码可以生成随机的断续踩镲模式,为原本常规的节拍注入活力。
for _ in range(16):
if randint(6) > 1: # 随机生成一个数字
playNote(4, beats=0.5) # 播放八分音符
else:
playNote(4, beats=0.25) # 或播放十六分音符
playNote(4, beats=0.25)
再举一个例子,下面两行 Python 程序可以播放一种在浩室(house)、电子舞曲(EDM)或流行音乐中常见的军鼓上升效果。你通常会在节拍爆发前听到这种技巧。这段代码使用衰减函数,使每个后续音符都稍短一些,从而产生逐渐加速的效果。暂时不必担心它的工作原理。我们会逐步详细解释。
for i in range(50): # 播放 50 个军鼓音
playNote(2, beats = pow(2, -0.09 * i))
这些效果的酷炫之处在于它们是参数化的。因为代码描述的是生成音乐的算法,而不是音乐本身,这意味着我们可以通过调整相关数字来创造无限的变化。例如,在陷阱音乐的踩镲代码中,我们可以通过增加或减少一个数字来轻松调整断续踩镲插入模式的频率。你可以把代码想象成电钻:你可以更换不同的钻头来钻出不同大小的孔。钻头就像参数,改变工具在特定情况下的作用。同样,算法是用途更广泛的工具,通过改变输入参数可以完成无数任务。
用代码创建军鼓上升效果显然与拿起两根鼓槌在真实鼓上敲击模式完全不同。需要明确的是,我们并不主张用代码取代学习演奏真实乐器。但是,代码可以成为你音乐技能库中的另一个工具,用于生成重复模式、探索数学思想,或者演奏那些快到或复杂到无法用手演奏的序列。
1.6.3 理由 3:代码让你构建自己的音乐工具库
在任何领域成为专业人士,都需要培养对工具的精通——获取设备并知道如何使用它们。显然,这在音乐行业是如此,在软件领域也是如此。专业软件工程师会获取专业设备和软件包,他们在多种编程语言和技术框架中培养专业技能。此外,他们还会构建自己的专用工具,用于多个项目。在本书中,我们将向你展示如何构建自己的 Python 函数库。你可以把函数看作是为执行不同音乐任务而创建的专用工具。除了上面描述的例子,你还可以编写一个函数来生成和弦进行或播放琶音,并且可以在许多音乐项目中反复使用这些函数。
1.6.4 理由 4:代码在无数其他领域也有用
正如我们在本章前面提到的,Python 是世界上功能最强大、用途最广泛的语言之一。它被用于创建 Web 服务器、社交媒体平台,也用于视频游戏、动画和音乐制作。它还用于研究、数据科学、政治和新闻领域。懂一点 Python 能让你接触到强大的机器学习和人工智能(AI/ML)技术,这些技术有望改变人类工作的大多数方面,包括音乐等创意领域。Python 既是脚本语言,也是软件工程平台——既是胶带,也是台锯——既能快速修复问题,也能开发耐用的软件应用程序。学一点 Python 不会让你成为软件工程师,就像学几个吉他和弦不会让你成为演奏家一样。但这是一条道路的开始,一扇曾经关闭的门现在打开了,一种新的思维方式和思考音乐的新方式。
1.6.5 理由 5:编程让我们更具人性
当我们想到学习编程时,往往会想到经济回报。你会听到这样的论点:学习编程能为简历增色,是通往高薪工作的途径。这种观点并非错误,但对你来说,这可能不是学习编程的正确理由。
就像擅长音乐的人热爱音乐一样,擅长编程的人往往也热爱编程。构建软件的过程可能枯燥且令人沮丧,但也可能带来回报。这是一种创造性表达自我和参与手工艺的方式。人们学习编织、烹饪或演奏乐器,不是为了这些追求所能带来的赚钱的职业道路——尽管这些追求当然能带来出色的职业——而是因为他们对这些事情有热情,因为这些事情能带来个人满足感。这些热情将我们与数百年的传统联系起来;将我们与教师、学习者和从业者社区联系起来;最终,让我们更具人性。因此,当事情变得有点令人沮丧时——学习任何有价值的技能时总会遇到挫折——请记住,就像诗歌、文学或音乐一样,代码既是艺术也是科学。就像木工、编织或烹饪一样,代码既是工艺也是工程学科。要有耐心,给自己一个爱上编程的机会。
1.7 音乐与代码的未来
在开始本书的正文之前,我们想简要谈谈技术、音乐和代码的未来。自从地球上有人类以来,就有了音乐。而且,自从有了音乐以来,人们就一直在创造技术来拓展和增强自己的创作潜力。鼓就是一种技术——一块兽皮绷在空心木头上并固定好。这是一项复杂的成就,是需要技能和工艺才能制作的部件组合。人们必须知道如何处理兽皮,如何用植物纤维制作绳子,以及如何制作和打磨工具。更重要的是,人们必须知道如何用鼓表演,与观众建立联系,通过节奏和情感的共鸣让他们舞动起来。技术将材料、工具与知识结合在一起。人们必须既有制作 artifact 的知识,也有使用它的知识。随着时间的推移——经过几代人——这些知识在师生之间传递时得到完善,变得风格化和多样化。工具、制品、知识和实践共同构成了更宏大的东西——我们称之为文化。
音乐世界一次又一次地被新技术颠覆、民主化和重新定义。嘻哈音乐是对音乐现状的反抗,由低成本技术推动,如可录制的盒式磁带、唱片机和 808 鼓机。早期创新者打破了艺术表达的常规,在此过程中重新定义了音乐、诗歌、视觉艺术和舞蹈。获取技术的低成本,加上对新形式真实自我表达的需求,点燃了种族和经济压迫的干柴。
技术进步正以惊人的速度改变世界,这一点再怎么强调也不为过。数字制品和基础设施无处不在,它们重新配置了社会、经济、法律和政治系统;彻底改变了科学研究;颠覆了艺术和文化;甚至渗透到我们个人和浪漫生活最私密的方面。我们已经谈到了数字工具在 21 世纪对音乐世界的变革性影响,但令人兴奋(也令人担忧)的是,我们正处于另一波变革的边缘,人工智能(AI)和机器学习(ML)将重新定义人类创造力。想象一下,AI 伴奏者能与人类音乐家实时即兴创作和声或旋律;深度学习算法能聆听数百万首歌曲并在同一流派中创新音乐;“硅基诗人”能充分理解人类语言,创作出复杂的说唱歌词;拥有数万亿晶体管突触的机器如此复杂,以至于它们开始“做梦”——逆向机器学习算法产生的图像如此离奇,足以打扰超现实主义画家在苦艾酒影响下的睡眠。现在,想象这不是投机性的科幻小说,而是我们当今世界的现实。这些事情已经存在,并且已经在挑战我们对人类创造力的理解。一个由数字创意赛博格(cyborgs)组成的社会会带来什么影响?
但关键在于:我们一直都是赛博格。西方音乐记谱法和 Python 代码一样,都是技术。精通任何足够先进的表示系统,都会深刻影响我们思考和感知周围世界的方式。古典音乐记谱法、理论和实践塑造了贝多芬的思想,正如他用它们塑造了音乐一样——以至于他在几乎完全失聪的情况下仍然能创作许多著名作品。贝多芬是一个被西方音乐记谱法和理论技术增强的创意赛博格。不同之处在于,现在我们已经将许多认知过程外化到能与我们一起思考的机器中。而且,这些工具正越来越多地为每个人所用。这将如何改变“有创造力的人”的含义,谁也说不准。
1.8 本书概述
我们很高兴能与你一起踏上这段音乐与代码的旅程。以下是我们接下来的内容指南。第 2 章和第 3 章涵盖节奏、音高和和声的基础知识。这些章节旨在快速推进,让你尽早开始用 Python 编程。我们将介绍 Python 变量、循环,这些都与音乐概念直接相关。第 4、5、6 章使用 Python 列表、函数和数据结构涵盖和弦、音阶和调式的基础知识。第 7、8、10 章从音乐创作转向音乐制作,涵盖频域、模块化合成和其他制作效果等主题。在第 9 章中,我们将切换到 EarSketch 平台,讨论如何组合各种音乐元素来创作完整长度的歌曲。最后,第 11 章简要概述音乐与代码的历史,并展望未来可能的发展。在每章之间,我们提供一系列简短的插曲,就像分步教程一样,介绍新的音乐和编程概念。
关于如何阅读本书的几点说明。任何时候我们包含 Python 代码,都会用编程字体显示,如下所示:playNote(60)
有时我们会在表格中编写代码并标注行号,以便我们可以引用特定的行。当我们引入新术语时,会将其加粗。如果你对任何编程或音乐术语感到困惑,请查看附录,其中包含所有重要概念的简要概述。我们经常会邀请你跟随在线示例操作。学习的最佳方式是亲自动手,因此我们强烈建议你在阅读各章时在线尝试编写 Python 代码。
注释 1 据说,粉丝们对李斯特的钢琴“摇滚明星”地位如此痴迷,以至于在他的演出中争抢他的丝绸手帕和天鹅绒手套。 2 我们推荐 https://www.w3schools.com/python/。
插曲 1 基础流行节拍
在本插曲中,我们将通过创建一个类似 SAINt JHN 的《Roses》风格的基础摇滚节拍来熟悉 TunePad 界面。你可以通过访问以下链接在线跟随操作: https://tunepad.com/interlude/pop-beat
步骤 1:深度聆听
养成深度聆听的习惯很有好处。深度聆听是尝试用各种可能的方式聆听声音的实践。首先在流媒体服务中加载一首你喜欢的歌曲,认真聆听——真正地聆听。将歌曲分解成各个元素。你听到了什么声音?它们是如何分层的?不同的部分在什么时候进入轨道,又是如何随时间变化的?思考制作人如何在整个频率范围内平衡声音,或者如何为歌词的过渡留出空间。试着只关注鼓声。你能开始识别出各个打击乐声音及其节奏模式吗?
步骤 2:创建新的 TunePad 项目
在笔记本电脑或 Chromebook 上访问 https://tunepad.com 并注册一个账户。1 如果你已有 Gmail 账户,可以使用现有账户登录。登录后,点击“New Project”按钮创建一个空项目工作区。你的项目看起来会像图 1.3 这样:
步骤 3:底鼓
在项目窗口中,点击“ADD CELL”按钮,然后选择“Drums”(图 1.4)。
在 TunePad 中,你可以把“cell”看作是一种可以编程来播放音乐的乐器。将新乐器命名为“Kicks”,然后添加以下 Python 代码:
# play four kick drums
playNote(1)
playNote(1)
playNote(1)
playNote(1)
完成后,你的项目应该会像图 1.5 这样。
点击左上角的“Play”按钮听听效果。恭喜!你刚刚编写了一个 Python 程序。
语法错误
有时你的代码可能无法正常工作,你会看到一个红色的错误消息框,如图 1.6 所示。这种错误消息称为“语法”(syntax)错误。在这个例子中,代码写成了 playnote
(小写“n”),而不是大写“N”的 playNote
。你可以通过将第 2 行的代码改为 playNote
(大写“N”)来修复这个错误(图 1.6)。
步骤 4:军鼓
在项目窗口中,再次点击“ADD CELL”按钮并选择“Drums”。现在你的项目中应该有两个鼓 cell,一个在另一个上面。将第二个乐器命名为“Snare Drums”,然后添加以下 Python 代码:
# play two snare drums on the up beats only
rest(1) # skip a beat
playNote(2) # play a snare drum sound
rest(1)
playNote(2)
你可能会注意到井号(#)后面的文本是程序的特殊部分。这些文本称为“注释”(comment),用于帮助程序员组织和记录代码。Python 会忽略行中井号后面的所有内容。试着播放这个军鼓 cell 听听效果。你也可以同时播放底鼓 cell,听听它们一起的效果。
步骤 5:踩镲
再次点击“ADD CELL”按钮添加第三个鼓 cell。将这个 cell 的标题改为“Hats”,并添加以下代码:
# play four hats between the kicks and snares
rest(0.5) # rest for half a beat
playNote(4, beats=0.5) # play a hat for half a beat
rest(0.5)
playNote(4, beats=0.5)
rest(0.5)
playNote(4, beats=0.5)
rest(0.5)
playNote(4, beats=0.5)
当你同时播放这三个鼓 cell 时,你应该会听到一个基础的摇滚节拍模式:
底鼓 - 踩镲 - 军鼓 - 踩镲 - 底鼓 - 踩镲 - 军鼓 - 踩镲
步骤 6:调整底鼓
你可能会注意到在这个混音中底鼓听起来有点重。我们可以在军鼓演奏的强拍(第 2 和第 4 拍)上加入休止符,为节奏留出一些空间。滚动回你的底鼓 cell,将代码改为如下所示:
# play kicks on the down beats only
playNote(1)
rest(1)
playNote(1)
rest(1)
playNote(1)
rest(1)
playNote(1)
rest(0.5) # rest a half beat
playNote(1, beats = 0.5) # half beat pickup kick
步骤 7:添加 bass 线
向项目中添加一个新 cell,但这次选择“Bass”而不是“Drums”。加载 cell 后,将音色改为“Plucked Bass”(图 1.7):
输入以下代码创建一个简化的 bass 线,风格类似 SAINt JHN 的《Roses》。完成后,试着一起播放所有内容,听听完整的效果。
playNote(5, beats=0.5) # start on low F
playNote(17, beats=0.5) # up an octave
rest(1)
playNote(10, beats=0.5) # A sharp
playNote(22, beats=0.5) # up an octave
rest(1)
playNote(8, beats=0.5) # G sharp
playNote(20, beats=0.5) # up an octave
rest(0.5)
playNote(8, beats=0.5) # G sharp - G - G
playNote(12, beats=0.5)
playNote(24, beats=0.5)
playNote(10, beats=0.75) # C sharp
playNote(22, beats=0.25) # D sharp
注释 1 我们推荐使用免费的 Google Chrome 浏览器以获得最佳体验。