#audio-playback #playback #gamedev #buffer

youtui-vendored-rodio

YOUTUI 的供应商库 - 不要使用

2 个版本

0.19.0-youtui-vendored.22024 年 8 月 3 日

272音频

Download history 331/week @ 2024-07-31 131/week @ 2024-08-07

462 每月下载量
用于 youtui

MIT/Apache

245KB
6.5K SLoC

允许 YOUTUI 发布到 CRATESIO 并带有供应商更改的 CRATE - 不要使用 - 使用 RODIO 代替。


lib.rs:

音频播放库。

该库的主要概念是 Source trait,它表示一个声音(可能是流式或非流式)。要播放一个声音,有三个步骤

  • 创建一个表示流式声音的对象。它可以是一个正弦波、一个缓冲区、一个 decoder,甚至是你自己的实现 Source trait 的类型。
  • 获取一个指向物理设备的输出流句柄。例如,使用 [OutputStream::try_default()] 获取系统默认声音设备的流。
  • 在输出流句柄上调用 .play_raw(source)

play_raw 函数期望源产生 [f32]s,这可能不是情况。如果你得到编译错误,尝试在源上调用 .convert_samples() 来修复它。

例如,以下是播放音频文件的示例

use std::fs::File;
use std::io::BufReader;
use rodio::{Decoder, OutputStream, source::Source};

// Get an output stream handle to the default physical sound device.
// Note that no sound will be played if _stream is dropped
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
// Load a sound from a file, using a path relative to Cargo.toml
let file = BufReader::new(File::open("examples/music.ogg").unwrap());
// Decode that sound file into a source
let source = Decoder::new(file).unwrap();
// Play the sound directly on the device
stream_handle.play_raw(source.convert_samples());

// The sound plays in a separate audio thread,
// so we need to keep the main thread alive while it's playing.
std::thread::sleep(std::time::Duration::from_secs(5));

接收器

为了更容易控制播放,rodio 库还提供了一个名为 Sink 的类型,它表示一个音频轨道。

你不需要使用 play_raw 来播放声音,而是将其添加到 Sink

  • 获取输出流的 Sink,并将你的声音 .append() 添加到它。
use std::fs::File;
use std::io::BufReader;
use std::time::Duration;
use rodio::{Decoder, OutputStream, Sink};
use rodio::source::{SineWave, Source};

// _stream must live as long as the sink
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();

// Add a dummy source of the sake of the example.
let source = SineWave::new(440.0).take_duration(Duration::from_secs_f32(0.25)).amplify(0.20);
sink.append(source);

// The sound plays in a separate thread. This call will block the current thread until the sink
// has finished playing all its queued sounds.
sink.sleep_until_end();

《append`方法将声音添加到接收器的末尾。它将在所有之前的声音播放完毕后播放。如果您想同时播放多个声音,您应该创建多个Sink

Sink类型还提供了播放/暂停或控制音量的实用工具。

请注意,Sink需要OutputStream,确保在接收器之前不会丢弃outputstream。

过滤器

Source特质提供了各种过滤器,类似于标准的Iterator特质。

示例

use rodio::Source;
use std::time::Duration;

// Repeats the first five seconds of the sound forever.
let source = source.take_duration(Duration::from_secs(5)).repeat_infinite();

替代解码后端

Symphonia是一个替代解码库,可以替代许多默认后端。目前,主要好处是Symphonia是唯一支持M4A和AAC的后端,但它可能在未来用于实现额外的可选功能。

要使用,启用symphonia-all功能以启用所有Symphonia编解码器,或使用其中一个symphonia-{codec name}功能来启用特定编解码器。如果您启用了Symphonia编解码器之一或多个,您可能希望设置default-features = false以避免向您的二进制文件添加额外的crate。请参阅所有选项的可用功能标志

内部工作原理

Rodio会启动一个专门用于从源读取并发送输出到设备的后台线程。每次您放弃对Source的所有权以播放它时,它就会被发送到这个后台线程,由rodio读取。

所有声音都由rodio混合在一起,然后发送到操作系统或硬件。因此,同时播放的声音数量或可以创建的接收器数量没有限制(除非创建太多会减慢您的程序)。

依赖关系

~0.7–30MB
~466K SLoC