Files
songbird/src/input/container/mod.rs
Kyle Simpson 7e4392ae68 Voice Rework -- Events, Track Queues (#806)
This implements a proof-of-concept for an improved audio frontend. The largest change is the introduction of events and event handling: both by time elapsed and by track events, such as ending or looping. Following on from this, the library now includes a basic, event-driven track queue system (which people seem to ask for unusually often). A new sample, `examples/13_voice_events`, demonstrates both the `TrackQueue` system and some basic events via the `~queue` and `~play_fade` commands.

Locks are removed from around the control of `Audio` objects, which should allow the backend to be moved to a more granular futures-based backend solution in a cleaner way.
2020-10-31 12:19:07 +01:00

70 lines
1.7 KiB
Rust

mod frame;
pub use frame::*;
use super::CodecType;
use byteorder::{LittleEndian, ReadBytesExt};
use std::{
fmt::Debug,
io::{Read, Result as IoResult},
mem,
};
/// Marker and state for decoding framed input files.
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub enum Container {
/// Raw, unframed input.
Raw,
/// Framed input, beginning with a JSON header.
///
/// Frames have the form `{ len: i16, payload: [u8; len]}`.
Dca {
/// Byte index of the first frame after the JSON header.
first_frame: usize,
},
}
impl Container {
/// Tries to read the header of the next frame from an input stream.
pub fn next_frame_length(
&mut self,
mut reader: impl Read,
input: CodecType,
) -> IoResult<Frame> {
use Container::*;
match self {
Raw => Ok(Frame {
header_len: 0,
frame_len: input.sample_len(),
}),
Dca { .. } => reader.read_i16::<LittleEndian>().map(|frame_len| Frame {
header_len: mem::size_of::<i16>(),
frame_len: frame_len.max(0) as usize,
}),
}
}
/// Tries to seek on an input directly using sample length, if the input
/// is unframed.
pub fn try_seek_trivial(&self, input: CodecType) -> Option<usize> {
use Container::*;
match self {
Raw => Some(input.sample_len()),
_ => None,
}
}
/// Returns the byte index of the first frame containing audio payload data.
pub fn input_start(&self) -> usize {
use Container::*;
match self {
Raw => 0,
Dca { first_frame } => *first_frame,
}
}
}