Skip to main content

Audio

Struct Audio 

Source
pub struct Audio { /* private fields */ }
Expand description

Audio Interface state: the two-deep DMA FIFO, the DAC rate divider, and the derived-timing sample emission.

Implementations§

Source§

impl Audio

Source

pub const fn new() -> Self

Construct at power-on (NTSC, idle).

Source

pub const fn set_region(&mut self, region: Region)

Select the console region (sets the video clock and re-derives the rate). Wired from the cart header at ROM load; defaults to NTSC.

Source

pub const fn underruns(&self) -> u64

Observed underrun count (buffer starvations) — for the harness.

Source

pub const fn sample_rate(&self) -> u32

The derived output sample rate in Hz (0 until AI_DACRATE is set).

Source

pub fn drain(&mut self) -> Vec<StereoSample>

Drain the emitted stereo stream produced since the last drain.

Source

pub fn read_reg(&self, index: u32) -> u32

Read an AI register (index = (addr >> 2) & 7).

Every register except AI_STATUS (index 3) is write-only and reads back a mirror of AI_LENGTH (the front transfer’s remaining bytes), per the wiki and ares. AI_STATUS reports the FULL/BUSY/ENABLED flags plus the best-effort COUNT/WC readback (ledgered — no oracle pins its phase).

Source

pub fn write_reg(&mut self, index: u32, val: u32) -> AiIrq

Write an AI register (index = (addr >> 2) & 7), returning the MI interrupt effect for the Bus to apply.

The interrupt fires when a transfer starts, not when it ends: writing AI_LENGTH into an idle queue (dma_count == 0) starts that buffer immediately and raises the interrupt now; a second buffer queued behind a playing one raises nothing until it is promoted in Audio::tick. This is what lets software refill during playback (wiki §DMA).

Source

pub fn tick<B: AudioBus>(&mut self, now: u64, bus: &mut B)

Advance the AI to now master ticks, emitting every output sample whose scheduled tick has arrived.

Derived timing (ADR 0006): the number of samples emitted is a function of now and the DAC period, never of an independently incremented counter. Hot path — allocation into the sink is the only cost while playing.

Source

pub fn tick_without_bus(&mut self, now: u64) -> Option<NeedsBus>

The part of a step that needs no bus access, returning None when it finished the step on its own and Some(NeedsBus) when samples must be read out of RDRAM.

This advances state, despite the Option return: it stamps last_tick on every call and anchors next_sample_tick on the first one. It is named tick_* rather than is_* for that reason.

Split out so a caller can decide whether to pay for bus access before arranging it. A caller that owns this struct cannot lend it out without first moving it, and that move is pure overhead on the ~99.95% of steps that emit nothing (docs/audio.md §Derived timing). Audio::tick calls this too, so there is one implementation of the early-outs and no way for the two to disagree.

Source

pub fn tick_with_bus<B: AudioBus>(&mut self, proof: NeedsBus, bus: &mut B)

The rest of the step, which reads sample words out of RDRAM.

Reachable only with a NeedsBus from Audio::tick_without_bus, so the two halves cannot run out of order: the preconditions — a non-zero period and at least one sample already due — are carried by the type rather than by a comment or an assertion. The token also carries the period, so the 64-bit divide that produced it is not repeated here.

Trait Implementations§

Source§

impl Clone for Audio

Source§

fn clone(&self) -> Audio

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Audio

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Audio

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Audio

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Audio

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for Audio

§

impl RefUnwindSafe for Audio

§

impl Send for Audio

§

impl Sync for Audio

§

impl Unpin for Audio

§

impl UnsafeUnpin for Audio

§

impl UnwindSafe for Audio

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,