pub struct AudioBuffer
{
channels : u32,
bit_depth : u32,
buffer_size : u32,
data : * mut u8,
ref_count : * mut u32
}
impl AudioBuffer
{
pub fn init(channels : u32, bit_depth : u32, buffer_size : u32) -> Self
{
let size = bit_depth / 8 * buffer_size;
unsafe
{
let ref_count = std::alloc::alloc(std::alloc::Layout::new::<u32>()) as * mut u32;
*ref_count = 1;
Self
{
channels,
bit_depth,
buffer_size,
data: std::alloc::alloc_zeroed(std::alloc::Layout::array::<u8>(size as usize).expect("Cannot allocate memory.")),
ref_count
}
}
}
pub fn read(&self, index: u32) -> f64
{
let bit_depth = self.bit_depth / 8;
let real_index = index % self.buffer_size * bit_depth;
let limit = if self.bit_depth == 8 { i8::MAX as i32 }
else if self.bit_depth == 16 { i16::MAX as i32 }
else if self.bit_depth == 24 { 2_i32.pow(24) - 1 }
else if self.bit_depth == 32 { i32::MAX }
else { 0 };
let mut data = 0;
for bit in 0..bit_depth
{
data = data << 8 | unsafe { *self.data.offset((real_index + bit_depth - bit) as isize) as u32 }
}
if data > limit as u32 { 0.0 - ((data - limit as u32) as i32 / limit) as f64 } else { (data / limit as u32) as f64 }
}
pub fn read_slice(&self, buffer : &mut [f64])
{
if buffer.len() != self.buffer_size as usize { return; }
for index in 0..self.buffer_size { buffer[index as usize] = self.read(index); }
}
pub fn write(&mut self, index: u32, data : f64)
{
let bit_depth = self.bit_depth / 8;
let real_index = index % self.buffer_size * bit_depth;
let limit = if self.bit_depth == 8 { i8::MAX as i32 }
else if self.bit_depth == 16 { i16::MAX as i32 }
else if self.bit_depth == 24 { 2_i32.pow(24) - 1 }
else if self.bit_depth == 32 { i32::MAX }
else { 0 };
let restored = if data < 0.0 { (data * limit as f64) as i32 } else { (data * limit as f64) as i32 };
for bit in 0..bit_depth
{
unsafe
{
*self.data.offset((real_index + bit) as isize) += ((restored & (0xFF << bit * 8)) >> (bit * 8)) as u8
}
}
}
pub fn write_slice(&mut self, buffer : &[f64])
{
if buffer.len() != self.buffer_size as usize { return; }
for index in 0..self.buffer_size { self.write(index, buffer[index as usize]); }
}
pub fn size(&self) -> u32 { self.buffer_size }
pub fn real_size(&self) -> u32 { self.bit_depth / 8 * self.buffer_size }
pub fn resize(&mut self, buffer_size : u32)
{
unsafe
{
let mut size = self.real_size();
std::alloc::dealloc(self.data, std::alloc::Layout::array::<u8>(size as usize).expect("Cannot allocate memory."));
self.buffer_size = buffer_size;
size = self.real_size();
self.data = std::alloc::alloc_zeroed(std::alloc::Layout::array::<u8>(size as usize).expect("Cannot allocate memory."));
}
}
pub fn clear(&mut self) { for index in 0..self.real_size() { unsafe { *self.data.offset(index as isize) = 0; } } }
}
impl std::clone::Clone for AudioBuffer
{
fn clone(&self) -> Self
{
unsafe { *self.ref_count += 1; }
Self
{
channels: self.channels,
bit_depth: self.bit_depth,
buffer_size: self.buffer_size,
data : self.data,
ref_count : self.ref_count,
}
}
}
impl std::default::Default for AudioBuffer
{
fn default() -> Self
{
Self
{
channels: Default::default(),
bit_depth: Default::default(),
buffer_size: Default::default(),
data: std::ptr::null_mut(),
ref_count: std::ptr::null_mut()
}
}
}
unsafe impl Sync for AudioBuffer { }
unsafe impl Send for AudioBuffer { }
impl Drop for AudioBuffer
{
fn drop(&mut self)
{
unsafe
{
if *self.ref_count == 1
{
let size = self.real_size();
std::alloc::dealloc(self.data, std::alloc::Layout::array::<u8>(size as usize).expect("Cannot allocate memory."));
std::alloc::dealloc(self.ref_count as * mut u8, std::alloc::Layout::new::<u32>());
}
else { *self.ref_count -= 1; }
}
}
}
pub struct AudioDevice<R : std::io::Read, W : std::io::Write>
{
name : String,
sample_rate : u32,
in_buffer : AudioBuffer,
out_buffer : AudioBuffer,
reader : std::io::BufReader<R>,
writer : std::io::BufWriter<W>
}
impl<R : std::io::Read, W : std::io::Write> AudioDevice<R, W>
{
pub fn init(name : &str, reader : R, writer : W) -> Self
{
Self
{
name: String::from(name),
sample_rate: u32::default(),
in_buffer: AudioBuffer::default(),
out_buffer: AudioBuffer::default(),
reader: std::io::BufReader::new(reader),
writer: std::io::BufWriter::new(writer),
}
}
pub fn name(&self) -> String { self.name.clone() }
pub fn get_sample_rate(&self) -> u32 { self.sample_rate }
pub fn set_sample_rate(&mut self, sample_rate : u32)
{
if sample_rate % 22050 == 0
{
self.sample_rate = sample_rate;
let state_data = ((sample_rate / 22050) as u8 - 1) << 2 | 0b01;
let _ = std::io::Write::write(&mut self.writer, &[state_data]);
return;
}
else if sample_rate % 24000 == 0
{
self.sample_rate = sample_rate;
let state_data = ((sample_rate / 24000) as u8 + 31) << 2 | 0b01;
let _ = std::io::Write::write(&mut self.writer, &[state_data]);
return;
}
println!("Invalid sample rate!");
}
pub fn get_in_buffer_size(&self) -> u32 { self.in_buffer.buffer_size }
pub fn get_out_buffer_size(&self) -> u32 { self.out_buffer.buffer_size }
pub fn get_in_channels(&self) -> u32 { self.in_buffer.channels }
pub fn get_out_channels(&self) -> u32 { self.out_buffer.channels }
pub fn get_in_bit_depth(&self) -> u32 { self.in_buffer.bit_depth }
pub fn get_out_bit_depth(&self) -> u32 { self.out_buffer.bit_depth }
fn read(&mut self)
{
std::io::BufRead::fill_buf(&mut self.reader).expect("Failed to fill the buffer.");
let buffer = self.reader.buffer();
let len = buffer.len();
if len == 0
{
println!("Buffer is empty!");
return;
}
let state_var = buffer[0] & 0b11;
let state_data = buffer[0] >> 2;
if state_var == 0b01
{
self.sample_rate = if state_data < 32 { (state_data + 1) as u32 * 22050 } else { (state_data - 31) as u32 * 24000 }
}
else if state_var == 0b10 { self.in_buffer.buffer_size = (state_data + 1) as u32 * 32 }
else if state_var == 0b11 { self.in_buffer.channels = (state_data as u32) + 1 }
if len == 1 { return; }
if self.in_buffer.bit_depth != 8 * (buffer.len() - 1) as u32 / (self.in_buffer.buffer_size * self.in_buffer.channels)
{
println!("Bit depth changed!");
self.in_buffer.bit_depth = 8 * (buffer.len() - 1) as u32 / (self.in_buffer.buffer_size * self.in_buffer.channels);
}
for index in 1..len { unsafe { *self.in_buffer.data.offset(index as isize) = buffer[index]; } }
}
fn write(&mut self)
{
let mut data = vec![0; self.out_buffer.buffer_size as usize + 1];
for index in 1..data.len() { data[index] = unsafe { *self.out_buffer.data.offset(index as isize) }; }
let _ = std::io::Write::write(&mut self.writer, &data);
self.out_buffer.clear();
}
pub fn play(&mut self, state : &bool)
{
while *state
{
let start_time = std::time::Instant::now();
self.read();
self.write();
let elapsed_time = start_time.elapsed();
let duration = std::time::Duration::from_secs_f64(self.in_buffer.buffer_size as f64 / self.sample_rate as f64);
if elapsed_time >= duration { continue; }
else { std::thread::sleep(duration - elapsed_time); }
}
}
}
unsafe impl<R : std::io::Read, W : std::io::Write> Sync for AudioDevice<R, W> { }
unsafe impl<R : std::io::Read, W : std::io::Write> Send for AudioDevice<R, W> { }