use std::{
num::{NonZeroU32, NonZeroUsize},
sync::Arc,
time::Duration,
};
pub use kithara_decode::{DecodeError, DecodeResult};
use kithara_decode::{PcmChunk, PcmSpec, TrackMetadata};
use kithara_events::EventBus;
use kithara_platform::tokio as platform_tokio;
use platform_tokio::sync::Notify;
mod kithara {
pub(crate) use kithara_test_macros::mock;
}
use crate::ServiceClass;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum PendingReason {
Buffering,
SeekInProgress,
StreamBackpressure,
}
#[kithara::mock(api = AudioEffectMock)]
pub trait AudioEffect: Send + 'static {
fn flush(&mut self) -> Option<PcmChunk>;
fn process(&mut self, chunk: PcmChunk) -> Option<PcmChunk>;
fn reset(&mut self);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadOutcome {
Frames {
count: NonZeroUsize,
position: Duration,
},
Pending {
reason: PendingReason,
position: Duration,
},
Eof { position: Duration },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SeekOutcome {
Landed {
target: Duration,
landed_at: Duration,
},
PastEof {
target: Duration,
duration: Duration,
},
}
#[derive(Debug)]
pub enum ChunkOutcome {
Chunk(PcmChunk),
Pending {
reason: PendingReason,
position: Duration,
},
Eof { position: Duration },
}
#[kithara::mock(api = PcmReaderMock)]
pub trait PcmReader: kithara_platform::MaybeSend {
fn abr_handle(&self) -> Option<kithara_abr::AbrHandle> {
None
}
fn duration(&self) -> Option<Duration>;
fn event_bus(&self) -> &EventBus;
fn metadata(&self) -> &TrackMetadata;
fn next_chunk(&mut self) -> Result<ChunkOutcome, DecodeError> {
Ok(ChunkOutcome::Eof {
position: self.position(),
})
}
fn position(&self) -> Duration;
fn preload(&mut self) -> Result<(), DecodeError> {
Ok(())
}
fn preload_notify(&self) -> Option<Arc<Notify>> {
None
}
fn read(&mut self, buf: &mut [f32]) -> Result<ReadOutcome, DecodeError>;
fn read_planar<'a>(
&mut self,
output: &'a mut [&'a mut [f32]],
) -> Result<ReadOutcome, DecodeError>;
fn seek(&mut self, position: Duration) -> Result<SeekOutcome, DecodeError>;
fn set_host_sample_rate(&self, _sample_rate: NonZeroU32) {}
fn set_playback_rate(&self, _rate: f32) {}
fn set_service_class(&self, _class: ServiceClass) {}
fn spec(&self) -> PcmSpec;
}