mirror of
https://github.com/haileys/bark
synced 2024-11-28 22:30:24 +00:00
use frames in input
This commit is contained in:
parent
45fe663aab
commit
77a39271f9
5 changed files with 27 additions and 20 deletions
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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}");
|
||||||
|
|
Loading…
Reference in a new issue