#android #api-bindings #aaudio #opensles

oboe

为Android库Oboe提供的低延迟音频I/O的安全接口

14个版本

0.6.1 2024年3月3日
0.5.0 2023年1月17日
0.4.6 2022年4月30日
0.4.5 2022年1月11日
0.1.0 2020年1月7日

#13 in 音频

Download history 18648/week @ 2024-04-07 20581/week @ 2024-04-14 19195/week @ 2024-04-21 21731/week @ 2024-04-28 21114/week @ 2024-05-05 20749/week @ 2024-05-12 30390/week @ 2024-05-19 28872/week @ 2024-05-26 32312/week @ 2024-06-02 29391/week @ 2024-06-09 32059/week @ 2024-06-16 30899/week @ 2024-06-23 25871/week @ 2024-06-30 21724/week @ 2024-07-07 21602/week @ 2024-07-14 21524/week @ 2024-07-21

92,994 每月下载量
511 个Crate (2 直接) 中使用

Apache-2.0

745KB
14K SLoC

Rust 9K SLoC // 0.1% comments C++ 5.5K SLoC // 0.2% comments

Oboe库的Rust绑定

github Crates.io Package Docs.rs API Docs License: Apache-2.0 CI Status

Oboe提供安全Rust接口,它是Android上的高性能音频库。它还提供了对一些对音频I/O重要的平台API的接口。

Oboe是一个C++库,使得在Android上构建高性能音频应用变得简单。它主要是为了允许开发人员针对一个简化API,该API可以在多个API级别上工作,直到API级别16(Jelly Bean)。

Crate特性

  • java-interface 为某些Android平台API添加接口。
  • generate-bindings 在编译时生成绑定。默认情况下,将使用预生成的绑定。
  • compile-library 使用cmake在编译时编译oboe C++库。默认情况下,将使用预编译的库。
  • shared-link 使用共享链接。默认情况下,将使用静态Oboe库。

该Crate已为以下Android目标预生成绑定和预编译静态库

  • armv7
  • aarch64
  • i686
  • x86_64

构建问题

clang-sys Crate使用llvm-config来搜索libclang库并为C/C++编译器配置准备。为了获得正确的设置,您应该将llvm-config添加到您的可执行文件搜索路径中。

如果您使用的是像bindgen这样的底层使用libclang的工具,您必须确保您的设置正确。否则,您将遇到与缺失头文件或定义相关的错误。

为了构建应用程序,您需要一个最新的cargo-apk版本,它支持最新的Android SDK (28+) 和 NDK (20+)。不要忘记使用安装的SDK路径设置ANDROID_SDK_ROOT环境变量。

对于需要C编译器的宿主Crate的构建,您也可以设置HOST_CC环境变量,以C编译器的路径。

使用示例

异步(回调驱动)模式播放正弦波

use oboe::{
    AudioOutputCallback,
    AudioOutputStream,
    AudioStreamBuilder,
    DataCallbackResult,
    PerformanceMode,
    SharingMode,
    Mono,
};

// Structure for sound generator
pub struct SineWave {
    frequency: f32,
    gain: f32,
    phase: f32,
    delta: Option<f32>,
}

// Default constructor for sound generator
impl Default for SineWave {
    fn default() -> Self {
        Self {
            frequency: 440.0,
            gain: 0.5,
            phase: 0.0,
            delta: None,
        }
    }
}

// Audio output callback trait implementation
impl AudioOutputCallback for SineWave {
    // Define type for frames which we would like to process
    type FrameType = (f32, Mono);

    // Implement sound data output callback
    fn on_audio_ready(&mut self, stream: &mut dyn AudioOutputStream, frames: &mut [f32]) -> DataCallbackResult {
        // Configure out wave generator
        if self.delta.is_none() {
            let sample_rate = stream.get_sample_rate() as f32;
            self.delta = (self.frequency * 2.0 * PI / sample_rate).into();
            println!("Prepare sine wave generator: samplerate={}, time delta={}", sample_rate, self.delta.unwrap());
        }

        let delta = self.delta.unwrap();

        // Generate audio frames to fill the output buffer
        for frame in frames {
            *frame = self.gain * self.phase.sin();
            self.phase += delta;
            while self.phase > 2.0 * PI {
                self.phase -= 2.0 * PI;
            }
        }

        // Notify the oboe that stream is continued
        DataCallbackResult::Continue
    }
}

// ...

// Create playback stream
let mut sine = AudioStreamBuilder::default()
    // select desired performance mode
    .set_performance_mode(PerformanceMode::LowLatency)
    // select desired sharing mode
    .set_sharing_mode(SharingMode::Shared)
    // select sound sample format
    .set_format::<f32>()
    // select channels configuration
    .set_channel_count::<Mono>()
    // set our generator as callback
    .set_callback(SineWave::default())
    // open the output stream
    .open_stream()
    .unwrap();

// Start playback
sine.start().unwrap();

// ...

依赖关系

~0.4–9MB
~91K SLoC