AVSynthesis:使用 OpenGL 和 Csound5 融合光与声音

作者:Dave Phillips

声音和图像的艺术结合是一种很常见的现象。电影、电视和各种互联网频道都展示了录制下来的视觉和声音融合的令人愉悦的结果。然而,这些例子通常将声音用作伴奏,也许非常重要,但仍然主要是伴奏。

还有另一种考虑音乐和声音在视频制作中的作用的方式——声音本身影响图像的流动及其转换。虽然这不是一个新颖的概念(参见维基百科关于约翰·惠特尼的条目),但随着计算机在数字声光的录制和编辑中的使用,这种实践已经呈现出新的丰富的可能性。

Jean-Pierre Lemoine 至少从 1990 年代后期就开始探索这些新的可能性。我在我的Linux 音乐与声音之书中介绍了他的 HPKComposer(与 Didiel Debril 合著),该书写于 1999 年,甚至那时 HPKComposer 网页就声明该程序是“...一个用于 Csound 的 3D 艺术创作工具”。当时,作者选择使用虚拟现实建模语言 (VRML) 作为其图形引擎。我可以满足该程序的 Java 要求并使用其 Csound 部分,但我当时无法在 Linux 下使用 VRML。尽管如此,该网站的屏幕截图给我留下了深刻的印象,我希望有一天这样的程序能在 Linux 下变得有用。

让我们转向 Csound 开发人员 Gabriel Maldonado 的工作:他的 Windows 版 CsoundAV 是从规范的 Csound 源代码树的一个真正的分支,但 Gabe 是一个随和的人,他免费向社区提供他所有的代码扩展。规范 Csound 最近的发展促进了某些 CsoundAV 操作码的采用,尽管我们仍在等待将 CsoundAV 操作码包含到 OpenGL 中,这种情况将我们带到了 Jean-Pierre Lemoine 的最新作品,简称为 AVSynthesis(图 1)。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 1. 运行中的 AVSynthesis

AVSynthesis 拥抱并扩展了 HPKComposer 背后的许多设计理念。该程序融合声音和图像,以产生抽象的非具象艺术作品。它用 Java 编写,Csound 仍然是首选的音频引擎,但 VRML 界面已被一组基于 OpenGL 着色语言 (GLSL) 的图像控件所取代。该程序在图像和声音之间创建了根本性的关联和对应关系,利用 Csound 和 OpenGL 的强大功能来任意操纵数字音频和数字图像。

要求和安装

像许多实验性应用程序一样,AVSynthesis 不是一个完美打包的程序,它不能开箱即用。它是一个独特的程序,因此,它有一些独特的 requirements,您的发行版的软件包仓库可能无法满足这些 requirements。构建所需的依赖项并不特别困难,只要您安装了典型的 Linux 开发环境并为您的系统正确配置即可。我在此处包含了编译 Csound 和配置 AVSynthesis 的具体说明,以及关于在 64 位系统上构建应用程序的要求的一些注意事项。

AVSynthesis 需要一组特定的依赖项

  • Java (1.5 或更高版本)

  • LWJGL(轻量级 Java 游戏库)

  • Csound (5.07 或更高版本)

  • OpenGL

在注明版本的地方,版本至关重要,并且每个组件都受其自身的构建先决条件约束。如前所述,Csound 需要一些特别的关注才能与 AVSynthesis 一起使用。

Csound 有其自身的一组必要的依赖项,但此处空间有限,无法完整描述该程序及其 requirements。幸运的是,可以从 www.csounds.com 获得详尽而优秀的文档,因此我在此仅关注编译该程序以与 AVSynthesis 一起使用所需的配置。

以下选项配置和编译 csound 二进制文件,用于双精度浮点运算,并创建 lib_jcsound.so,这是一个 Java “wrapper” 库,用于 Csound 的音频合成和处理服务

scons useDouble=1 install=1 buildPythonOpcodes=1 buildInterfaces=1 
 ↪buildJavaWrapper=1 dynamicCsoundLibrary=1

AVSynthesis 不需要 Python 操作码,但我包含该选项是为了与 Steven Yi 的 blue 一起使用,blue 是一个用于处理 Csound 的极好的环境。此构建配置中的所有其他选项都必须包含在内才能与 AVSynthesis 一起使用。如果构建成功,lib_jcsound.so 库将位于 Csound 源代码树的顶层。安装 Csound (scons install),然后将 lib_jcsound.so 复制到 AVSynthesis native 目录。就这样;您已经完成了 AVSynthesis 音频方面的设置。

OpenGL 和 LWJGL 库提供了界面的视觉组件和风格。各种参数控制屏幕类似于许多基于 OpenGL 的游戏中看到的控制面板,具有视觉效果,例如动画图标和移动透明度——这些优点使程序的外观更加生动,并改善其工作流程。

LWJGL 库带来了一个小小的困难。AVSynthesis 软件包包含 Windows 格式的 DLL 形式的 LWJGL 库,但不包含所需的 native Linux 库(即 .so 格式)。该软件包包含以下 DLL

  • DevIL.dll

  • ILU.dll

  • ILUT.dll

  • _jcsound.dll

  • lwjgl-devil.dll

  • lwjgl.dll

这些文件必须替换为以下 native Linux 等效文件

  • libIL.so

  • libILU.so

  • libILUT.so

  • lib_jcsound.so

  • liblwjgl-devil.so

  • liblwjgl.so

lib_jcsound.so 库来自上面描述的 Csound 构建;其他库来自 LWJGL 二进制软件包(从 lwjgl.org 下载)。唉,64 位用户将需要自己构建和安装 LWJGL 和 IL 库。据我所知,这些库的软件包在 64 位格式中不易获得,但构建它们很简单,除了在配置步骤中添加 --with-pic 之外,不需要任何特殊说明 (./config --with-pic)。构建或下载库后,必须将其复制到 AVSynthesis native 目录。然后,您可以移动或删除 DLL 版本。

Java 和 OpenGL 都不需要任何重建或特殊的运行时选项。这些现在都是常见的软件包,因此如果您尚未安装它们,请调用您的软件包管理器并安装最新版本(Java 必须是 1.5 或更高版本)。AVSynthesis 本身是从 .jar 文件启动的,该文件在 32 位或 64 位环境中同样有效。

除了这些软件 requirements 之外,您的计算机还应该具有快速的 CPU 和能够加速 3D 图形的视频系统。我测试了 AVSynthesis 在两台机器上:一台 32 位机器,配备 AMD64 3800+ CPU(2.4GHz 芯片)和一台 64 位机器,由 AMD64 3200+ CPU (2GHz) 驱动。这两个系统都包含 NVIDIA 显卡(分别为 GeForce 7300GS 和 GeForce 7600GS),xorg.conf 配置为 NVIDIA 的专有 nvidia 驱动程序(即,不是开源 nv 模块)。32 位机器运行基于 OpenSUSE 10.2 的 JAD 发行版,我的 64 位机器运行基于 Debian 的发行版 64 Studio。这两个系统都针对多媒体进行了优化,并包含针对实时性能优化的内核。但是,像 AVSynthesis 这样的程序需要资源,大量的资源,我认为我的机器对于 AVSynthesis 来说相当低端。您的结果可能会有所不同,当然,但为了从该程序获得最佳结果,我建议使用 3GHz CPU、至少 2GB 的 RAM、快速 3D 显卡和大容量快速硬盘。

我还建议使用高质量的音频系统。廉价的桌面扬声器阵列可能适合观看 DVD,但 Csound 能够输出发烧友级别的音频,因此您需要一个与您的图形系统一样强大的声音系统。在 Dave 工作室,我将我的 JAD 盒子连接到一个相对低端的 5.1 声道系统(Creative Labs 和 Peavey 硬件的组合),而 64 Studio 机器则连接到一个传统的带有 Yamaha 数字调音台、独立 100 瓦功率放大器和一对高质量监听扬声器的小型工作室音频系统。

AVSynthesis 入门

现在我们可以开始使用 AVSynthesis 了。首先,编辑 data/config.xml 文件,以设置 Csound 和 OpenGL 的运行时选项。我添加了这些选项,以设置 Csound 以便与 JACK 音频服务器一起运行,并为我的屏幕尺寸和视频帧率配置 OpenGL

<config csound="-+rtaudio=jack -+rtmidi=portmidi 
 ↪--expression-opt -odac:alsa_pcm:playback_ -d -m0 -g -f 
 ↪-M0 -b1024 temp.orc temp.sco" ksmps="16" width="1280" 
 ↪height="1024" fullscreen="false" FPS="30"/>

如果 Csound 未使用 JACK 或 PortMIDI 支持编译,则必须使用其他选项。有关其他启动和运行时选项的信息,请参阅 Csound 文档。

接下来,我使用以下命令准备了 Csound 和 Java 环境

export OPCODEDIR64=/usr/local/lib/csound/plugins64/
export PATH=$PATH:/home/dlphilp/jdk16/:/home/dlphilp/jdk16/bin/

这些命令可以添加到您主目录的 .bashrc 文件中,以自动化此步骤。

接下来,我使用 QJackCtl 配置并启动 JACK 音频服务器。如果您不使用 JACK,则此步骤是不必要的,但我建议这样做以获得最佳延迟。

最后,我可以启动程序了

cd $HOME/AVSynthesis
java -Xmx768m -Djava.library.path=./native -cp 
 ↪AVSynthesis.jar:./lib/*  org.hpk.av.AVSynthesis

此命令调用 Java,为其设置内存量,将 Java 库路径指向 AVSynthesis/native 目录,声明 classpath (-cp),从顶层目录和 lib 目录加载所需的 .jar 文件,并启动应用程序。顺便说一句,末尾的神秘字符串在 AVSynthesis jar 文件中。我知道这是一种奇怪的启动应用程序的方式,但 Java 可能就是这样。

工作原理

AVSynthesis 接受两个或多个 PNG 或 JPG 图像,将它们混合在动画序列中,并使用 OpenGL 着色语言实现的各种变换处理该序列。同时,程序创建与视频序列遵循相同时间线的音轨。音轨本身可能会受到 Csound 提供的合成、处理和合成算法的重度处理。在 AVSynthesis 的术语中,声音和图像的这种组合称为图层。顺便说一句,您可以将您自己的 PNG 和 JPG 图像添加到 AVSynthesis data/textures 目录,并且可以将您自己的声音文件添加到 data/loops 目录(用于 Csound 循环乐器生成器处理)。

鉴于本文的空间限制,不可能完全描述对图像和声音处理器的各种控制。仅考虑音频部分的这种可能情况:每个图层最多可以使用三个声源,每个声源是五种生成器类型之一,并且每个生成器的声音可以通过最多三个音频信号处理器进一步修改。每个处理器是 13 种类型之一。合成器和处理器中的几乎每个参数都可以通过八条包络曲线之一进行调制,并且每条曲线也会受到其时间跨度修改的影响。如您所见,它是复杂性中的复杂性,我甚至还没有考虑音序器和混音器添加的可能性。

让我描述一个简单的项目——一个演示 AVSynthesis 基础知识的练习。请注意,我的描述仅触及该程序的表面,只有在实际操作中才能看到和听到它的全部功能。我在“资源”部分中提供了指向一些演示文件的链接,但它们仅暗示了可能性。更糟糕的是,必要的视频压缩编解码器对 AVSynthesis 实时性能的生动清晰度并不友好。考虑到这些事实,让我们继续进行该项目。

合成编辑器,第 1 部分

AVSynthesis 打开到合成编辑器,这是程序的最高级别。此屏幕类似于数字音频多轨录音机中的轨道显示,但此处的轨道仅执行一项任务。每个轨道是一个时间线,分为 30 个十秒部分,每个部分包含一个简单三阶段线段包络的一个阶段,该包络控制轨道的图层的可见性和相应的音频音量。正如我们将看到的,此包络本身可能会被程序中其他地方工作的因素修改。

没有文本标签或工具提示描述“合成”屏幕的各种功能,因此用户必须记住它们的含义和目的。幸运的是,此屏幕上的功能相对较少。图 2 定义了其他屏幕元素,其中大多数与性能控制和保存/加载功能有关。稍后,我们将更仔细地考虑其中的一些,但首先,让我们制作一部带有声音的电影。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 2. 合成屏幕布局

图层编辑器

图 3 显示了一个默认的空图层。当鼠标指针停留在图层图像上时,会出现一个透明的覆盖层,其中包含用于管理图层的各种控件。单击覆盖层左下角的图标以调用图 4 中所示的“图层编辑器”。屏幕截图顶部的图标从左到右分别表示:变换后的图像、基础图像选择器、调制图像选择器、GL 着色器效果编辑器、包络曲线编辑器和音频系统编辑器。让我们从选择我们的基础图像和调制器图像开始制作电影,以创建一个用于 GL 着色器处理的图像。接下来,单击该图像(它是顶部三个图像中最大的一个)以调用 GLSL 着色器选择器,然后为您的混合图像设置光源、对比度和效果处理器。每个着色器都有自己的一组性能控件,其中一些控件是所有着色器共有的,而另一些控件是您选择的特定效果所独有的。图 4 显示了添加 Wobble 着色器后此类过程的结果。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 3. 空白图层

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 4. 图层编辑器

此时,您可以调用 GL 着色器编辑器以进一步微调变换。请注意,混合图像上显示的透明度包括一个播放控件,用于在过程中的任何时候测试您稍后的变换,因此可以随意弯曲、折叠、装订和损坏到任何必要的程度。设置约束范围,应用包络曲线并指定单个值。实验,实验,再实验。但是,请注意,AVSynthesis 缺乏安全措施,因此请经常保存您的工作。也没有撤消/重做,除了在您决定退出程序时,您不会收到任何警告。

图 5 显示了 Wobble 效果的控制面板。着色器的独特控件位于面板底部,包括一个启动滑块和两个滑块,分别用于控制效果的频率和幅度参数。其余控件(如前所述)是所有着色器共有的。它们包括纹理管理器、透明度滑块、颜色控件以及眼睛和光源定位器。这些公共控件可以通过特定着色器所需的扩展来增强。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 5. GL 着色器控件

参数值可以使用其滑块显式设置,或者您可以使用约束蒙版(图 5 中显示的黑色和灰色条)定义值范围,以将可能的值限制为仅蒙版覆盖的范围。此范围可以通过在“曲线”屏幕中定义的包络之一进一步修改。

音频系统

图 4 右上角的图标调用 AVSynthesis 音频系统编辑器。选择该图标后,屏幕左侧会出现一列新图标(图 6)。从上到下,这些图标分别表示:音频音序器、三个合成器、三个处理模块和音频混音器。它们都是 AVSynthesis 中 Csound 引擎的外部表示。我们将依次考虑这些组件中的每一个,但只是简要地考虑一下。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 6. AVSynthesis 音序器

音序器管理声音和视频变换演变的时间流。较低的值表示较慢的速度,较高的值使事物发生得更快。但是,时间扭曲的可能性在 AVSynthesis 中很普遍,并且准确预测作品将持续多长时间并不总是那么简单。

合成、处理和混合屏幕中的控件的行为与它们的视频对应物完全相同(图 7)。值使用滑块和蒙版定义,包络可以放置在范围上,等等。

AVSynthesis: Blending Light and Sound with OpenGL and Csound5

图 7. Csound 合成器

顺便说一句,Csound 的部署对普通用户是完全隐藏的,并且使用 AVSynthesis 不需要事先了解 Csound 或任何其他编程语言。

测试播放功能也在此处可用。当您对声音感到满意时,保存图层,然后单击合成编辑器的小图像(位于“图层编辑器”的左上角)以返回到该屏幕。

合成编辑器,第 2 部分

在做任何其他事情之前,使用“保存部分/表演”按钮(图 2)保存您的表演及其所有部分。最多可以保存十个表演,每个表演包含十个部分,每个部分最多包含 13 个图层。现在,只需将您的工作保存到其起始位置(例如,表演 0,部分 3)。

您的轨道现在由其图层的混合图像表示。接下来,我们需要在轨道时间线中添加性能曲线。在轨道部分顶部附近单击鼠标左键以设置曲线的峰值,在底部附近单击鼠标左键以设置零值。包络曲线仅提供固定长度的上升和衰减段,但您可以单击并拖动以设置峰值和零值段的任意长度(图 1)。好的,我们已经定义了我们的视觉和音频元素及其变换,我们在合成时间线中设置了性能曲线,因此我们已准备好将 AVSynthesis 置于其性能模式之一。

“合成”屏幕右下角的方形按钮表示程序的三个性能模式。最右边的按钮打开渲染模式,中间的方块将 AVSynthesis 置于 MIDI 控制模式,左边的按钮切换实时性能模式。

实时模式在合成屏幕时间线上播放图层及其关联曲线的排列。单击该按钮,您的作品将实时播放。单击合成屏幕中的任意位置以停止播放。如果发生错误,AVSynthesis 可能会在您的终端窗口中打印一些相关信息,或者它可能会在没有显示或声音的情况下运行,直到您单击停止播放。或者,它可能会完全崩溃并冻结您的系统。正如我所说,它是实验性软件,因此这些事情会发生。

当选择 MIDI 性能模式时,MIDI 连续控制器 #85 可用作合成屏幕实时性能期间的图层衰减器。输入端口由 AVSynthesis config.xml 文件中指定的 Csound 选项指定。在上面的示例中,-M0 选项将输入端口设置为 ALSA MIDI Thru 端口。

我通过将音序器连接到 QJackCtl 的 MIDI 连接面板中的 MIDI Thru 端口来测试 MIDI 控制。我为控制器 #85 使用了顺序值和随机值的循环,一切都完美运行。实现是有限的,但它为更有趣的实时性能控制指明了方向,例如图层消隐和突然出现。这种 MIDI 控制仅扩展到图层的视频部分;它不影响音频部分。

渲染模式以慢于实时的速度在“合成”屏幕中运行排列,以生成每个视频帧一个 TGA 图像文件。帧率在 data/config.xml 文件中设置(见上文),作者建议将其保留为默认值每秒 30 帧。因此,在默认帧率下,每秒您的作品将创建 30 个图像文件。这些文件可以编译成动画(见下文)。同时,Csound 的输出被捕获到可以添加到动画的声音文件(data 目录中的 render.wav)中。

由于某种原因,渲染模式每个会话只能工作一次。如果您想录制另一个镜头,请保存您的工作并重新打开程序。希望此限制将在未来版本中删除。

顺便说一句,“全屏”、“保存表演/部分”、“实时性能”和“MIDI 模式”按钮在 AVSynthesis 中的所有屏幕上都可用。

制作电影

AVSynthesis 不会直接创建电影。当您单击“渲染”按钮时,程序会创建一系列大小统一的图像文件(每个约 4MB),并且文件数量可能很大。您将需要一个视频编码程序来将这些静态图像转换为流畅的动画。以下说明使用 MPlayer 项目中的 MEncoder,但任何其他视频编码器都应该可以工作,只要它能够将静态 TGA 图像转换为电影即可。

第一步是将 TGA 文件排序为编号列表。如果您的编码器按以下顺序读取 TGA 文件,则此步骤是必要的:1.tga、10.tga、100.tga、1000.tga、1001.tga...101.tga、1010.tga、1011.tga 等等。

按该顺序编码文件会导致图像以原始顺序渲染出来。我们需要按以下顺序对它们进行编码:1.tga、2.tga、3.tga、4.tga 等等。

我询问了 Linux 音频用户邮件列表上的专家他们将如何解决这个令人恼火的困境。提出了各种解决方案,其中最吸引人的是 Wolfgang Woehl 的这个优雅的修复方案

cd data/render
find *tga | sort -n > list

然后可以使用 MEncoder 处理列表文件。

正如我所提到的,Csound 音频输出保存在 AVSynthesis data 目录中名为 render.wav 的单独音频文件中。默认情况下,此文件是采样率为 44.1kHz 的 16 位立体声 WAV 文件——即 CD 质量的声音文件。除非您想重命名它,否则它不需要特别注意。

现在,我们准备编码我们的图像和声音文件。鉴于 TGA 图像的数量可能很大,编码器可能会生成非常大的视频文件,即使是相对较短的动画也可能消耗数十 GB 的存储空间。我们需要考虑一种压缩方案来减小文件大小。

我发现了两种使用 MEncoder 从我的音频和视频数据创建压缩 AVI 的方法。第一种方法使用多遍方法

mencoder -ovc lavc -lavcopts vcodec=huffyuv:pred=2:format
↪=422P:vstrict=-1 -noskip -mf fps=30 -o master.avi mf://@list
mencoder -ovc lavc -lavcopts vcodec=mpeg4:vme=1:keyint
↪=25:vbitrate=1000:vpass=1 -noskip -o foo.avi master.avi
mencoder -oac copy -audiofile ../render.wav -ovc lavc -lavcopts 
 ↪vcodec=mpeg4:vme=1:keyint=25:vbitrate=1000:vpass=2 
 ↪-noskip -o foo.avi master.avi

第一步创建一个巨大的主文件,然后对其进行两遍缩减方案处理,该方案在第二遍中添加音频数据。

这种单遍方法也会创建一个大文件,但它具有生产速度更快的优势

mencoder -oac copy -audiofile ../render.wav -ovc lavc 
 ↪-lavcopts vcodec=mpeg4:vme=1:keyint=30:vbitrate=1000 
 ↪-vf scale=800:600 -noskip -mf type=tga:fps=30 -o 
 ↪avs-001.avi mf://@list

如所示,此方法将电影显示大小设置为 800x600。比例参数也可以包含在多遍示例中的第二步或第三步中,并且如果您的系统抱怨创建大型电影,则实际上可能是必要的。

我已将三个示例 AVI 在线放置在 linux-sound.org/avs-examples。每个动画都演示了单个 GL 着色器(例如,wobble.avi)、最简单的 Csound 音频设置(一个合成器、一个信号处理器)以及音序器的(大部分)默认值可能产生的某些效果。唉,压缩后的视频只能暗示 AVSynthesis 实时执行的视觉美感,它们仅仅作为对该程序艺术潜力的惊鸿一瞥而提供。

已知问题

AVSynthesis config.xml 文件包含用于更改程序窗口大小的条目。AVSynthesis 默认为当前屏幕设置,如果无法验证配置文件中给出的尺寸,则将无法启动。唉,我无法在除我的默认尺寸 (1280x1024) 之外的任何屏幕模式下启动程序。

Csound 相位声码器操作码非常占用 CPU 资源。当我使用基于这些操作码的效果时,AVSynthesis 会随机崩溃,尽管它在其他时候使用它们可以正常工作。

render.wav 文件和 data/render 目录必须由用户清除;AVSynthesis 将覆盖当前内容。

当使用 Analog Synth 2 和 Wild Grain 处理器时,声音可能会失真。使用混音器平衡来自合成器的音频输出。

总结

AVSynthesis 非常值得为实现它而付出的努力。我越深入了解 AVSynthesis,我就越发现更多值得进一步探索的可能性,我可以看到(和听到)自己会在相当长的一段时间内继续参与该程序。该程序的作者已声明他打算消除剩余的错误并添加一些新功能,但他希望尽可能保持 AVSynthesis 的简洁。您可以自己查看最新版本,并且在本文的帮助下,您应该可以在 Linux 下快速流畅地运行 AVSynthesis。玩得开心,发挥创造力,并务必让 Jean-Pierre 知道您是如何使用他的软件的。

资源

AVSynthesis: avsynthesis.blogspot.com

我的 AVSynthesis 示例: linux-sound.org/avs-examples

Csound: www.csounds.com

OpenGL: www.opengl.org

CsoundAV: www.csounds.com/csoundav

MPlayer: www.mplayerhq.hu

Dave Phillips 是一位居住在俄亥俄州芬德利的专业音乐家和作家。他自 1990 年代中期以来一直在使用 Linux,并且是 Linux 音频开发者小组的最初创始人之一。他是Linux 音乐与声音之书(No Starch Press,2000 年)的作者,并为各种期刊和在线新闻网站撰写了许多关于 Linux 音乐和声音问题的文章。当他不玩弄光和声音时,他喜欢阅读拉丁文学、练习太极拳、追逐沙皮幼犬以及与他心爱的常春藤共度时光。

加载 Disqus 评论