CsoundAC 简介:使用 Csound 和 Python 进行算法作曲

作者:Dave Phillips

当世界上最强大的波形编译器遇到世界上最流行的编程语言之一时会发生什么?了解一位程序员如何使这一切协同工作,这是 CsoundAC 的介绍。

Michael Gogins 是一位专业程序员,也是 Csound5(强大而历史悠久的 Csound 的现代面貌)开发的主要贡献者。Michael 致力于使用计算机创作音乐的艺术。更具体地说,他的工作重点是使用计算机创造其他任何方式都无法产生的音乐。在过去的二十年中,这种兴趣促使他开发了各种工具来辅助他自己的作曲。他最新的工具包是 CsoundAC,这是一个基于 Python 的函数和例程集,专门为使用 Csound 进行算法音乐作曲而编写。

CsoundAC 需要 Python 编程语言,并且假定您具有一定的通用编程语言经验。它还假定您知道如何使用 Csound 进行编程。但是,Python 和 Csound 都是相对容易学习的语言,作者建议新读者在深入研究 CsoundAC 之前,先学习 www.python.org 上的教程。

在简要介绍了基础知识之后,Michael 在他的 Csound 算法作曲教程 (PDF) 中提供了一系列引人入胜的 CsoundAC 练习。该系列非常酷,包含用于实现莫扎特、约翰·凯奇、拉蒙特·扬、莱贾伦·希勒、比尔·肖茨塔特、特里·莱利和查尔斯·道奇作品的 Python/Csound 代码。再次,我必须提醒读者,这些练习是大量的代码块,需要事先了解所涉及的语言才能充分理解其过程。这些努力是值得的,我祝贺作者决定将知名作曲家的作品纳入教程材料中。仅仅将这些作品实现为音频就具有启发性和趣味性,但这些作品也是复杂的编程练习,用户可以通过这些练习掌握 CsoundAC 及其功能。

这些功能是什么?CsoundAC 的主要功能列表包括用于探索混沌系统、图像到乐谱转换、Lindenmayer 系统、奇异吸引子以及其他偶然和概率领域的例程和函数。支持 MIDI 输出,并且作者周到地包含了一大套乐器和效果器,用于通过 Csound 实现乐谱的音频。除了 Python 要求之外,CsoundAC 还是一个独立的系统,您可以在其中编码、编译和执行程序,即将其实现为音频文件。


安装和配置

您必须拥有支持 Python 接口的 Csound5 版本。感谢 Csound 用户 Felipe Satelier 等人的努力,一些 Linux 发行版包含最新的 Csound 软件包,其中包括 csound 二进制文件及其各种扩展模块。如果您想自己构建 Csound,您可能需要使用以下一些编译时选项

useDouble=1 useOSC=1 buildPythonOpcodes=1 buildInterfaces=1 buildPythonWrapper=1 \
buildJavaWrapper=1 buildLoris=1 buildCsoundAC=1 pythonVersion=2.6 \
dynamicCsoundLibrary=1

您可以省略除 Python 特定的选项之外的所有内容,但如果您想将 Csound 与更广泛的程序一起使用,您还需要其他选项。此外,您还需要安装 FLTK 图形工具包、C++ 的 boost 扩展库和 SWIG 接口生成软件的二进制文件和开发包。与 Python 和 Csound 一样,所有这些软件包都是免费和开源的。

顺便说一句,如果您决定自己构建系统,您可能需要手动安装 CsoundAC 模块。在我的当前机器上,Csound 源代码树中的 install.py 脚本没有安装所有内容,因此我必须确保 /usr/lib/python2.6/site-packages 包含以下组件

  CsoundAC.py
  _CsoundAC.so
  _csnd.so
  csnd.py

您可以执行一个简单的测试来查看 CsoundAC 是否已正确安装。启动 Python shell 后,输入以下命令

  import CsoundAC

如果您收到错误,您应该检查系统的 PYTHONPATH 变量

  echo $PYTHONPATH

如果您的 Python 版本的 site-packages 目录未在结果中列出,您可以使用以下命令添加它

  export PYTHONPATH=$PYTHONPATH:/usr/lib/python2.6/site-packages

根据您的 Python 版本和路径进行更正,然后再次尝试将 CsoundAC 模块导入 Python。如果错误仍然存在,您可能需要重新安装 Python。

图 1. SciTE 编辑器托管 Python + CsoundAC

还有一件事:Linux 版本的 CsoundAC 本质上是一个基于文本的环境。您可以选择从 Python 解释器的提示符下工作,但 CsoundAC 的作者建议使用 SciTE 程序员编辑器(图 1)或类似的程序,这些程序支持随机访问编辑、语法突出显示和代码执行等便利功能。


CsoundAC 内部

在 CsoundAC 的核心,我们发现了音乐图的概念。音乐图将 Csound 乐谱表示为“……节点的层次树,其中可以包含音符、乐谱生成器、乐谱转换和其他节点”,这是 Csound 手册 中的定义。事实上,该手册中的相关段落对 CsoundAC 的定义非常好,以至于我要进一步引用它

CsoundAC 中的坐标系基于欧几里得音乐空间,其维度为 {时间、时长、事件类型、乐器编号、以 MIDI 音键表示的音高、以 MIDI 速度表示的响度、相位、空间 X 坐标、空间 Y 坐标、空间 Z 坐标、音级集合、1}。音乐空间中的一个点可以是一个音符、一个音符的变调,甚至是声音的颗粒。

音乐图是音乐空间中节点的有向无环图或树。这些节点与 [坐标系] 的局部变换相关联。存在用于包含乐谱或乐谱片段、用于生成乐谱以及用于转换乐谱的节点。此外,任何节点都可以包含继承父节点坐标系的子节点。

因此,可以通过在较低级别的节点中包含或生成音符、使用较高级别的节点将它们组装成乐谱,并最终使用 Csound 渲染乐谱来创作音乐乐谱。该过程严格类似于在计算机图形中通过生成球体、圆锥体和立方体等原始对象并在空间中移动它们以组装场景来构建 3 维场景……

最后,可以从任何现有节点在 Python 中派生一个新的 Node 类,以便创建新的乐谱生成器和转换作为作曲过程的一部分。

如果该描述的任何部分让您感到困惑,请不要害怕,它可能也让我感到困惑。但最终重要的是从所有这些定义和描述中产生的音乐,而 CsoundAC 首先是一个音乐制作人的工具包。您不一定需要确切了解“混沌动力系统”是如何工作的,甚至它是什么。您确实需要知道如何在 Python/Csound 环境中运行该代码,并且代码本身是开始学习此类系统的好地方。


一个简单的练习

让我们看一下 CsoundAC 中的一个简单练习。以下代码是 Michael 教程中第一个示例的略微编辑版本

    import CsoundAC	; Bring CsoundAC functions and processes into Python.

    orchestra = '''	; Set the orchestra code block.
    sr = 44100		; These lines set the instrument's
    ksmps = 100		; sample rate, control rate, and
    nchnls = 2		; number of output channels.

                instr 1		; Define a Csound instrument, numbered 1.
		; Begin envelope design.
                ; Sharp attack stage, but not sharp enough to click.
    iattack     =           0.005
                ; Moderate decay stage.
    idecay      =           0.2
                ; Fast but gentle release stage.
    irelease    =           0.05
                ; Extend the total duration (p3 in the score) to include 
		; the attack, decay, and release.
    isustain    =           p3
    p3          =           iattack + idecay + isustain + irelease
                ; Exponential envelope.
    kenvelope    transeg       0.0, iattack, -3.0, 1.0, idecay, -3.0, 0.25, \
                               isustain, -3.0, 0.25, irelease, -3.0, 0.0
                ; Translate MIDI key number (p4) to frequency in cycles per second.
    ifrequency  =           cpsmidinn(p4)
                ; Translate MIDI velocity value (p5) to amplitude.
    iamplitude  =           ampdb(p5)
                ; Band-limited oscillator with integrated sawtooth wave.
    aout        vco2        iamplitude * kenvelope, ifrequency, 8
                ; Output stereo signal
                outs        aout, aout
                endin	; End the instrument definition.
    '''			; End the orchestra block.

    score = '''		; Begin score block.
    i 1 0 10 68 80	; A Csound score event with five parameters (p-fields).
    '''			; End score block.

    command = 'csound -RWfo toot1.wav toot1.orc toot1.sco' ; Sets command to
                                                           ; run the csound
                                                           ; binary with the
                                                           ; indicated options.
    model = CsoundAC.MusicModel()	; Sets the model to CsoundAC's MusicModel.
    model.setCsoundOrchestra(orchestra) ; Process the orchestra code.
    model.setCsoundScoreHeader(score)   ; Process the score code.
    model.setCsoundCommand(command)      ; Process the string defined in the
                                        ; command statement.

    model.render()			; Render the embedded Csound code.

Csound 部分在原始示例代码中得到了充分的文档记录。我为我们这些不懂 Python 的人添加了一些解释性材料。

该练习将 Csound 代码嵌入到 Python 框架中,该框架会将代码编译成名为 toot1.wav 的 WAV 文件。经验丰富的 Csound 用户会识别出该示例的很大一部分。从 sr(采样率)定义到 endin(结束乐器定义)标记的所有内容都是未更改的 Csound 代码。单行乐谱 (i 1 0 10 68 80 同样是纯 Csound,而示例中的其他所有内容都是 Python 代码。三引号 (''') 本质上将 Csound 代码块转换为定义为 orchestrascore 的变量。然后将这些变量提供给 model 代码,以生成锯齿波形的 WAV 格式文件,该波形以每秒 440 周(又名 A440)的音高播放 10 秒(在乐谱行中定义)。顺便说一句,如果您从未用 Python 编程过,您需要知道该语言对缩进和代码块排列很敏感。空格是有意义的,忽略它们会自食其果。

经验丰富的 Csound 用户可能会注意到,可以重新编写 command 定义以从示例中生成实时输出。我将把这个练习留给勤奋的读者,然后继续使用 CsoundAC 从一些更雄心勃勃的代码创建 MIDI 文件。


高级 CsoundAC

下一个示例建立在第一个练习的基础上,增加了一个用于写入外部乐谱文件的功能。它还用一个公式替换了原始乐谱语句,该公式用于创建由称为 奇异吸引子 的混沌现象产生的值。此示例的大部分内容已从之前的练习中吸收,因此未加注释。以下代码中仅描述了添加的部分

    import CsoundAC
    import string	; Add facility for writing a text file.

    orchestra = '''
    sr = 44100	
    ksmps = 100	
    nchnls = 2	

                instr 1	
    iattack     =           0.005
    idecay      =           0.2
    irelease    =           0.05
    isustain    =           p3
    p3          =           iattack + idecay + isustain + irelease
    kenvelope   transeg     0.0, iattack, -3.0, 1.0, idecay, -3.0, 0.25, \
                            isustain, -3.0, 0.25, irelease, -3.0, 0.0
    ifrequency  =           cpsmidinn(p4)
    iamplitude  =           ampdb(p5)
    aout        vco2        iamplitude * kenvelope, ifrequency, 8
                outs        aout, aout
                endin	
    '''

    r = 3.974		; This block introduces the mathematics
    y = 0.5		; of the attractor. The values produced
    time_ = 0.0		; here are used to create each line
    duration = 0.25	; of the Csound score.
    istatements = []
    for i in xrange(1000):
        y = r * y * (1.0 - y)
        time_ = time_ + duration / 2.0
        midikey = int(36.0 + (y * 60.0))
        istatement = "i 1 %f %f %d 80\n" % (time_, duration, midikey) ; The Csound score event.                                                                                
        print istatement,
        istatements.append(istatement)

    score = string.join(istatements)	; Produce Csound score from events created 
                                        ; by the for loop above.

    command = 'csound -RWfo toot2.wav toot2.orc toot2.sco' 

    model = CsoundAC.MusicModel()
    model.setCsoundOrchestra(orchestra)
    model.setCsoundScoreHeader(score)  
    model.setCsoundCommand(command)    

    model.render()		

在此示例中,练习 1 中的硬编码乐谱事件已被一个例程所取代,该例程用于生成一系列此类事件。吸引子的简单公式提供了用于生成结果 Csound 乐谱每一行的值。与之前的示例一样,乐谱随后由乐器处理,command 指令将输出实现为 WAV 格式的声音文件。您可以在 CsoundAC 教程 #2 音频示例 中收听结果的采样。

要改变此练习的输出,您应该使用不同的吸引子方程值(ry)重新运行它。为了获得更大的节奏变化,您可以编辑 duration 定义的值,甚至用一个函数替换它,以便为每个事件生成不同的值(for 循环中的 istatement)。当然,请务必学习教程的相关部分。


文档

现在应该很明显,进入 CsoundAC 的途径是 Michael 的教程。该文本既是对 CsoundAC 的具体介绍,也是对算法音乐作曲的历史和方法的一般介绍。如果您对 Csound 一无所知,作者还撰写了一篇关于 Csound 的一般介绍,我向新用户推荐。

本教程是对 CsoundAC 的方法和手段的良好介绍,但我希望提供更多的简单示例。幸运的是,通过编辑现有示例,您可以轻松地创建此类练习。随着学生深入系统,本教程的更大价值开始显现,尤其是在其代表作品的选择方面。其中一些作品非常著名——莫扎特的 音乐骰子游戏 和约翰·凯奇的 星图 是通过偶然程序创作音乐的著名例子——而另一些则基于其他作曲家使用各种算法策略创作的著名作品。

顺便说一句,我必须向 Michael Gogins 道歉,因为我从他的教程中挪用了这么多材料。我将通过指出他是一位优秀的作家来使我蹩脚的借口合法化——请参阅 他的博客 以证明——我只是觉得我无法改进他的表达。


R 日快乐,Vercoe 博士!

Barry Vercoe 博士,Csound 的“盛宴创始人”,最近宣布从 麻省理工学院媒体实验室 退休。很难想象没有 Csound 的我的音乐生活,因此我代表世界各地的 Csound 用户向 Vercoe 博士及其众多学生和同事表示衷心的“感谢!”感谢他们为世界上最先进的声音和音乐制作编程环境所做的宝贵工作。祝您退休生活愉快,V 博士,再次感谢 Csound。


结尾

在我的下一篇文章中,我将继续本系列,介绍 Christopher Ariza 的杰作 athenaCL。下次见!

加载 Disqus 评论