tauri-plugin-audioplayer 0.1.1

Tauri Audioplayer Plugin
use std::sync::{Arc, Mutex};

pub(crate) struct PlaybackState {
    pub(crate) samples: Arc<Vec<f32>>,
    pub(crate) source_channels: usize,
    pub(crate) position_samples: usize,
    pub(crate) playing: bool,
    pub(crate) volume: f32,
}

impl PlaybackState {
    pub(crate) fn new(samples: Arc<Vec<f32>>, source_channels: usize) -> Self {
        Self {
            samples,
            source_channels,
            position_samples: 0,
            playing: true,
            volume: 1.0,
        }
    }
}

pub(crate) fn seek_position_samples(
    position_seconds: f64,
    sample_rate: u32,
    channels: usize,
    sample_count: usize,
) -> Option<usize> {
    if !position_seconds.is_finite() || position_seconds < 0.0 || sample_rate == 0 || channels == 0
    {
        return None;
    }

    let total_frames = sample_count / channels;
    let requested_frame = (position_seconds * sample_rate as f64).floor() as usize;
    Some(requested_frame.min(total_frames) * channels)
}

pub(crate) fn render_samples(
    data: &mut [f32],
    output_channels: usize,
    playback: &Arc<Mutex<PlaybackState>>,
) {
    if output_channels == 0 {
        return;
    }

    let Ok(mut playback) = playback.lock() else {
        data.fill(0.0);
        return;
    };

    for output_frame in data.chunks_mut(output_channels) {
        if !playback.playing
            || playback.position_samples + playback.source_channels > playback.samples.len()
        {
            output_frame.fill(0.0);
            playback.playing = false;
            continue;
        }

        let source_frame = &playback.samples
            [playback.position_samples..playback.position_samples + playback.source_channels];
        for (output_channel, sample) in output_frame.iter_mut().enumerate() {
            let source_channel = output_channel * playback.source_channels / output_channels;
            *sample = source_frame[source_channel] * playback.volume;
        }
        playback.position_samples += playback.source_channels;
    }
}