Skip to content
File

Blob: archive/fft-benchmark/firmware/crates/esp32-radio/src/platform/music.rs

rust38 lines
1//! C allocates/frees PSRAM; Rust only borrows its immutable initialized contents.
2use super::ffi;
3use crate::error::{Error, Result};
4use std::{ptr::NonNull, slice};
5 
6#[derive(Debug)]
7pub(crate) struct MusicBytes {
8 pointer: NonNull<u8>,
9 length: usize,
10}
11 
12impl MusicBytes {
13 pub(crate) fn load() -> Result<Self> {
14 let mut length = 0;
15 // SAFETY: length is writable for the call. On success C transfers a
16 // fresh, fully initialized PSRAM allocation with no remaining aliases.
17 let pointer = NonNull::new(unsafe { ffi::radio_music_load(&mut length) })
18 .ok_or(Error::new("music partition could not be loaded"))?;
19 let bytes = Self { pointer, length };
20 if length != 4 * 1024 * 1024 {
21 return Err(Error::new("unexpected music partition size"));
22 }
23 Ok(bytes)
24 }
25 pub(crate) fn as_slice(&self) -> &[u8] {
26 // SAFETY: C returned exactly length initialized bytes in one allocation,
27 // bounded to 4 MiB (< isize::MAX). No C aliases remain. The returned
28 // lifetime is tied to self, so Drop cannot free live Rust borrows.
29 unsafe { slice::from_raw_parts(self.pointer.as_ptr(), self.length) }
30 }
31}
32impl Drop for MusicBytes {
33 fn drop(&mut self) {
34 // SAFETY: sole allocation owner; borrows have ended; free on C's allocator.
35 unsafe { ffi::radio_music_free(self.pointer.as_ptr()) };
36 }
37}