ileaved: bool,
}
+fn copy_audio<T:Clone+Copy>(dst: &mut [T], dstride: usize,
+ src: &[T], sstride: usize,
+ len: usize, channels: usize)
+{
+ match (sstride == 1, dstride == 1) {
+ (false, false) => {
+ for (dchan, schan) in dst.chunks_mut(dstride).zip(
+ src.chunks(sstride)).take(channels) {
+ dchan[..len].copy_from_slice(&schan[..len]);
+ }
+ },
+ (false, true) => {
+ for (ch, schan) in src.chunks(sstride).take(channels).enumerate() {
+ for (dchunk, &samp) in dst[ch..].chunks_mut(channels).zip(schan.iter()).take(len / channels) {
+ dchunk[0] = samp;
+ }
+ }
+ },
+ (true, false) => {
+ for (i, frame) in src.chunks_exact(channels).take(len).enumerate() {
+ for (&samp, dchan) in frame.iter().zip(dst[i..].chunks_mut(dstride)) {
+ dchan[0] = samp;
+ }
+ }
+ },
+ (true, true) => {
+ dst[..len].copy_from_slice(&src[..len]);
+ },
+ }
+}
+
impl<T:Clone+Copy+From<u8>> AudioQueue<T> {
fn new(channels: usize, rec_size: usize, ileaved: bool) -> Self {
Self {
data: vec![0.into(); rec_size * channels],
}
}
- fn get_cur_size(&self) -> usize {
- let size = self.end - self.start;
+ fn get_cur_size(&self) -> usize { self.end - self.start }
+ fn get_length(&self) -> usize {
+ let size = self.get_cur_size();
if !self.ileaved {
size
} else {
let old_len = self.get_cur_size();
let new_len = src.get_length();
if old_len > 0 {
- for (dst, (old, new)) in new_buf.chunks_exact_mut(new_stride).zip(
- self.data.chunks_exact(self.stride).zip(
- src.get_data().chunks(src.get_stride()))) {
- dst[..old_len].copy_from_slice(&old[self.start..self.end]);
- dst[old_len..][..new_len].copy_from_slice(&new[..new_len]);
+ if !self.ileaved {
+ for (dst, (old, new)) in new_buf.chunks_exact_mut(new_stride).zip(
+ self.data.chunks_exact(self.stride).zip(
+ src.get_data().chunks(src.get_stride()))) {
+ dst[..old_len].copy_from_slice(&old[self.start..self.end]);
+ dst[old_len..][..new_len].copy_from_slice(&new[..new_len]);
+ }
+ } else {
+ new_buf[..old_len].copy_from_slice(&self.data[self.start..self.end]);
+ copy_audio(&mut new_buf[old_len..], 1, src.get_data(), src.get_stride(), new_len, self.channels);
}
} else {
- for (dst, new) in new_buf.chunks_exact_mut(new_stride).zip(
- src.get_data().chunks(src.get_stride())) {
- dst[..new_len].copy_from_slice(&new[..new_len]);
- }
+ copy_audio(&mut new_buf, if !self.ileaved { new_stride } else { 1 }, src.get_data(), src.get_stride(), new_len, self.channels);
}
self.data = new_buf;
self.stride = new_stride;
return;
}
}
- match (src.get_step() != 1, self.ileaved) {
- (false, false) => {
- for (dst, src) in self.data.chunks_exact_mut(self.stride).zip(src.get_data().chunks_exact(src.get_stride())) {
- dst[self.end..][..to_copy].copy_from_slice(&src[..to_copy]);
- }
- },
- (true, false) => {
- for (i, chunk) in src.get_data().chunks_exact(src.get_step()).enumerate() {
- for (ch, &samp) in chunk.iter().enumerate() {
- self.data[self.stride * ch + self.end + i] = samp;
- }
- }
- }
- (true, true) => {
- let sdata = src.get_data();
- self.data[self.end..][..to_copy].copy_from_slice(&sdata[..to_copy]);
- },
- _ => unimplemented!(),
- };
+ copy_audio(&mut self.data[self.end..], if !self.ileaved { self.stride } else { 1 }, src.get_data(), src.get_stride(),
+ to_copy, self.channels);
self.end += to_copy;
}
fn write(&mut self, dbuf: &mut NAAudioBuffer<T>) {
let mut dst_len = dbuf.get_length();
let dst_stride = dbuf.get_stride();
- let dst_step = dbuf.get_step();
let dst = dbuf.get_data_mut().unwrap();
- match (self.ileaved, dst_step != 1) {
- (false, false) => {
- for (dst, src) in dst.chunks_mut(dst_stride).zip(self.data.chunks_exact(self.stride)) {
- dst[..dst_len].copy_from_slice(&src[self.start..][..dst_len]);
- }
- },
- (true, true) => {
- dst_len *= self.channels;
- dst[..dst_len].copy_from_slice(&self.data[self.start..][..dst_len]);
- },
- _ => unimplemented!(),
- };
+ if dst_stride == 1 {
+ dst_len *= self.channels;
+ }
+ copy_audio(dst, dst_stride, &self.data[self.start..], if !self.ileaved { self.stride } else { 1 },
+ dst_len, self.channels);
self.start += dst_len;
}
fn renorm(&mut self) {
impl AudioDataType {
fn get_length(&self) -> usize {
match self {
- AudioDataType::U8(ref queue) => queue.get_cur_size(),
- AudioDataType::I16(ref queue) => queue.get_cur_size(),
- AudioDataType::I32(ref queue) => queue.get_cur_size(),
- AudioDataType::F32(ref queue) => queue.get_cur_size(),
- AudioDataType::Packed(ref queue) => queue.get_cur_size(),
+ AudioDataType::U8(ref queue) => queue.get_length(),
+ AudioDataType::I16(ref queue) => queue.get_length(),
+ AudioDataType::I32(ref queue) => queue.get_length(),
+ AudioDataType::F32(ref queue) => queue.get_length(),
+ AudioDataType::Packed(ref queue) => queue.get_length(),
}
}
}