resonator 0.3.2

This crate allows 2 devices to send live PCM audio data to each other through a server
Documentation
use serde::{Deserialize, Serialize};
use crate::{config::{AUDIO_BUFFER_SIZE, HEADER_SIZE, METADATA_SIZE}};
use crate::common::metadata::Metadata;

const BUFFER_SIZE:             usize = METADATA_SIZE + AUDIO_BUFFER_SIZE * std::mem::size_of::<f32>();
const BUFFER_WITH_HEADER_SIZE: usize = HEADER_SIZE + METADATA_SIZE + AUDIO_BUFFER_SIZE * std::mem::size_of::<f32>();

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct AudioBuffer {
    pub samples: Vec<f32>,
    pub metadata: Metadata
}

#[derive(Debug)]
pub enum AudioBufferError {
    InvalidSamplesLength //Length of samples vector does not match the AUDIO_BUFFER_SIZE
}

impl AudioBuffer {
    /**

     * Converts the AudioBuffer to a RawAudioBuffer, which the raw byte data can then be extracted from
     */
    pub fn as_buffer(&self) -> Result<RawAudioBuffer, AudioBufferError> {
        //Create a buffer sized to store the entire audio buffer & metadata
        let mut buffer = [0; BUFFER_SIZE];

        //Create two temp buffers to store the metadata and audio byte data
        let mut metadata = [0; METADATA_SIZE];
        let mut audio = [0; AUDIO_BUFFER_SIZE * std::mem::size_of::<f32>()];

        //Store the buffer size and sample rate in the metadata buffer
        metadata[0..4].copy_from_slice(&self.metadata.buffer_size.to_le_bytes());
        metadata[4..8].copy_from_slice(&self.metadata.sample_rate.to_le_bytes());
        
        //Throw an error if the length of the samples vector does not match the AUDIO_BUFFER_SIZE
        if self.samples.len() != AUDIO_BUFFER_SIZE {
            println!("Error! Length of samples vector does not match AUDIO_BUFFER_SIZE. Samples vector len is {} and AUDIO_BUFFER_SIZE is {}.", self.samples.len(), AUDIO_BUFFER_SIZE);
            return Err(AudioBufferError::InvalidSamplesLength);
        }

        //Convert each sample to bytes and store in the audio buffer
        for i in 0..AUDIO_BUFFER_SIZE {
            let sample_bytes = self.samples[i].to_le_bytes();
            audio[(i * std::mem::size_of::<f32>())..((i + 1) * std::mem::size_of::<f32>())].copy_from_slice(&sample_bytes);
        }

        //Construct the final buffer by concatenating the metadata and audio data buffers
        buffer[..8].copy_from_slice(&metadata);
        buffer[8..].copy_from_slice(&audio);

        Ok(RawAudioBuffer {
            buffer
        })
    }

    /**

     * Static method to create a new AudioBuffer from a buffer of raw bytes
     */
    pub fn from_bytes(buffer: &[u8]) -> AudioBuffer {
        //Copy the initial buffer into a new buffer titled bytes which can be mutated
        let bytes = &buffer[..];

        //Split the buffer into two parts, the metadata and the audio data
        let metadata_bytes = &bytes[..METADATA_SIZE];
        let audio_bytes = &bytes[METADATA_SIZE..];

        //Parse the buffer size and sample rate out of the metadata byte array
        let m_buff_size = i32::from_le_bytes(metadata_bytes[0..4].try_into().unwrap());
        let m_sample_rate = i32::from_le_bytes(metadata_bytes[4..8].try_into().unwrap());

        //Parse the samples out of the audio byte array
        let samples: Vec<f32> = audio_bytes.chunks_exact(4).map(|chunk| {
            f32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]])
        })
            .collect();

        //Construct & return a new AudioBuffer
        let new_buff = AudioBuffer {
            samples,
            metadata: Metadata {
                sample_rate: m_sample_rate,
                buffer_size: m_buff_size,
            }
        };

        new_buff
    }
}

pub struct RawAudioBuffer {
    buffer: [u8; BUFFER_SIZE]
}

impl RawAudioBuffer {
    /**

     * Adds a header with the specified sender_id and reciever_id to the RawAudioBuffer, and then returns the raw byte data
     */
    pub fn raw_buffer_with_header(&self, sender_id: i32, receiver_id: i32) -> [u8; BUFFER_WITH_HEADER_SIZE] {
        let mut buffer = [0; BUFFER_WITH_HEADER_SIZE];
        let mut header = [0; HEADER_SIZE];
        header[0..4].copy_from_slice(&sender_id.to_le_bytes());
        header[4..8].copy_from_slice(&receiver_id.to_le_bytes());
        buffer[..HEADER_SIZE].copy_from_slice(&header);
        buffer[HEADER_SIZE..].copy_from_slice(&self.buffer);
        buffer
    }

    /**

     * Getter for the raw byte data of the RawAudioBuffer
     */
    pub fn raw_buffer(&self) -> &[u8; BUFFER_SIZE] {
        &self.buffer
    }
}