を使用してWAVファイルを再生しようとしていますrust-sdl2
。
私は見つけました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 }
}
}
}
}
...しかし、次のエラーを回避する方法がわかりません。
the traitcore::marker::Sync is not implemented for the type *mut u8
これはのaudio_buf
フィールドのようですAudioSpecWAV
が、そうでない場合Sync
は、コールバックにバッファを渡すことになっていますか?
(参考までに、生成されたサウンドを再生する例を示します)
AudioCallback
実装者はである必要がありますSend
。これを行うにAudioSpecWAV
は、構造体をラップしてその構造体unsafe impl
に対してforを実行するSend
か、データをコピーします。自分が行っていることが実際に安全であることがわかっていない限り、通常は安全でないものを使用するべきではないため、コピーアプローチを検討することをお勧めします。
両方のアプローチの例を次に示します。
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ファイルと関係があるかどうかはわかりません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加