Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

audio_buffer.rs 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //! Audio buffer type to transfer audio data within different software/hardware components.
  2. #![warn(missing_docs)]
  3. use core::cell::{Cell, UnsafeCell};
  4. use core::ops::Deref;
  5. use cortex_m::interrupt::{CriticalSection, Mutex};
  6. use stable_deref_trait::StableDeref;
  7. /// Each packet contains 1 millisecond of audio data (48 samples at 48000kHz).
  8. ///
  9. /// This translates two twice the number of values, as each sample contains two channels.
  10. pub const SAMPLES_PER_PACKET: usize = 48;
  11. /// Number of channels for all audio data.
  12. pub const CHANNELS: usize = 2;
  13. /// Buffer for a single packet with audio data.
  14. pub type Packet = [u32; SAMPLES_PER_PACKET * CHANNELS];
  15. /// Type for audio packet buffering.
  16. ///
  17. /// The audio packets always contain two channels with 32-bit samples. The type contains a number
  18. /// of buffers each containing the same fixed number of samples.
  19. pub struct AudioBuffer<const PACKETS: usize> {
  20. mutex: Mutex<AudioBufferInner<PACKETS>>,
  21. }
  22. struct AudioBufferInner<const PACKETS: usize> {
  23. /// Packet contents.
  24. packets: [UnsafeCell<Packet>; PACKETS],
  25. /// Bitmask of packets which contain valid data and are not currently being read.
  26. valid: Cell<u32>,
  27. /// Bitmask of packets which do not contain valid data and which are not currently being
  28. /// written.
  29. invalid: Cell<u32>,
  30. /// Bitmask of all packets which are currently borrowed via `borrow_read()`.
  31. reading: Cell<u32>,
  32. /// Bitmask of all packets which are currently borrowed via `borrow_write()`.
  33. writing: Cell<u32>,
  34. }
  35. impl AudioBuffer<4> {
  36. /// Creates a new audio buffer.
  37. pub const fn new() -> Self {
  38. const PACKETS: usize = 4;
  39. // Initially, all packet contents are invalid and no packets are currently being read or
  40. // written.
  41. AudioBuffer {
  42. mutex: Mutex::new(AudioBufferInner {
  43. packets: [
  44. UnsafeCell::new([0; SAMPLES_PER_PACKET * CHANNELS]),
  45. UnsafeCell::new([0; SAMPLES_PER_PACKET * CHANNELS]),
  46. UnsafeCell::new([0; SAMPLES_PER_PACKET * CHANNELS]),
  47. UnsafeCell::new([0; SAMPLES_PER_PACKET * CHANNELS]),
  48. ],
  49. valid: Cell::new(0),
  50. invalid: Cell::new(((1 << PACKETS) - 1) as u32),
  51. reading: Cell::new(0),
  52. writing: Cell::new(0),
  53. }),
  54. }
  55. }
  56. }
  57. impl<const PACKETS: usize> AudioBuffer<PACKETS> {
  58. /// Returns an interface to read packets from this buffer.
  59. pub fn read(&'static self) -> ReadBuffer<PACKETS> {
  60. ReadBuffer { buffer: self }
  61. }
  62. /// Returns an interface to write packets to this buffer.
  63. pub fn write(&'static self) -> WriteBuffer<PACKETS> {
  64. WriteBuffer { buffer: self }
  65. }
  66. }
  67. /// Interface to read packets from a buffer.
  68. pub struct ReadBuffer<const PACKETS: usize> {
  69. buffer: &'static AudioBuffer<PACKETS>,
  70. }
  71. impl<const PACKETS: usize> ReadBuffer<PACKETS> {
  72. /// Returns whether there are any buffers with valid data ready for reading.
  73. pub fn can_read(&self, cs: &CriticalSection) -> bool {
  74. let inner = self.buffer.mutex.borrow(cs);
  75. inner.valid.get() != 0
  76. }
  77. /// Borrows a single buffer for reading, returns `None` if no buffer with valid data is
  78. /// available.
  79. ///
  80. /// The caller needs to return the buffer via `read_finished()` once the data has been
  81. /// processed.
  82. pub fn borrow_read(&self, cs: &CriticalSection) -> Option<ReadPacket<PACKETS>> {
  83. let inner = self.buffer.mutex.borrow(cs);
  84. let valid = inner.valid.get();
  85. if valid == 0 {
  86. return None;
  87. }
  88. let index = valid.trailing_zeros();
  89. inner.valid.set(valid & !(1 << index));
  90. inner.reading.set(inner.reading.get() | (1 << index));
  91. let index = index as usize;
  92. Some(ReadPacket {
  93. buffer: self.buffer,
  94. data: unsafe { &*inner.packets[index].get() },
  95. index,
  96. })
  97. }
  98. /// Returns a buffer that was allocated via `borrow_read()` and marks it as empty.
  99. pub fn read_finished(&self, packet: ReadPacket<PACKETS>, cs: &CriticalSection) {
  100. assert!((self.buffer as *const _) == (packet.buffer as *const _));
  101. let inner = self.buffer.mutex.borrow(cs);
  102. let index = packet.index;
  103. inner.reading.set(inner.reading.get() & !(1 << index));
  104. inner.invalid.set(inner.invalid.get() | (1 << index));
  105. }
  106. }
  107. /// Interface to write packets to a buffer.
  108. pub struct WriteBuffer<const PACKETS: usize> {
  109. buffer: &'static AudioBuffer<PACKETS>,
  110. }
  111. impl<const PACKETS: usize> WriteBuffer<PACKETS> {
  112. /// Returns whether there are any empty buffers ready for writing.
  113. pub fn can_write(&self, cs: &CriticalSection) -> bool {
  114. let inner = self.buffer.mutex.borrow(cs);
  115. inner.invalid.get() != 0
  116. }
  117. /// Borrows a single buffer for writing, returns `None` if no empty buffer is available.
  118. ///
  119. /// The caller needs to return the buffer via `write_finished()` once it was filled with data.
  120. pub fn borrow_write(&self, cs: &CriticalSection) -> Option<WritePacket<PACKETS>> {
  121. let inner = self.buffer.mutex.borrow(cs);
  122. let invalid = inner.invalid.get();
  123. if invalid == 0 {
  124. return None;
  125. }
  126. let index = invalid.trailing_zeros();
  127. inner.invalid.set(invalid & !(1 << index));
  128. inner.writing.set(inner.writing.get() | (1 << index));
  129. let index = index as usize;
  130. Some(WritePacket {
  131. buffer: self.buffer,
  132. data: unsafe { &mut *inner.packets[index].get() },
  133. index,
  134. })
  135. }
  136. /// Returns a buffer that was allocated via `borrow_write()` and marks it as ready for reading.
  137. pub fn write_finished(&self, packet: WritePacket<PACKETS>, cs: &CriticalSection) {
  138. assert!((self.buffer as *const _) == (packet.buffer as *const _));
  139. let inner = self.buffer.mutex.borrow(cs);
  140. let index = packet.index;
  141. inner.writing.set(inner.writing.get() & !(1 << index));
  142. inner.valid.set(inner.valid.get() | (1 << index));
  143. }
  144. }
  145. /// Packet buffer that has been borrowed for reading (i.e., the buffer contains valid data).
  146. pub struct ReadPacket<const PACKETS: usize> {
  147. buffer: &'static AudioBuffer<PACKETS>,
  148. data: &'static Packet,
  149. index: usize,
  150. }
  151. impl<const PACKETS: usize> AsRef<[u32]> for ReadPacket<PACKETS> {
  152. fn as_ref(&self) -> &[u32] {
  153. self.data
  154. }
  155. }
  156. impl<const PACKETS: usize> Deref for ReadPacket<PACKETS> {
  157. type Target = Packet;
  158. fn deref(&self) -> &Self::Target {
  159. &self.data
  160. }
  161. }
  162. unsafe impl<const PACKETS: usize> StableDeref for ReadPacket<PACKETS> {}
  163. /// Packet buffer that has been borrowed for writing (i.e., the buffer was previously empty).
  164. pub struct WritePacket<const PACKETS: usize> {
  165. buffer: &'static AudioBuffer<PACKETS>,
  166. data: &'static mut Packet,
  167. index: usize,
  168. }
  169. impl<const PACKETS: usize> AsRef<[u32]> for WritePacket<PACKETS> {
  170. fn as_ref(&self) -> &[u32] {
  171. self.data
  172. }
  173. }
  174. impl<const PACKETS: usize> AsMut<[u32]> for WritePacket<PACKETS> {
  175. fn as_mut(&mut self) -> &mut [u32] {
  176. self.data
  177. }
  178. }