gpt4 book ai didi

audio - 如何使用 Rust SDL2 播放 WAV 文件?

转载 作者:行者123 更新时间:2023-11-29 07:55:36 34 4
gpt4 key购买 nike

我正在尝试使用 rust-sdl2 播放 WAV 文件.

我找到了 AudioSpecWAV , 但似乎没有一个音频初始化方法将它作为一种类型,并且它没有实现 AudioCallback。我尝试用我自己的回调自己实现这个,看起来像:

struct MyWav {
wav: AudioSpecWAV,
volume: f32,
pos: usize,
}

impl AudioCallback for MyWav {
type Channel = f32;

fn callback(&mut self, out: &mut [f32]) {
for x in out.iter_mut() {
*x = match self.wav.buffer().get(self.pos) {
Some(v) => { self.pos += 1; v as f32 },
None => { 0.0 }
}
}
}
}

...但我不知道如何解决我收到的以下错误:

traitcore::marker::Sync 没有为 *mut u8 类型实现

这似乎是 AudioSpecWAVaudio_buf 字段,但如果不是 Sync 我应该如何将缓冲区传递给回调?

(供引用,here is an example of playing a generated sound)

最佳答案

AudioCallback 要求实现者发送。您可以通过将 AudioSpecWAV 包装在结构中并为该结构上的 Send 执行 unsafe impl 来实现,或者您可以复制数据。由于您通常不应该使用 unsafe 除非您知道您正在做的事情实际上是安全的,因此您可能需要查看复制方法。

这是两种方法的示例:

extern crate sdl2;

use std::thread::{self};

use sdl2::{Sdl};
use sdl2::audio::{self, AudioSpecDesired, AudioSpecWAV, AudioCallback, AudioDevice};

//----------------------------------------------------------------------------//

struct CopiedData {
bytes: Vec<u8>,
position: usize
}

impl AudioCallback for CopiedData {
type Channel = u8;

fn callback(&mut self, data: &mut [u8]) {
let (start, end) = (self.position, self.position + data.len());
self.position += data.len();

let audio_data = &self.bytes[start..end];
for (src, dst) in audio_data.iter().zip(data.iter_mut()) {
*dst = *src;
}
}
}

//----------------------------------------------------------------------------//

struct WrappedData {
audio: AudioSpecWAV,
position: usize
}

impl AudioCallback for WrappedData {
type Channel = u8;

fn callback(&mut self, data: &mut [u8]) {
let (start, end) = (self.position, self.position + data.len());
self.position += data.len();

let audio_data = &self.audio.buffer()[start..end];
for (src, dst) in audio_data.iter().zip(data.iter_mut()) {
*dst = *src;
}
}
}

unsafe impl Send for WrappedData { }

//----------------------------------------------------------------------------//

pub fn main() {
let sdl_context = sdl2::init().unwrap();
let audio_system = sdl_context.audio().unwrap();

let audio_spec = AudioSpecDesired{ freq: None, channels: None, samples: None };
let audio_wav = AudioSpecWAV::load_wav("test.wav").unwrap();

let copied_data = CopiedData{ bytes: audio_wav.buffer().to_vec(), position: 0 };
//let wrapped_data = WrappedData{ audio: audio_wav, position: 0 };

let audio_device = audio_system.open_playback(None, audio_spec, move |spec| {
copied_data
}).unwrap();

audio_device.resume();

thread::sleep_ms(5000);
}

注意:我播放的 WAV 声音很大(到了听起来失真的地步)而且我不是一个声音专家所以我不确定这是否与我的代码或我使用的 WAV 文件有关一般而言。

关于audio - 如何使用 Rust SDL2 播放 WAV 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33057198/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com