This commit is contained in:
2021-04-30 18:12:13 +01:00
commit 129486f2b0
4 changed files with 988 additions and 0 deletions

86
src/lib.rs Normal file
View 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])
}
}