law_encoder/
lib.rs

1#![no_std]
2
3pub use crate::errors::EncodeError;
4pub use crate::formats::{InputFormat, OutputFormat};
5
6mod encoder;
7pub mod errors;
8pub mod formats;
9
10pub struct LawEncoder;
11
12impl LawEncoder {
13    ///Encodes audio data from one format to another, writing the encoded data into the provided output buffer.
14    ///
15    ///#### Parameters:
16    ///
17    ///- `input_format`: An `InputFormat` enum specifying the format of the input data.
18    ///- `input_data`: A slice of `u8` representing the audio data to be encoded. This data should conform to the format specified by `input_format`.
19    ///- `output_format`: An `OutputFormat` enum specifying the desired format of the output data.
20    ///- `output_buffer`: A mutable slice of `u8` where the encoded data will be stored. The buffer must be large enough to hold the encoded data; otherwise, an error is returned.
21    ///#### Returns:
22    ///- A `Result<usize, EncodeError>` indicating the outcome of the encoding operation. On success, it returns `Ok(num_bytes)`, where `num_bytes` is the number of bytes written to `output_buffer`. On failure, it returns `Err(EncodeError)`, indicating the nature of the error.
23    ///#### Errors:
24    ///- `EncodeError::OutputBufferTooSmall`: This error indicates that the provided `output_buffer` is not large enough to contain the encoded data. The size of the output buffer must be at least half the size of the input data, reflecting the specific encoding algorithm's requirements.
25    ///#### Example Usage:
26    ///```rust
27    ///use law_encoder::{InputFormat, OutputFormat, LawEncoder};
28    ///let input_data = vec![/* input data bytes */];
29    ///let mut output_buffer = vec![0u8; /* appropriate size */ 12];
30    ///let encoder = LawEncoder;
31    ///match encoder.encode(InputFormat::BigEndian, &input_data, OutputFormat::Alaw, &mut output_buffer) {
32    ///    Ok(num_bytes) => println!("Encoded {} bytes successfully.", num_bytes),
33    ///    Err(e) => println!("Encoding failed: {:?}", e),
34    ///}
35    ///```
36    ///
37    ///#### Notes:
38    ///
39    ///- The exact size requirement for `output_buffer` may vary depending on the input and output formats. It is generally recommended to allocate the output buffer with at least half the size of the input data to accommodate the encoded data.
40    pub fn encode(
41        &self,
42        input_format: InputFormat,
43        input_data: &[u8],
44        output_format: OutputFormat,
45        output_buffer: &mut [u8],
46    ) -> Result<usize, EncodeError> {
47        if output_buffer.len() < (input_data.len() / 2) {
48            return Err(EncodeError::OutputBufferTooSmall);
49        }
50
51        let num_bytes = encoder::encode(input_format, input_data, output_format, output_buffer);
52
53        Ok(num_bytes)
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    fn setup() -> LawEncoder {
62        LawEncoder {}
63    }
64
65    #[test]
66    fn num_encoded_bytes() {
67        let encoder = setup();
68
69        let bytes: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
70        let mut output: [u8; 5] = [0; 5];
71
72        let num_encoded = encoder
73            .encode(
74                InputFormat::BigEndian,
75                &bytes,
76                OutputFormat::Mulaw,
77                &mut output,
78            )
79            .unwrap();
80        assert_eq!(num_encoded, 5);
81
82        let empty = [0; 0];
83
84        let num_encoded = encoder
85            .encode(
86                InputFormat::BigEndian,
87                &empty,
88                OutputFormat::Mulaw,
89                &mut output,
90            )
91            .unwrap();
92        assert_eq!(num_encoded, 0);
93    }
94
95    #[test]
96    fn correct_encoded_bytes_big_endian() {
97        let encoder = setup();
98
99        // 1000 and -1000 divided across 1 byte segments in big endian
100        let bytes: [u8; 4] = [0b00000011, 0b11101000, 0b11111100, 0b00011000];
101        let mut output: [u8; 2] = [0; 2];
102
103        let _num_encoded = encoder
104            .encode(
105                InputFormat::BigEndian,
106                &bytes,
107                OutputFormat::Mulaw,
108                &mut output,
109            )
110            .unwrap();
111        assert_eq!(output, [206, 78]);
112
113        let _num_encoded = encoder
114            .encode(
115                InputFormat::BigEndian,
116                &bytes,
117                OutputFormat::Alaw,
118                &mut output,
119            )
120            .unwrap();
121        assert_eq!(output, [250, 122])
122    }
123
124    #[test]
125    fn correct_encoded_bytes_little_endian() {
126        let encoder = setup();
127
128        // 1000 and -1000 divided across 1 byte segments in little endian
129        let bytes: [u8; 4] = [0b11101000, 0b00000011, 0b00011000, 0b11111100];
130        let mut output: [u8; 2] = [0; 2];
131
132        let _num_encoded = encoder
133            .encode(
134                InputFormat::LittleEndian,
135                &bytes,
136                OutputFormat::Mulaw,
137                &mut output,
138            )
139            .unwrap();
140        assert_eq!(output, [206, 78]);
141
142        let _num_encoded = encoder
143            .encode(
144                InputFormat::LittleEndian,
145                &bytes,
146                OutputFormat::Alaw,
147                &mut output,
148            )
149            .unwrap();
150        assert_eq!(output, [250, 122]);
151    }
152
153    #[test]
154    fn output_buffer_error() {
155        let encoder = setup();
156
157        let bytes: [u8; 20] = [0; 20];
158        let mut output_buffer: [u8; 2] = [0; 2];
159
160        let result = encoder.encode(
161            InputFormat::BigEndian,
162            &bytes,
163            OutputFormat::Mulaw,
164            &mut output_buffer,
165        );
166
167        assert!(result.is_err(), "Expected an error for ouput buffer size");
168    }
169
170    #[test]
171    fn odd_length_input() {
172        let encoder = setup();
173
174        let bytes: [u8; 3] = [0b00000011, 0b11101000, 0b11111100];
175        let mut output: [u8; 2] = [0; 2];
176
177        let num_encoded_bytes = encoder
178            .encode(
179                InputFormat::BigEndian,
180                &bytes,
181                OutputFormat::Mulaw,
182                &mut output,
183            )
184            .unwrap();
185        assert_eq!(num_encoded_bytes, 1);
186        assert_eq!(output[0], 206);
187        assert_eq!(output[1], 0);
188    }
189}