initial
This commit is contained in:
86
src/lib.rs
Normal file
86
src/lib.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
use libxm::*;
|
||||
use rodio::{OutputStream, Source, Sink};
|
||||
use std::fs;
|
||||
|
||||
pub const BUFFER_SIZE: usize = 2048;
|
||||
|
||||
/// Example usage
|
||||
/// ```rust
|
||||
/// fn main() {
|
||||
/// let mut xm = libxm::XMContext::new(
|
||||
/// include_bytes!("path/to/file.xm"),
|
||||
/// 48000
|
||||
/// ).expect("failed to parse xm");
|
||||
///
|
||||
/// let (_stream, stream_handle) = rodio::OutputStream::try_default().unwrap();
|
||||
///
|
||||
/// let mut samples: [f32; rodio_xm::BUFFER_SIZE] = [0.0; rodio_xm::BUFFER_SIZE];
|
||||
/// xm.generate_samples(&mut samples);
|
||||
///
|
||||
/// let source = rodio_xm::XMSource::new(xm);
|
||||
/// let sink = rodio::Sink::try_new(&stream_handle).unwrap();
|
||||
///
|
||||
/// sink.append(source);
|
||||
/// sink.sleep_until_end();
|
||||
/// }
|
||||
/// ```
|
||||
pub struct XMSource {
|
||||
xm_context: XMContext,
|
||||
buffer: [f32; BUFFER_SIZE],
|
||||
buffer_index: usize,
|
||||
}
|
||||
|
||||
impl XMSource {
|
||||
pub fn new(xm_context: XMContext) -> Self {
|
||||
XMSource {
|
||||
xm_context,
|
||||
buffer: [0.0; BUFFER_SIZE],
|
||||
buffer_index: 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Self {
|
||||
let xm = libxm::XMContext::new(bytes, 48000)
|
||||
.expect("failed to parse xm");
|
||||
|
||||
self::new(xm)
|
||||
}
|
||||
|
||||
pub fn from_file(path: PathBuf) -> Self {
|
||||
let file = fs::read(path).expect("couldn't read file");
|
||||
let xm = libxm::XMContext::new(file.as_bytes(), 48000)
|
||||
.expect("failed to parse xm");
|
||||
|
||||
self::new(xm)
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for XMSource {
|
||||
fn current_frame_len(&self) -> Option<usize> {
|
||||
Some(BUFFER_SIZE - self.buffer_index)
|
||||
}
|
||||
|
||||
fn channels(&self) -> u16 { 2 }
|
||||
|
||||
fn sample_rate(&self) -> u32 { 48000 }
|
||||
|
||||
fn total_duration(&self) -> Option<Duration> { None }
|
||||
}
|
||||
|
||||
impl Iterator for XMSource {
|
||||
type Item = f32;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.buffer_index += 1;
|
||||
|
||||
if self.buffer_index >= BUFFER_SIZE {
|
||||
self.xm_context.generate_samples(&mut self.buffer);
|
||||
self.buffer_index = 0;
|
||||
}
|
||||
|
||||
Some(self.buffer[self.buffer_index])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user