从 Rust 中的多个音频流中并行获取相同大小的块

Posted

技术标签:

【中文标题】从 Rust 中的多个音频流中并行获取相同大小的块【英文标题】:Taking equal-sized chunks from multiple audio streams in Rust in parallel 【发布时间】:2019-12-14 21:19:05 【问题描述】:

我正在尝试在 Rust 中编写优雅的音频处理代码,它可以锁步地消耗来自 N 个通道(单声道、立体声或环绕声,在编译时已知)的音频块,减少它们并发送减少的值(或平面映射值)转移到另一个流进行处理。

在 Clojure 中,序列抽象和高阶转换器可以很容易地从流中咬出块并将处理后的结果发布到另一个 core.async 频道,但我正在努力让这个在 Rust 中工作,特别是因为 Rust抱怨泛型迭代器在编译时没有调整大小。

具体来说,我如何以锁步的方式从多个通道中消耗相同大小的音频块,例如计算所有值的平方和,然后用那个值做点什么?我知道横梁。

这是我正在寻找的伪代码:

type Audiosample = f64;
struct Signal<S, const N: usize> 
    sample_rate: f64,
    channels: [Iterator<S>; N], // I know this won't compile


fn process_signal(signal: Signal<AudioSample, 5>) -> f64 
    let mut sum_squared = 0.0;
    let chunk_size = 0.1 * signal.sample_rate; // 100ms of audio from each channel
    for channel in signal.channels   // how to parallelize this blocking call?
        let chunk = channel.take(chunk_size); // assuming this blocks until 100ms of signal is available
        sum_squared += chunk.fold(|0., sample| sample * sample);
    

    sum_squared

如果您能展示一种实用的方法来使 process_signal() 函数“增量”,即对 N 通道异步且可并行化,则可加分。

【问题讨论】:

doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact ?不清楚你想要什么 既然您提到了并行化和阻塞调用:您是否希望“迭代器”在您从中提取数据时从另一个线程接收数据,还是所有这些都是单线程的? 我希望它必须是多线程的,但如果它可以是单线程的,那就太酷了,假设有一种方法可以查看/选择正在填充的 N 个缓冲区硬件中断。 @Stargateur 我想通过从 N 个音频通道中获取相同大小的块来并​​行合并 N 个通道,映射这些块并将它们减少为一个值,该值被发送到其他地方进行处理。该一般问题的任何具体解决方案都可以。如果在编译时不需要知道 N,则额外加分。 我现在找到了这个 DSP 板条箱,它可能更适合我正在尝试做的事情 - 不过还没有尝试过:rustaudio.github.io/dsp-chain/dsp 【参考方案1】:

也许您可以让另一个线程负责处理,而不是尝试同步缓冲区读取?这似乎是一个使用a mpsc channel 的好机会。

由于您可能只能对来自被调用的音频调度程序的回调做出反应,因此如果您尝试在齐声。

【讨论】:

以上是关于从 Rust 中的多个音频流中并行获取相同大小的块的主要内容,如果未能解决你的问题,请参考以下文章

我如何懒惰地从Rust中的文件/流中读取多个JSON值?

如何在从 NodeJS 中的多个输入流中读取时写入单个文件

从文件夹中读取 Java 流中的块中的文件名

在 UWP 中播放流中的音频

如何在服务器上使用 ffmpeg 从 WebRTC 流中获取音频和视频

从 iPhone 上的音频流中获取 Hz 频率