- 图形学
- 3D渲染
【免费下载链接】goo-engine
Custom build of blender with some extra NPR features.
Audaspace(读作 "outer space")是一个用 C++ 编写、附带 Python 语言绑定的高级音频库,最初作为三维建模应用 Blender 的音频引擎起步,现已作为独立库对外发布。在本仓库 goo-engine(基于 Blender 的定制构建)中,Audaspace 以 extern/audaspace/README.md 所述的方式被内嵌为第三方依赖,并经由 source/blender/blenkernel/intern/sound.cc 等模块的AUD_Sound_*/AUD_Device_*C API 深度集成进 Blender 的音频系统。读完本文,你将掌握 Audaspace 的设备与插件架构、文件读写、滤波器/效果、波形生成、重规格化(respecification)与音频序列编排等全部核心能力,并能直接使用其 Python 绑定写出可运行的播放、音效合成与 3D 定位音频程序。
Audaspace 是什么:源自 Blender 的独立音频库
Audaspace 的设计目标是提供一个"高层"(high level)的音频库:应用开发者不必直接面对各个底层音频后端(ALSA、CoreAudio、WASAPI 等)的差异,而是通过统一的抽象接口完成设备打开、声音播放与播放控制。根据 extern/audaspace/README.md,它:
- 以 C++ 实现,并提供 C 与 Python 语言绑定;
- 发源于 Blender 的音频引擎,如今作为独立库发布;
- 名称发音为 "outer space"(读音近似"外太空")。
在 goo-engine 中,Audaspace 的定位是"内嵌第三方库"而非独立项目,这一点可以从 extern/audaspace/README.blender 得到佐证——该文件记录了上游版本信息(Upstream version: 1.4+,对应 0d18fe7, 2024 Jan 2)与本地修改(Local modifications: JOSResampleReader default quality set to MEDIUM,即把 JOS 重采样器的默认质量档设为 MEDIUM)。同时,extern/audaspace/CMakeLists.txt 声明库版本AUDASPACE_VERSION 1.4,并在非独立构建模式下(AUDASPACE_STANDALONE为 FALSE 时)作为 Blender 的一部分参与整体构建。
在 Blender 侧,source/blender/blenkernel/intern/sound.cc 大量调用 Audaspace 的 C 绑定:例如BKE_sound_new_file经由AUD_Sound_file加载声音文件,BKE_sound_cache使用AUD_Sound_cache建立缓存,BKE_sound_init则通过AUD_DeviceSpecs配置并打开默认音频设备。可以推断,Blender 场景中的音频序列、视频预览播放(source/blender/windowmanager/intern/wm_playanim.cc)等能力都建立在 Audaspace 之上。
底层抽象:ISound / IReader / IDevice / IHandle 四件套
理解 Audaspace 的功能,首先要理解它的四个核心抽象接口,它们构成了"声音描述 → 可读流 → 设备播放 → 播放控制"的完整数据链路:
| 接口 | 头文件 | 职责 |
|---|---|---|
ISound | extern/audaspace/include/ISound.h | 一种声音源的描述,保存必要参数,通过工厂方法createReader()创建可播放的 reader |
IReader | extern/audaspace/include/IReader.h | 可作为流或缓冲被读取的声音源,提供seek、getLength、getPosition、getSpecs与read等接口 |
IDevice | extern/audaspace/include/devices/IDevice.h | 声音输出设备抽象,可对应 SDL、OpenAL 等跨平台后端或平台特定后端,甚至是文件、RAM 缓冲 |
IHandle | extern/audaspace/include/devices/IHandle.h | 一次具体播放的句柄,用于暂停、恢复、停止、定位、调音量、调音高与设置循环等 |
关键设计要点如下:
ISound对象本身只是"声音的描述",不会立即产生声音;只有调用createReader()才会生成真正可读取采样数据的IReader。Python 教程中也特别强调:"At this point nothing is playing back yet, Sound objects are just descriptions of sounds."IReader以"样本数"(samples)为单位描述位置与长度:seek(int position)中从时间(秒)换算到样本数只需乘以采样率;getLength()返回负值表示长度未知。IDevice::play()同时接受std::shared_ptr<IReader>与std::shared_ptr<ISound>两种重载,并可通过keep参数让声音播完后转为暂停而非删除(见 extern/audaspace/include/devices/IDevice.h)。IHandle定义了Status枚举:STATUS_INVALID(句柄失效)、STATUS_PLAYING(播放中)、STATUS_PAUSED(已暂停)、STATUS_STOPPED(已停止但保留在设备中);loop_count为负值表示无限循环;还支持设置stopCallback在播放到达末尾时回调(extern/audaspace/include/devices/IHandle.h)。
核心特性详解
extern/audaspace/README.md 以(可能不完整的)列表形式列出了 Audaspace 支持的功能,下面结合仓库源码逐一展开。
输入 / 输出设备
Audaspace 支持:
- 输入:来自麦克风、line in 等录音设备;
- 输出:包括 3D 音频支持在内的多种输出设备。
在仓库中,设备能力通过插件(plugins)形式提供,见 extern/audaspace/plugins 目录:
openal/:跨平台 OpenAL 输出设备(OpenALDevice),支持 3D 音频定位;pulseaudio/:Linux 下的 PulseAudio 设备,支持运行时动态加载(DYNLOAD_PULSEAUDIO);jack/:专业音频 JACK 设备,同样可动态加载(DYNLOAD_JACK);coreaudio/:macOS 的 CoreAudio 设备,还额外实现了CoreAudioSynchronizer用于精确音画同步;wasapi/:Windows 的 WASAPI 设备;sdl/:跨平台 SDL 输出设备(可选用 SDL2,对应USE_SDL2选项)。
设备打开流程由 extern/audaspace/src/devices/DeviceManager.cpp 承担:DeviceManager::openDefaultDevice()打开系统默认设备,DeviceManager::getDeviceFactory(name)按名称获取指定类型的设备工厂,再通过IDeviceFactory::openDevice()实例化设备。仓库还内置了NULLDevice(静默空设备)、ReadDevice(将设备输出读取回内存)、SoftwareDevice(软件混音)与ThreadedDevice(线程化播放)等参考实现,见 extern/audaspace/src/devices 与 extern/audaspace/CMakeLists.txt。
文件读写
Audaspace 支持音频文件的读取与写入,主要依赖两个文件格式插件:
plugins/ffmpeg/:基于 FFmpeg 的通用媒体读取/写入(FFMPEGReader、FFMPEGWriter),覆盖面广;plugins/libsndfile/:基于 libsndfile 的SndFileReader/SndFileWriter。
文件层的核心实现位于 extern/audaspace/src/file,包括File(按文件名/缓冲创建声音)、FileManager(通过插件查找并解析文件)与FileWriter(写出文件)。在 Python 绑定中对应aud.Sound.file()类方法;在 Blender 中,BKE_sound_new_file与AUD_Sound_bufferFile(从内存缓冲直接加载)都建立在它之上。
滤波器与效果
extern/audaspace/include/fx 与 extern/audaspace/src/fx 提供了丰富的效果处理类,README 中提到的包括:
- 低通 / 高通滤波:
Lowpass、Highpass(均基于 Butterworth 滤波器系数计算,见ButterworthCalculator、Butterworth),以及通用的IIRFilter/DynamicIIRFilter; - 延迟:
Delay(含DelayReader); - 反向播放:
Reverse; - 淡入淡出:
Fader(配合FaderReader); - 音量控制:
Volume/VolumeSound/VolumeStorage(支持"可写入"的渐进式音量存储); - 更多实用效果:
ADSR(包络)、Envelope、Pitch(变调)、Limiter、Threshold、Modulator、Accumulator、Loop、MutableSound、SoundList、Source与Sum等。
以Threshold为例(extern/audaspace/include/fx/Threshold.h),其作用是把任意信号转换为方波:振幅 ≥ 阈值的样本置 1,≤ −阈值置 −1,介于两者之间置 0。它通过CallbackIIRFilterReader的thresholdFilter回调实现,这解释了 README 特性中"滤波器/效果"为何能与"波形生成"组合出丰富的合成音色。
简单波形生成器
extern/audaspace/include/generator 与 extern/audaspace/src/generator 提供了 README 提到的几个基础波形发生器:
Silence:静音;Sine:正弦波(参数为频率与目标采样率,见 extern/audaspace/include/generator/Sine.h);Square:方波;Triangle:三角波;Sawtooth:锯齿波(README 列表中虽未明确写出,但源码已实现)。
在 Python 绑定中,它们以aud.Sound.sine(frequency, rate=48000)、aud.Sound.square(...)、aud.Sound.sawtooth(...)、aud.Sound.triangle(...)、aud.Sound.silence(...)等类方法暴露(见 extern/audaspace/bindings/python/PySound.cpp 的方法表)。Python 文档字符串明确建议:rate参数最好与播放设备的采样率一致,以避免不必要的重采样开销。
重规格化(Respecification)
"重规格化"是 Audaspace 用来描述"改变音频流参数"的术语,覆盖三个维度(README 原述):
- 声道数(channel count):声道重映射,对应 extern/audaspace/src/respec/ChannelMapper.cpp 的
ChannelMapper,可把立体声转单声道、指定各声道到目标声道的映射关系等; - 采样格式(sample format):库内部统一使用 32 位浮点(
sample_t)。extern/audaspace/include/respec/Specification.h 定义了SampleFormat枚举:FORMAT_U8、FORMAT_S16、FORMAT_S24、FORMAT_S32、FORMAT_FLOAT32、FORMAT_FLOAT64,其中格式的低 4 位编码字节数(AUD_FORMAT_SIZE宏)。外部音频文件/设备通常以这些格式输入,库内部统一转为 32 位浮点处理后再按需转出; - 采样率(sample rate):重采样。实现包括
LinearResample(线性插值,低开销)与JOSResample(Julius O. Smith 风格的高质量重采样,按系数表分 High / Medium / Low 三档质量),统一由ResampleReader驱动(extern/audaspace/src/respec)。
值得一提的仓库细节:goo-engine 对 Audaspace 的唯一本地修改就是把JOSResampleReader的默认质量档设为 MEDIUM(记录于 extern/audaspace/README.blender),在保证重采样质量的同时控制了计算开销,读者在使用该库时也可按需调整此档位。
此外,Specification.h还定义了声道布局枚举(CHANNELS_MONO到CHANNELS_SURROUND71)、声道名称枚举(CHANNEL_FRONT_LEFT、CHANNEL_LFE等)以及默认采样率枚举(RATE_8000至RATE_192000),并提供了Specs(源规格:采样率 + 声道数)与DeviceSpecs(设备规格:在源规格基础上增加采样格式)两个核心数据结构。
音频序列编排
README 将序列能力分为两类:
- 简单序列:叠加(superposition,同时播放多路声音并混合)、连接(joining,按顺序先后播放两段声音)与乒乓(ping-pong,即正向播放后接反向播放,等价于"声音 + 其反向"的连接)。对应 extern/audaspace/src/sequence/Superpose.cpp、extern/audaspace/src/sequence/Double.cpp 与 extern/audaspace/src/sequence/PingPong.cpp;
- 复杂序列(非线性音频编辑):
Sequence/SequenceEntry/SequenceData/SequenceHandle体系,支持把多段声音按时间轴位置精确排布、独立控制每条 entry 的播放与静音(extern/audaspace/src/sequence)。
在 Python 绑定中:aud.Sound.join(sound)对应Double,要求两个声音的规格(声道数与采样率)一致;aud.Sound.mix(sound)对应Superpose;aud.Sound.pingpong()对应PingPong(见 extern/audaspace/bindings/python/PySound.cpp 的文档与实现)。aud.Sequence/aud.SequenceEntry则用于时间轴编排。
Python 绑定实战:从简单播放到 3D 定位音效
Audaspace 的 Python 绑定只有少数几个核心类(aud.Device、aud.Sound、aud.Handle,以及aud.Sequence、aud.SequenceEntry),教程文档见 extern/audaspace/bindings/doc/tutorials.rst,完整示例代码位于 extern/audaspace/bindings/python/examples。
1. 极简播放(simple.py)
extern/audaspace/bindings/python/examples/simple.py 完整展示了"打开设备 → 生成声音 → 应用效果 → 播放 → 等待"的全部基本构件:
#!/usr/bin/python import aud, time device = aud.Device() sine = aud.Sound.sine(440) square = sine.threshold() handle = device.play(square) time.sleep(3)要点:
aud.Device()不传参数时打开系统默认设备。其构造参数(见 extern/audaspace/bindings/python/PyDevice.cpp)依次为type(设备类型名,默认自动选择)、rate(采样率,默认 48000)、channels(声道数,默认立体声)、format(采样格式,默认FORMAT_FLOAT32)、buffer_size(缓冲大小,必须 ≥ 128)、name(设备名);aud.Sound.sine(440)只创建 440 Hz 正弦波的"描述",尚未发声;sine.threshold()把正弦波整形为方波——这是 README "滤波器/效果"与"生成器"组合的经典范例(虽然直接aud.Sound.square(440)更高效,但示例意在展示效果链);device.play(square)返回aud.Handle,用于后续播放控制。
2. 简易音乐播放器(player.py)
extern/audaspace/bindings/python/examples/player.py 展示了从文件加载声音并等待播放结束:
#!/usr/bin/python import aud, sys, time device = aud.Device() sound = aud.Sound.file(sys.argv[1]) handle = device.play(sound) while handle.status: time.sleep(0.1)这里aud.Sound.file()即文件读取能力,handle.status属性(对应IHandle::getStatus)在声音播完后变为非真值,循环结束。教程还留下练习:扩展为按顺序播放命令行传入的任意多个文件。
3. 环绕头顶的警报声(siren.py)
extern/audaspace/bindings/python/examples/siren.py 演示了效果链、无限循环与 3D 音频定位:
#!/usr/bin/python import aud, math, time length = 0.5 fadelength = 0.05 device = aud.Device() high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length) low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6) sound = high.join(low) handle = device.play(sound) handle.loop_count = -1 start = time.time() while time.time() - start < 10: angle = time.time() - start handle.location = [math.sin(angle), 0, -math.cos(angle)]技术要点:
- 效果函数返回新的
Sound,因此可以链式调用:limit(截取 0 ~ length 区间)、fadein/fadeout(淡入淡出)、volume(音量,文档建议取值 [0, 1] 以避免削波,见 extern/audaspace/bindings/python/PySound.cpp); high.join(low)把两段 0.5 秒的声音首尾连接成 1 秒的警报音;join要求两声音规格一致;handle.loop_count = -1无限循环;handle.location是三维向量,程序以运行时间驱动角度计算,让声音在 XZ 平面绕听众画圆。立体声至少能听到左右声像移动;在多声道且输出设备支持 3D 音频时效果更明显。教程还提示:正确设置handle.velocity还能触发多普勒效应,对比参考 extern/audaspace/bindings/python/examples/siren2.py。
4. 用 Sequence 编排俄罗斯方块音乐(tetris2.py)
extern/audaspace/bindings/python/examples/tetris2.py 演示了非线性音频编辑:用aud.Sequence按时间轴添加音符,替代"用 join 拼出极端不平衡的二叉树"的做法:
position = 0 sequence = aud.Sequence() # ...解析乐谱循环中... note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength) entry = sequence.add(note, position, position + length, 0) if char == 'p': entry.muted = True position += lengthsequence.add(note, begin, end, skip)返回aud.SequenceEntry,可对其设置muted属性实现休止符静音;最后以sequence.limit(0, position)收尾。相比join链,Sequence的时间轴模型在编排大量音符时更清晰、更易维护。更复杂的完整实现还可参考 extern/audaspace/bindings/python/examples/tetris.py 与 extern/audaspace/bindings/python/examples/tetris3.py。
构建配置与插件体系
Audaspace 使用 CMake 构建(extern/audaspace/CMakeLists.txt),其构建选项同样佐证了 README 的特性列表:
AUDASPACE_STANDALONE:是否作为独立库构建(在本仓库中作为 Blender 依赖时为 FALSE);WITH_C/WITH_PYTHON:是否构建 C / Python 绑定,WITH_PYTHON_MODULE控制 Python 模块(audaspace-py),SEPARATE_C控制 C 绑定是否独立成库;WITH_FFMPEG/WITH_LIBSNDFILE:文件读写插件;WITH_OPENAL/WITH_PULSEAUDIO/WITH_JACK/WITH_SDL/WITH_COREAUDIO/WITH_WASAPI:各类输出设备插件(按平台自动启用对应项,如 macOS 默认 CoreAudio、Windows 默认 WASAPI);WITH_FFTW:启用卷积 / 双耳(binaural)/ HRTF / 均衡器(Equalizer)等进阶功能(对应src/fx下的Convolver、BinauralSound、HRTF、Equalizer等类);WITH_STRICT_DEPENDENCIES:依赖缺失时报错(REQUIRED)而非降级警告;DYNLOAD_JACK/DYNLOAD_PULSEAUDIO:JACK / PulseAudio 插件改为运行时动态加载;BUILD_DEMOS:构建audainfo、audaplay、audaconvert、audaremap、signalgen、randsounds、dynamicmusic、playbackmanager等命令行演示程序。
插件采用"静态注册"机制:STATIC_PLUGIN_CLASS/STATIC_PLUGIN_REGISTER宏把各设备插件注册进PluginManager,既支持独立.so/.dll动态插件,也支持静态链接进主程序。默认插件安装/加载路径在 Unix 上为${CMAKE_INSTALL_PREFIX}/share/audaspace/plugins,Windows/macOS 上为当前目录。
许可证
Audaspace 采用 Apache License 2.0 许可(extern/audaspace/README.md 中的 License 一节),版权归 Jörg Müller 所有(Copyright © 2009-2023)。这与仓库根目录的 COPYING 及 release/license/Apache-2.0.txt 中声明的第三方许可策略一致。使用 Audaspace 源码时,需保留 Apache 2.0 许可证文本并满足其条款(如保留版权声明、显著修改声明等)。
- 图形学
- 3D渲染
【免费下载链接】goo-engine
Custom build of blender with some extra NPR features.
相关推荐
MPV视频编辑功能:快速剪辑与转换教程
MPV视频编辑功能:快速剪辑与转换教程 MPV作为一款轻量级媒体播放器,不仅支持高清视频播放,还隐藏着强大的视频编辑功能。本文将带你探索如何利用MPV实现快速剪
文档教程libopenmpt多平台部署:Windows、Linux与macOS实现方案
libopenmpt多平台部署:Windows、Linux与macOS实现方案 libopenmpt是一款强大的开源模块音乐库,支持在Windows、Linux
React 360 音频播放指南:从环境背景音到 3D 空间化音效的 AudioModule 全解
React 360 音频播放指南:从环境背景音到 3D 空间化音效的 AudioModule 全解 导读 在 React 360 应用中,声音是构建沉浸感不可或
前端3D渲染
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考