| | |
| | | sample_rate: u32, |
| | | channels: u32, |
| | | ) -> Result<Vec<PcmFrame>> { |
| | | if sample_rate != TARGET_SAMPLE_RATE_HZ || channels != u32::from(TARGET_NUM_CHANNELS) { |
| | | return Err(anyhow!( |
| | | "unsupported pcm_s16le stream format: sample_rate={}, channels={}", |
| | | sample_rate, |
| | | channels |
| | | )); |
| | | } |
| | | if payload.len() % 2 != 0 { |
| | | return Err(anyhow!("pcm_s16le payload has odd byte length")); |
| | | } |
| | | let samples: Vec<i16> = payload |
| | | .chunks_exact(2) |
| | | .map(|chunk| i16::from_le_bytes([chunk[0], chunk[1]])) |
| | | .collect(); |
| | | if samples.is_empty() { |
| | | return Ok(Vec::new()); |
| | | } |
| | | let samples_per_channel = (sample_rate / 50).max(1); |
| | | let frame_sample_count = samples_per_channel as usize * channels as usize; |
| | | let mut frames = Vec::new(); |
| | | for chunk in samples.chunks(frame_sample_count) { |
| | | let chunk_samples_per_channel = (chunk.len() / channels as usize) as u32; |
| | | if chunk_samples_per_channel == 0 { |
| | | continue; |
| | | } |
| | | frames.push(PcmFrame::new( |
| | | chunk.to_vec(), |
| | | sample_rate, |
| | | channels, |
| | | chunk_samples_per_channel, |
| | | )); |
| | | } |
| | | Ok(frames) |
| | | audio::pcm_s16le_bytes_to_frames( |
| | | payload, |
| | | sample_rate, |
| | | channels, |
| | | TARGET_SAMPLE_RATE_HZ, |
| | | TARGET_NUM_CHANNELS, |
| | | ) |
| | | } |
| | | |
| | | fn trim_ascii_whitespace(value: &[u8]) -> &[u8] { |