#[cfg(feature = "g729")]
use crate::codecs::g729::impls::annex_b::{dtx::DtxState, vad::VadState};
use crate::codecs::g729::impls::api::config::EncoderConfig;
use crate::codecs::g729::impls::api::frame::FrameType;
#[cfg(any())]
use crate::codecs::g729::impls::bitstream::itu_params::{unpack_sid_params, unpack_speech_params};
#[cfg(feature = "g729")]
use crate::codecs::g729::impls::codec::encode::encode_annex_b_frame;
use crate::codecs::g729::impls::codec::encode::encode_speech_frame;
use crate::codecs::g729::impls::codec::state::EncoderState;
#[cfg(any())]
use crate::codecs::g729::impls::constants::PRM_SIZE;
use crate::codecs::g729::impls::error::CodecError;
use crate::codecs::g729::impls::{FRAME_SAMPLES, SPEECH_FRAME_BYTES};
pub struct G729Encoder {
state: EncoderState,
config: EncoderConfig,
#[cfg(feature = "g729")]
vad: VadState,
#[cfg(feature = "g729")]
dtx: DtxState,
}
impl G729Encoder {
pub fn new(config: impl Into<EncoderConfig>) -> Self {
Self {
state: EncoderState::default(),
config: config.into(),
#[cfg(feature = "g729")]
vad: VadState::default(),
#[cfg(feature = "g729")]
dtx: DtxState::default(),
}
}
pub fn encode(
&mut self,
pcm: &[i16; FRAME_SAMPLES],
output: &mut [u8; SPEECH_FRAME_BYTES],
) -> FrameType {
#[cfg(feature = "g729")]
{
if self.config.annex_b {
let (frame_type, bits) =
encode_annex_b_frame(&mut self.state, &mut self.vad, &mut self.dtx, pcm);
*output = bits;
return frame_type;
}
}
*output = encode_speech_frame(&mut self.state, pcm);
FrameType::Speech
}
pub fn encode_frame(&mut self, pcm: &[i16]) -> Result<[u8; SPEECH_FRAME_BYTES], CodecError> {
if pcm.len() != FRAME_SAMPLES {
return Err(CodecError::InvalidPcmLength {
expected: FRAME_SAMPLES,
got: pcm.len(),
});
}
let mut frame = [0i16; FRAME_SAMPLES];
frame.copy_from_slice(pcm);
let mut out = [0u8; SPEECH_FRAME_BYTES];
let _ = self.encode(&frame, &mut out);
Ok(out)
}
#[cfg(any())]
pub fn encode_parm(
&mut self,
pcm: &[i16; FRAME_SAMPLES],
ana: &mut [i16],
) -> Result<(FrameType, usize), CodecError> {
if ana.len() < PRM_SIZE + 1 {
return Err(CodecError::InvalidParameterLength {
expected: PRM_SIZE + 1,
got: ana.len(),
});
}
ana.fill(0);
let mut bits = [0u8; SPEECH_FRAME_BYTES];
let frame_type = self.encode(pcm, &mut bits);
match frame_type {
FrameType::Speech => {
let prm = unpack_speech_params(&bits);
ana[0] = 1;
for i in 0..PRM_SIZE {
ana[i + 1] = prm[i].0;
}
Ok((FrameType::Speech, PRM_SIZE))
}
FrameType::Sid => {
let sid = [bits[0], bits[1]];
let prm = unpack_sid_params(&sid);
ana[0] = 2;
for i in 0..4 {
ana[i + 1] = prm[i].0;
}
Ok((FrameType::Sid, 4))
}
FrameType::NoData => {
ana[0] = 0;
Ok((FrameType::NoData, 0))
}
}
}
pub fn reset(&mut self) {
self.state = EncoderState::default();
#[cfg(feature = "g729")]
{
self.vad = VadState::default();
self.dtx = DtxState::default();
}
}
pub fn config(&self) -> EncoderConfig {
self.config
}
}
impl Default for G729Encoder {
fn default() -> Self {
Self::new(EncoderConfig::default())
}
}