如何在 Rust 中将 16 位 PCM 音频的采样率从 24000 Hz 更改为 48000 Hz?

问题描述

我从 Google 的文本到语音服务中获取 16 位 PCM 数据(24000 Hz),然后将其存储在 u8 数组中。有没有一种简单的方法可以将其重新采样到 48000 Hz,输出为 u8 阵列?我不明白 FFmpeg 上的任何在线示例。

现在我将它包裹在一个 Cursor 中以单独读取每个 i16,然后将每个 i16 复制一次(即,使 1234 变为 11223344)。我的逻辑是,既然原始音频是 24000,那么加倍就是 48000,对吗?

let mut raw = Cursor::new(raw);
let mut new_samples = Vec::new();

loop {
    match raw.read_i16::<LittleEndian>() {
        Ok(x) => {
            samples.push(x);
            samples.push(x);
        }
        Err(_) => break,}
}

接下来我使用 hound crate 将新样本转换为 48000 WAV。

let mut new_wav = Cursor::new(Vec::new());
let mut writer = WavWriter::new(
    &mut new_wav,WavSpec {
        channels: 1,sample_rate: 48000,bits_per_sample: 16,sample_format: SampleFormat::Int,},)
.unwrap();

new_samples
    .into_iter()
    .for_each(|x| writer.write_sample(x).unwrap());

writer.finalize().unwrap();

现在 new_wav 应该有 48000 Hz 的音频。但这不起作用。当我使用 discord songbird crate 播放它时,我只听到一个非常简短的静电:

call.lock().await.play_source(Input::new(
    false,new_wav.into_inner().into(),Codec::Pcm,Container::Raw,None,));

解决方法

好的,我想通了。我就是这样做的。

let mut original = Cursor::new(original);
let mut resampled = Cursor::new(Vec::new());

loop {
    match original.read_i16::<LittleEndian>() {
        Ok(x) => {
            // Write it twice
            resampled.write_i16::<LittleEndian>(x).unwrap();
            resampled.write_i16::<LittleEndian>(x).unwrap();
        }
        Err(_) => break,}
}

现在“重新采样”为 48000 Hz(并且播放完美)。