use frames in input

This commit is contained in:
Hailey Somerville 2023-12-29 20:15:28 +11:00
parent 45fe663aab
commit 77a39271f9
5 changed files with 27 additions and 20 deletions

View file

@ -6,6 +6,8 @@ use core::fmt::Display;
use bark_protocol::types::AudioPacketFormat;
use thiserror::Error;
use crate::audio::Frame;
#[derive(Debug, Error)]
pub enum NewEncoderError {
#[error("opus codec error: {0}")]
@ -22,5 +24,5 @@ pub enum EncodeError {
pub trait Encode: Display + Send {
fn header_format(&self) -> AudioPacketFormat;
fn encode_packet(&mut self, samples: &[f32], out: &mut [u8]) -> Result<usize, EncodeError>;
fn encode_packet(&mut self, frames: &[Frame], out: &mut [u8]) -> Result<usize, EncodeError>;
}

View file

@ -2,6 +2,8 @@ use core::fmt::{self, Display};
use bark_protocol::{types::AudioPacketFormat, SAMPLE_RATE};
use crate::audio::{Frame, self};
use super::{Encode, EncodeError, NewEncoderError};
pub struct OpusEncoder {
@ -35,7 +37,7 @@ impl Encode for OpusEncoder {
AudioPacketFormat::OPUS
}
fn encode_packet(&mut self, samples: &[f32], out: &mut [u8]) -> Result<usize, EncodeError> {
Ok(self.opus.encode_float(samples, out)?)
fn encode_packet(&mut self, samples: &[Frame], out: &mut [u8]) -> Result<usize, EncodeError> {
Ok(self.opus.encode_float(audio::to_interleaved(samples), out)?)
}
}

View file

@ -2,6 +2,8 @@ use core::fmt::{self, Display};
use bark_protocol::types::AudioPacketFormat;
use crate::audio::{Frame, self};
use super::{Encode, EncodeError};
pub struct S16LEEncoder;
@ -17,8 +19,8 @@ impl Encode for S16LEEncoder {
AudioPacketFormat::S16LE
}
fn encode_packet(&mut self, samples: &[f32], out: &mut [u8]) -> Result<usize, EncodeError> {
encode_packed(samples, out, |sample| {
fn encode_packet(&mut self, frames: &[Frame], out: &mut [u8]) -> Result<usize, EncodeError> {
encode_packed(frames, out, |sample| {
let scale = i16::MAX as f32;
let sample = sample.clamp(-1.0, 1.0) * scale;
i16::to_le_bytes(sample as i16)
@ -39,16 +41,17 @@ impl Encode for F32LEEncoder {
AudioPacketFormat::F32LE
}
fn encode_packet(&mut self, samples: &[f32], out: &mut [u8]) -> Result<usize, EncodeError> {
encode_packed(samples, out, f32::to_le_bytes)
fn encode_packet(&mut self, frames: &[Frame], out: &mut [u8]) -> Result<usize, EncodeError> {
encode_packed(frames, out, f32::to_le_bytes)
}
}
fn encode_packed<const N: usize>(
samples: &[f32],
frames: &[Frame],
out: &mut [u8],
func: impl Fn(f32) -> [u8; N],
) -> Result<usize, EncodeError> {
let samples = audio::to_interleaved(frames);
let out = check_length(out, samples.len() * N)?;
for (output, input) in out.chunks_exact_mut(N).zip(samples) {

View file

@ -1,7 +1,7 @@
use alsa::Direction;
use alsa::pcm::PCM;
use bark_protocol::{CHANNELS, time::Timestamp};
use bark_protocol::time::SampleDuration;
use bark_core::audio::{Frame, self};
use bark_protocol::time::{Timestamp, SampleDuration};
use nix::errno::Errno;
use thiserror::Error;
@ -24,7 +24,7 @@ impl Input {
Ok(Input { pcm })
}
pub fn read(&self, mut audio: &mut [f32]) -> Result<Timestamp, ReadAudioError> {
pub fn read(&self, mut audio: &mut [Frame]) -> Result<Timestamp, ReadAudioError> {
let now = Timestamp::from_micros_lossy(time::now());
let timestamp = now.saturating_sub(self.delay()?);
@ -36,7 +36,7 @@ impl Input {
Ok(timestamp)
}
fn read_partial(&self, audio: &mut [f32]) -> Result<usize, ReadAudioError> {
fn read_partial(&self, audio: &mut [Frame]) -> Result<usize, ReadAudioError> {
let io = unsafe {
// the checked versions of this function call
// snd_pcm_hw_params_current which mallocs under the hood
@ -45,10 +45,8 @@ impl Input {
loop {
// try to write audio
let err = match io.readi(audio) {
Ok(n) => {
return Ok(n * CHANNELS.0 as usize);
}
let err = match io.readi(audio::to_interleaved_mut(audio)) {
Ok(n) => { return Ok(n) }
Err(e) => e,
};

View file

@ -1,10 +1,12 @@
use std::sync::Arc;
use std::time::Duration;
use bark_core::audio::Frame;
use bark_core::encode::Encode;
use bark_core::encode::opus::OpusEncoder;
use bark_core::encode::pcm::{S16LEEncoder, F32LEEncoder};
use bark_protocol::SAMPLES_PER_PACKET;
use bark_protocol::FRAMES_PER_PACKET;
use bytemuck::Zeroable;
use structopt::StructOpt;
use bark_protocol::time::SampleDuration;
@ -92,10 +94,10 @@ pub fn run(opt: StreamOpt) -> Result<(), RunError> {
crate::thread::set_name("bark/audio");
loop {
let mut sample_buffer = [0f32; SAMPLES_PER_PACKET];
let mut audio_buffer = [Frame::zeroed(); FRAMES_PER_PACKET];
// read audio input
let timestamp = match input.read(&mut sample_buffer) {
let timestamp = match input.read(&mut audio_buffer) {
Ok(ts) => ts,
Err(e) => {
log::error!("error reading audio input: {e}");
@ -105,7 +107,7 @@ pub fn run(opt: StreamOpt) -> Result<(), RunError> {
// encode audio
let mut encode_buffer = [0; Audio::MAX_BUFFER_LENGTH];
let encoded_data = match encoder.encode_packet(&sample_buffer, &mut encode_buffer) {
let encoded_data = match encoder.encode_packet(&audio_buffer, &mut encode_buffer) {
Ok(size) => &encode_buffer[0..size],
Err(e) => {
log::error!("error encoding audio: {e}");