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 bark_protocol::types::AudioPacketFormat;
use thiserror::Error; use thiserror::Error;
use crate::audio::Frame;
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum NewEncoderError { pub enum NewEncoderError {
#[error("opus codec error: {0}")] #[error("opus codec error: {0}")]
@ -22,5 +24,5 @@ pub enum EncodeError {
pub trait Encode: Display + Send { pub trait Encode: Display + Send {
fn header_format(&self) -> AudioPacketFormat; 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 bark_protocol::{types::AudioPacketFormat, SAMPLE_RATE};
use crate::audio::{Frame, self};
use super::{Encode, EncodeError, NewEncoderError}; use super::{Encode, EncodeError, NewEncoderError};
pub struct OpusEncoder { pub struct OpusEncoder {
@ -35,7 +37,7 @@ impl Encode for OpusEncoder {
AudioPacketFormat::OPUS AudioPacketFormat::OPUS
} }
fn encode_packet(&mut self, samples: &[f32], out: &mut [u8]) -> Result<usize, EncodeError> { fn encode_packet(&mut self, samples: &[Frame], out: &mut [u8]) -> Result<usize, EncodeError> {
Ok(self.opus.encode_float(samples, out)?) 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 bark_protocol::types::AudioPacketFormat;
use crate::audio::{Frame, self};
use super::{Encode, EncodeError}; use super::{Encode, EncodeError};
pub struct S16LEEncoder; pub struct S16LEEncoder;
@ -17,8 +19,8 @@ impl Encode for S16LEEncoder {
AudioPacketFormat::S16LE AudioPacketFormat::S16LE
} }
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> {
encode_packed(samples, out, |sample| { encode_packed(frames, out, |sample| {
let scale = i16::MAX as f32; let scale = i16::MAX as f32;
let sample = sample.clamp(-1.0, 1.0) * scale; let sample = sample.clamp(-1.0, 1.0) * scale;
i16::to_le_bytes(sample as i16) i16::to_le_bytes(sample as i16)
@ -39,16 +41,17 @@ impl Encode for F32LEEncoder {
AudioPacketFormat::F32LE AudioPacketFormat::F32LE
} }
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> {
encode_packed(samples, out, f32::to_le_bytes) encode_packed(frames, out, f32::to_le_bytes)
} }
} }
fn encode_packed<const N: usize>( fn encode_packed<const N: usize>(
samples: &[f32], frames: &[Frame],
out: &mut [u8], out: &mut [u8],
func: impl Fn(f32) -> [u8; N], func: impl Fn(f32) -> [u8; N],
) -> Result<usize, EncodeError> { ) -> Result<usize, EncodeError> {
let samples = audio::to_interleaved(frames);
let out = check_length(out, samples.len() * N)?; let out = check_length(out, samples.len() * N)?;
for (output, input) in out.chunks_exact_mut(N).zip(samples) { for (output, input) in out.chunks_exact_mut(N).zip(samples) {

View file

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

View file

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