1. 产品
  2.   声音的
  3.   C++
  4.   portaudio

portaudio

 
 

开源 C 音频 I/O 库

通过开源 C API 在 Windows、macOS、Linux 等平台实现实时音频输入与输出。

什么是 portaudio?

PortAudio 是一个免费、开源、跨平台的 C 库,使开发者能够编写具有实时输入输出功能的可移植音频应用程序。它抽象了平台特定的音频子系统,如 ASIO、CoreAudio、ALSA、WASAPI 和 JACK,允许在 Windows、macOS、Linux 以及其他操作系统之间实现一致的音频 I/O。该库支持多种音频格式——包括 32 位浮点——并在内部处理格式转换。凭借简洁而强大的 API,PortAudio 被广泛用于音频软件、插件、教育工具以及需要低延迟、高性能音频处理的研究项目。

PortAudio 提供两种主要的操作模式:基于回调的模式(用于低延迟流式传输)和阻塞读/写模式(用于更简单的同步 I/O)。它包含丰富的文档、示例程序和测试工具,帮助开发者快速入门。该库由全球社区维护,并采用 MIT 许可证,使其适用于开源和商业应用。无论您是构建数字音频工作站、语音识别工具,还是交互式音乐应用,PortAudio 都提供可靠、轻量的跨平台音频开发基础。

Previous Next

开始使用 portaudio

要开始使用 PortAudio,您可以从源码构建或通过包管理器安装。对于大多数开发者来说,最简单的方法是克隆官方 portaudio GitHub 仓库,并使用 CMake 或 autotools 编译。在 Linux 上,可通过 `apt install portaudio19-dev` 安装;在 macOS 上,使用 `brew install portaudio`;在 Windows 上,下载预构建二进制文件或使用 vcpkg(`vcpkg install portaudio`)。安装后,包含 `portaudio.h` 并链接库(`-lportaudio`)。该库轻量且依赖最少,使得在实时音频应用中集成变得简单。

通过包管理器安装 PortAudio

# Linux (Debian/Ubuntu)
sudo apt install portaudio19-dev

# macOS (Homebrew)
brew install portaudio

# Windows (vcpkg)
vcpkg install portaudio

使用回调的实时音频流

PortAudio 的基于回调的流模式非常适合低延迟、实时音频处理。当流启动时,PortAudio 会定期调用您的回调函数来请求或提供音频数据。此模式让您对时序拥有精确控制,并将缓冲区欠载降至最低。回调函数会收到输入和输出缓冲区、帧计数、时间信息以及状态标志——从而实现动态音频生成、效果处理或分析。由于回调运行在高优先级线程中,必须快速执行(通常在 10 毫秒以内)以避免卡顿。这使其非常适合合成器、吉他效果踏板或语音通信系统等对确定性性能要求极高的实时音频应用。

通过回调的实时正弦波生成器

typedef struct {
    float phase;
    float phase_increment;
} paTestData;

int patestCallback(const void *input, void *output,
    unsigned long frameCount,
    const PaStreamCallbackTimeInfo* timeInfo,
    PaStreamCallbackFlags statusFlags,
    void *userData)
{
    paTestData *data = (paTestData*)userData;
    float *out = (float*)output;
    for (unsigned long i = 0; i < frameCount; i++) {
        *out++ = sinf(data->phase);
        data->phase += data->phase_increment;
        if (data->phase >= M_PI * 2) data->phase -= M_PI * 2;
    }
    return paContinue;
}

设备枚举与查询

PortAudio 提供强大的 API 来枚举和检查可用的音频设备——包括输入和输出设备——以及它们的功能。开发者可以使用诸如 `Pa_GetDeviceCount()`、`Pa_GetDeviceInfo()` 和 `Pa_GetDefaultInputDeviceID()` 等函数查询设备名称、通道数、默认采样率和延迟值。这使得应用程序能够向用户展示有效设备列表并优化流的配置。您还可以检测默认设备、检查支持的采样率以及确定最小/最大延迟。这种灵活性对于构建可配置的音频工具、数字音频工作站(DAW)或语音录音器至关重要,能够在无需手动配置的情况下适应多样的硬件环境。

列出所有可用的音频设备

PaError err;
err = Pa_Initialize();
if (err != paNoError) goto error;

int numDevices = Pa_GetDeviceCount();
for (int i = 0; i < numDevices; i++) {
    const PaDeviceInfo *info = Pa_GetDeviceInfo(i);
    printf("%d: %s (in: %d, out: %d)\n", 
        i, info->name, 
        info->maxInputChannels, 
        info->maxOutputChannels);
}
Pa_Terminate();

跨平台主机 API 支持

PortAudio 通过模块化的主机 API 实现抽象平台特定的音频 API,确保在不同操作系统之间行为一致。在 Windows 上,它支持 ASIO(专业音频)、WASAPI(Vista 及以上)、DirectSound 和传统的 MME。macOS 利用 Core Audio 实现超低延迟,而 Linux 支持 ALSA、JACK 和 PulseAudio。BSD 系统使用 OSS 或 sndio。开发者只需一次编写即可在各处部署——核心逻辑无需条件编译。库会自动选择最佳可用的主机 API,或允许您显式指定。这种通用性使 PortAudio 成为便携式音频工具、教育软件和必须在多种硬件和操作系统配置上可靠运行的研究框架的理想选择。

在 Linux 上强制使用 JACK 主机 API

PaStreamParameters inputParam, outputParam;
PaError err;

inputParam.device = Pa_GetHostApiInfoByType(paJACK)->defaultInputDevice;
inputParam.channelCount = 2;
inputParam.sampleFormat = paFloat32;
// ... configure outputParam similarly ...

PaStream *stream;
err = Pa_OpenStream(&stream, &inputParam, &outputParam, 
    44100, 256, paNoFlag, callback, NULL);

音频格式转换与抖动

PortAudio 透明地处理内部采样格式转换,使客户端能够使用诸如 32 位浮点等便利格式,而底层系统使用本机整数格式(例如,16 位 PCM)。它支持在 8、16、24 和 32 位整数格式之间以及 32 位浮点之间的转换。此外,它在位深度降低时提供可选的抖动,以最小化量化噪声——这是高保真音频应用中微妙但关键的特性。抖动在从更高位深度转换为更低位深度时保持感知的音频质量。这些功能确保跨平台保持一致的音频保真度,而无需开发者自行实现复杂的格式处理逻辑。

配置带抖动的 32 位浮点输入

PaStreamParameters inputParam = {0};
inputParam.device = Pa_GetDefaultInputDevice();
inputParam.channelCount = 2;
inputParam.sampleFormat = paFloat32;
inputParam.suggestedLatency = Pa_GetDeviceInfo(inputParam.device)->defaultLowInputLatency;

// Enable dithering for output conversion
PaStream *stream;
Pa_OpenStream(&stream, &inputParam, NULL, 44100, 128, 
    paClipOff | paDitherOff, NULL, NULL);
// Note: paDitherOff disables dithering; omit for default dithering
 中国人