use crate::{config::{METADATA_SIZE, AUDIO_BUFFER_SIZE, HEADER_SIZE}, server::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)]
pub struct AudioBuffer {
pub samples: Vec<f32>,
pub metadata: Metadata
}
#[derive(Debug)]
pub enum AudioBufferError {
InvalidSamplesLength }
impl AudioBuffer {
pub fn as_buffer(&self) -> Result<RawAudioBuffer, AudioBufferError> {
let mut buffer = [0; BUFFER_SIZE];
let mut metadata = [0; METADATA_SIZE];
let mut audio = [0; AUDIO_BUFFER_SIZE * std::mem::size_of::<f32>()];
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());
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);
}
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);
}
buffer[..8].copy_from_slice(&metadata);
buffer[8..].copy_from_slice(&audio);
Ok(RawAudioBuffer {
buffer
})
}
pub fn from_bytes(buffer: &[u8; BUFFER_SIZE]) -> AudioBuffer {
let bytes = &buffer[..];
let metadata_bytes = &bytes[..METADATA_SIZE];
let audio_bytes = &bytes[METADATA_SIZE..];
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());
let samples: Vec<f32> = audio_bytes.chunks_exact(4).map(|chunk| {
f32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]])
})
.collect();
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 {
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
}
pub fn raw_buffer(&self) -> &[u8; BUFFER_SIZE] {
&self.buffer
}
}