【CPAL 使用笔记 ③】Stream 音频流处理详解

前篇导航:【CPAL 使用笔记 ②】制作一个振荡器(一)(http://t.csdnimg.cn/qu1F5)]

在继续振荡器的制作之前,我们需要对音频流的处理深入学习

预备知识

帧(frame)

一帧音频数据是指在一个时间点上所有声道(Channel)的采样值(Sample)集合。比如对于立体声系统,一帧可能包含两个样本(左声道一个,右声道一个)。

如何发送音频流数据?

build_output_stream

fn build_output_stream<T, D, E> (
	&self,
	config: &StreamConfig,
	data_callback: D,
	error_callback: E,
	timeout: Option<Duration>
) -> Result<Self::Stream, BuildStreamError>
where
	T: SizedSample,
	D: FnMut(&mut [T], &OutputCallbackInfo + Send + 'static),
	E: FnMut(StreamError) + Send + 'static,

以上是 build_output_stream() 的签名,不难发现,音频数据的处理交给了 error_callback 这个闭包。

data_callback

这个参数要求传入一个闭包,我们的处理逻辑全交给了这里。我们主要关心第一个参数 &mut [SizedSample] 这个参数传入一个包含一个缓冲区所有采样的数组。在这里采样实际上就是一个数,它具体是哪个类型(如 f32f64)取决于该输出流配置。例如如果你的输出流配置为 SampleFormat::F32 格式,那么你在 data_callback 中处理的缓冲区中的每个元素都是 f32 类型的,便可以直接对其进行赋值操作以修改音频数据。

当涉及到多个声道时,我们在某个时刻实际上处理的是是一帧的信号。此时 &mut [SizedSample] 便以通道数为步长来组织数据。比如说一个双声道音频流,我们按2个为一组划分采样数组,其中每一组的第一个值代表左声道,第二个代表右声道。

以代码为例:

for frame in sample_data.chunks_mut(num_channels) { // 以声道数为步长遍历数据
	// value = ...    // 计算值
	for sample in frame.iter_mut() {  // 遍历声道
		//*sample = ...    // 修改值(通过对 sample 解引用)
	}
}

综上所述,每当音频设备需要更多数据时,就会调用该闭包并传递一个新的缓冲区。通过修改缓冲区内的样本值,即可实现对音频数据的发送或处理。

有了这个框架,我们就可以随心所欲地传输数据啦!

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值