Skip to main content

a1800_codec/
lib.rs

1pub mod analysis;
2pub mod bitstream;
3pub mod decoder;
4pub mod encoder;
5pub mod filterbank;
6pub mod fixedpoint;
7pub mod synthesis;
8pub mod tables;
9pub mod wav;
10
11use decoder::{DecoderState, FRAME_SIZE};
12use encoder::EncoderState;
13
14/// A1800 audio codec decoder.
15///
16/// Decodes .a18 bitstream frames into 16-bit PCM audio samples.
17/// Each frame produces 320 samples (20ms at 16kHz).
18pub struct A1800Decoder {
19    state: DecoderState,
20}
21
22/// Errors that can occur during decoding.
23#[derive(Debug)]
24pub enum DecodeError {
25    /// Invalid bitrate (must be 4800–32000 in steps of 800).
26    InvalidBitrate(u16),
27    /// Input buffer too small for one encoded frame.
28    InputTooSmall { expected: usize, got: usize },
29    /// Output buffer too small for decoded frame.
30    OutputTooSmall { expected: usize, got: usize },
31}
32
33impl std::fmt::Display for DecodeError {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        match self {
36            DecodeError::InvalidBitrate(br) => {
37                write!(f, "invalid bitrate {}: must be 4800–32000 in steps of 800", br)
38            }
39            DecodeError::InputTooSmall { expected, got } => {
40                write!(f, "input too small: need {} i16 words, got {}", expected, got)
41            }
42            DecodeError::OutputTooSmall { expected, got } => {
43                write!(f, "output too small: need {} samples, got {}", expected, got)
44            }
45        }
46    }
47}
48
49impl std::error::Error for DecodeError {}
50
51impl A1800Decoder {
52    /// Create a new decoder for the given bitrate.
53    ///
54    /// Bitrate must be 4800–32000 in steps of 800 (e.g., 8000, 16000, 24000).
55    pub fn new(bitrate: u16) -> Result<Self, DecodeError> {
56        let state = DecoderState::new(bitrate).map_err(|_| DecodeError::InvalidBitrate(bitrate))?;
57        Ok(A1800Decoder { state })
58    }
59
60    /// Size of one encoded frame in i16 words.
61    pub fn encoded_frame_size(&self) -> usize {
62        self.state.encoded_frame_size as usize
63    }
64
65    /// Size of one decoded frame in samples (always 320).
66    pub fn decoded_frame_size(&self) -> usize {
67        FRAME_SIZE
68    }
69
70    /// Decode one frame of A1800 audio.
71    ///
72    /// `input` must contain at least `encoded_frame_size()` i16 words.
73    /// `output` must have space for at least 320 samples.
74    pub fn decode_frame(
75        &mut self,
76        input: &[i16],
77        output: &mut [i16],
78    ) -> Result<(), DecodeError> {
79        let enc_size = self.encoded_frame_size();
80        if input.len() < enc_size {
81            return Err(DecodeError::InputTooSmall {
82                expected: enc_size,
83                got: input.len(),
84            });
85        }
86        if output.len() < FRAME_SIZE {
87            return Err(DecodeError::OutputTooSmall {
88                expected: FRAME_SIZE,
89                got: output.len(),
90            });
91        }
92
93        // Decode bitstream into subband samples
94        let mut subband = [0i16; FRAME_SIZE];
95        let scale_param = self.state.decode_frame_to_subbands(input, &mut subband);
96
97        // Synthesize PCM from subbands
98        synthesis::synthesize(
99            &subband,
100            &mut self.state.synth_memory[..160],
101            &mut output[..FRAME_SIZE],
102            FRAME_SIZE as i16,
103            scale_param,
104        );
105
106        Ok(())
107    }
108}
109
110/// Errors that can occur during encoding.
111#[derive(Debug)]
112pub enum EncodeError {
113    /// Invalid bitrate (must be 4800–32000 in steps of 800).
114    InvalidBitrate(u16),
115    /// Input buffer too small for one frame.
116    InputTooSmall { expected: usize, got: usize },
117    /// Output buffer too small for encoded frame.
118    OutputTooSmall { expected: usize, got: usize },
119}
120
121impl std::fmt::Display for EncodeError {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        match self {
124            EncodeError::InvalidBitrate(br) => {
125                write!(f, "invalid bitrate {}: must be 4800–32000 in steps of 800", br)
126            }
127            EncodeError::InputTooSmall { expected, got } => {
128                write!(f, "input too small: need {} samples, got {}", expected, got)
129            }
130            EncodeError::OutputTooSmall { expected, got } => {
131                write!(f, "output too small: need {} i16 words, got {}", expected, got)
132            }
133        }
134    }
135}
136
137impl std::error::Error for EncodeError {}
138
139/// A1800 audio codec encoder.
140///
141/// Encodes 16-bit PCM audio samples into .a18 bitstream frames.
142/// Each frame consumes 320 samples (20ms at 16kHz).
143pub struct A1800Encoder {
144    state: EncoderState,
145}
146
147impl A1800Encoder {
148    /// Create a new encoder for the given bitrate.
149    ///
150    /// Bitrate must be 4800–32000 in steps of 800 (e.g., 8000, 16000, 24000).
151    pub fn new(bitrate: u16) -> Result<Self, EncodeError> {
152        let state = EncoderState::new(bitrate).map_err(|_| EncodeError::InvalidBitrate(bitrate))?;
153        Ok(A1800Encoder { state })
154    }
155
156    /// Size of one encoded frame in i16 words.
157    pub fn encoded_frame_size(&self) -> usize {
158        self.state.encoded_frame_size as usize
159    }
160
161    /// Encode one frame of A1800 audio.
162    ///
163    /// `input` must contain at least 320 PCM samples.
164    /// `output` must have space for at least `encoded_frame_size()` i16 words.
165    pub fn encode_frame(
166        &mut self,
167        input: &[i16],
168        output: &mut [i16],
169    ) -> Result<(), EncodeError> {
170        if input.len() < FRAME_SIZE {
171            return Err(EncodeError::InputTooSmall {
172                expected: FRAME_SIZE,
173                got: input.len(),
174            });
175        }
176        let enc_size = self.encoded_frame_size();
177        if output.len() < enc_size {
178            return Err(EncodeError::OutputTooSmall {
179                expected: enc_size,
180                got: output.len(),
181            });
182        }
183
184        // Zero output first
185        for w in output[..enc_size].iter_mut() {
186            *w = 0;
187        }
188
189        self.state.encode_frame_to_bitstream(&input[..FRAME_SIZE], &mut output[..enc_size]);
190        Ok(())
191    }
192}