Ver código fonte

firmware: Implement the remaining audio buffer functions.

Mathias Gottschlag 5 anos atrás
pai
commit
db2dce0f04
1 arquivos alterados com 48 adições e 8 exclusões
  1. 48
    8
      hackamp/firmware/src/audio_buffer.rs

+ 48
- 8
hackamp/firmware/src/audio_buffer.rs Ver arquivo

@@ -1,3 +1,4 @@
1
+//! Audio buffer type to transfer audio data within different software/hardware components.
1 2
 #![warn(missing_docs)]
2 3
 
3 4
 use core::cell::{Cell, UnsafeCell};
@@ -8,9 +9,12 @@ use cortex_m::interrupt::{CriticalSection, Mutex};
8 9
 ///
9 10
 /// This translates two twice the number of values, as each sample contains two channels.
10 11
 pub const SAMPLES_PER_PACKET: usize = 48;
12
+/// Number of channels for all audio data.
11 13
 pub const CHANNELS: usize = 2;
14
+/// Number of packets that can be stored in each `AudioBuffer`.
12 15
 pub const PACKETS: usize = 3;
13 16
 
17
+/// Buffer for a single packet with audio data.
14 18
 pub type Packet = [u32; SAMPLES_PER_PACKET * CHANNELS];
15 19
 
16 20
 /// Type for audio packet buffering.
@@ -57,11 +61,16 @@ impl AudioBuffer {
57 61
     }
58 62
 
59 63
     /// Returns whether there are any buffers with valid data ready for reading.
60
-    pub fn read_data_available(&self, cs: &CriticalSection) -> bool {
64
+    pub fn can_read(&self, cs: &CriticalSection) -> bool {
61 65
         let inner = self.mutex.borrow(cs);
62 66
         inner.valid.get() != 0
63 67
     }
64 68
 
69
+    /// Borrows a single buffer for reading, returns `None` if no buffer with valid data is
70
+    /// available.
71
+    ///
72
+    /// The caller needs to return the buffer via `read_finished()` once the data has been
73
+    /// processed.
65 74
     pub fn borrow_read(&'static self, cs: &CriticalSection) -> Option<ReadPacket> {
66 75
         let inner = self.mutex.borrow(cs);
67 76
         let valid = inner.valid.get();
@@ -80,17 +89,24 @@ impl AudioBuffer {
80 89
         })
81 90
     }
82 91
 
83
-    pub fn read_finished(&'static self, _packet: ReadPacket, _cs: &CriticalSection) {
84
-        // TODO
85
-        panic!("Not yet implemented.");
92
+    /// Returns a buffer that was allocated via `borrow_read()` and marks it as empty.
93
+    pub fn read_finished(&'static self, packet: ReadPacket, cs: &CriticalSection) {
94
+        assert!((self as *const _) == (packet.buffer as *const _));
95
+        let inner = self.mutex.borrow(cs);
96
+        let index = packet.index;
97
+        inner.reading.set(inner.reading.get() & !(1 << index));
98
+        inner.invalid.set(inner.invalid.get() | (1 << index));
86 99
     }
87 100
 
88 101
     /// Returns whether there are any empty buffers ready for writing.
89
-    pub fn write_data_available(&self, cs: &CriticalSection) -> bool {
102
+    pub fn can_write(&self, cs: &CriticalSection) -> bool {
90 103
         let inner = self.mutex.borrow(cs);
91 104
         inner.invalid.get() != 0
92 105
     }
93 106
 
107
+    /// Borrows a single buffer for writing, returns `None` if no empty buffer is available.
108
+    ///
109
+    /// The caller needs to return the buffer via `write_finished()` once it was filled with data.
94 110
     pub fn borrow_write(&'static self, cs: &CriticalSection) -> Option<WritePacket> {
95 111
         let inner = self.mutex.borrow(cs);
96 112
         let invalid = inner.invalid.get();
@@ -109,20 +125,44 @@ impl AudioBuffer {
109 125
         })
110 126
     }
111 127
 
112
-    pub fn write_finished(&'static self, _packet: WritePacket, _cs: &CriticalSection) {
113
-        // TODO
114
-        panic!("Not yet implemented.");
128
+    /// Returns a buffer that was allocated via `borrow_write()` and marks it as ready for reading.
129
+    pub fn write_finished(&'static self, packet: WritePacket, cs: &CriticalSection) {
130
+        assert!((self as *const _) == (packet.buffer as *const _));
131
+        let inner = self.mutex.borrow(cs);
132
+        let index = packet.index;
133
+        inner.writing.set(inner.writing.get() & !(1 << index));
134
+        inner.valid.set(inner.valid.get() | (1 << index));
115 135
     }
116 136
 }
117 137
 
138
+/// Packet buffer that has been borrowed for reading (i.e., the buffer contains valid data).
118 139
 pub struct ReadPacket {
119 140
     buffer: &'static AudioBuffer,
120 141
     data: &'static Packet,
121 142
     index: usize,
122 143
 }
123 144
 
145
+impl AsRef<[u32]> for ReadPacket {
146
+    fn as_ref(&self) -> &[u32] {
147
+        self.data
148
+    }
149
+}
150
+
151
+/// Packet buffer that has been borrowed for writing (i.e., the buffer was previously empty).
124 152
 pub struct WritePacket {
125 153
     buffer: &'static AudioBuffer,
126 154
     data: &'static mut Packet,
127 155
     index: usize,
128 156
 }
157
+
158
+impl AsRef<[u32]> for WritePacket {
159
+    fn as_ref(&self) -> &[u32] {
160
+        self.data
161
+    }
162
+}
163
+
164
+impl AsMut<[u32]> for WritePacket {
165
+    fn as_mut(&mut self) -> &mut [u32] {
166
+        self.data
167
+    }
168
+}

Carregando…
Cancelar
Salvar