audiofox 1.1.0

Cross platform audio capture made easy!
Documentation
// SPDX-License-Identifier: GPL-2.0-or-later WITH Classpath-exception-2.0
// Audiofox, the audio capturer!
// Copyright (c) 2026 foxberries

use core::ops::Deref;
use core::slice;

/// F32LE PCM samples output by [`link()`](crate::AudioManager::link).
///
/// These samples are interleaved, stereo, and returned at a rate of 48kHz.
///
/// # Platforms
/// `Chunk` size is ultimately determined by the system, and may thus be limited by some of the 
/// following factors:
/// - Linux: by quantum and buffer config values, or if a source sets the `node.force-quantum` 
/// property.
/// - macOS: by the system-specified buffer size range, but *not* by the action of 
/// `AudioHardwarePowerHint`.
/// - Windows: by the system-specified loopback buffer size, which is fixed and cannot be changed.
///
/// The upward limit is subject to change in future development.
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct Chunk<'a>(pub(crate) &'a [f32]);

impl Deref for Chunk<'_> {
    type Target = [f32];

    fn deref(&self) -> &Self::Target {
        self.0
    }
}

impl<'a> IntoIterator for &Chunk<'a> {
    type Item = &'a f32;
    type IntoIter = core::slice::Iter<'a, f32>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.iter()
    }
}

impl<'a> From<&'a [f32]> for Chunk<'a> {
    fn from(slice: &'a [f32]) -> Self {
        Chunk(slice)
    }
}

impl<'a> From<&'a [u8]> for Chunk<'a> {
    /// Converts an audio buffer to a finalized [`Chunk`].
    ///
    /// # Safety
    /// This conversion is safe if `Chunk` is fully populated with F32LE data.
    fn from(buffer: &'a [u8]) -> Self {
        Self(unsafe {
            slice::from_raw_parts(
                buffer.as_ptr().cast::<f32>(),
                buffer.len() / size_of::<f32>(),
            )
        })
    }
}