pub mod adpcm_clip_generated;
pub mod audio_player_generated;
pub mod pcm_clip_generated;
#[doc = "Macro to \"compile in\" a compressed (ADPCM) WAV clip from an external file (includes syntax details)."]
#[doc = include_str!("audio_player/adpcm_clip_docs.md")]
#[doc = include_str!("audio_player/audio_prep_steps_1_2.md")]
#[doc = include_str!("audio_player/adpcm_clip_step_3.md")]
#[doc(inline)]
pub use device_envoy_core::audio_player::adpcm_clip;
#[doc = "Macro to \"compile in\" an uncompressed (PCM) clip from an external file (includes syntax details)."]
#[doc = include_str!("audio_player/pcm_clip_docs.md")]
#[doc = include_str!("audio_player/audio_prep_steps_1_2.md")]
#[doc = include_str!("audio_player/pcm_clip_step_3.md")]
#[doc(inline)]
pub use device_envoy_core::audio_player::pcm_clip;
pub use device_envoy_core::audio_player::*;
#[cfg(target_os = "none")]
use crate::pio_irqs::{DmaIrqMap, PioIrqMap};
#[cfg(target_os = "none")]
use embassy_rp::Peri;
#[cfg(target_os = "none")]
use embassy_rp::dma::ChannelInstance;
#[cfg(target_os = "none")]
use embassy_rp::gpio::Pin;
#[cfg(target_os = "none")]
use embassy_rp::pio::{Instance, Pio, PioPin};
#[cfg(target_os = "none")]
use embassy_rp::pio_programs::i2s::{PioI2sOut, PioI2sOutProgram};
#[cfg(target_os = "none")]
const BIT_DEPTH_BITS: u32 = 16;
#[cfg(target_os = "none")]
const SAMPLE_BUFFER_LEN: usize = 256;
#[doc(hidden)]
pub struct AudioPlayerRp<const MAX_CLIPS: usize, const SAMPLE_RATE_HZ: u32> {
audio_player_static: &'static AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ>,
}
impl<const MAX_CLIPS: usize, const SAMPLE_RATE_HZ: u32> AudioPlayerRp<MAX_CLIPS, SAMPLE_RATE_HZ> {
#[doc(hidden)]
pub const fn new_static() -> AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ> {
AudioPlayerStatic::new_static()
}
#[doc(hidden)]
pub const fn new_static_with_max_volume(
max_volume: Volume,
) -> AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ> {
AudioPlayerStatic::new_static_with_max_volume(max_volume)
}
#[doc(hidden)]
pub const fn new_static_with_max_volume_and_initial_volume(
max_volume: Volume,
initial_volume: Volume,
) -> AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ> {
AudioPlayerStatic::new_static_with_max_volume_and_initial_volume(max_volume, initial_volume)
}
#[doc(hidden)]
#[must_use]
pub const fn new(
audio_player_static: &'static AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ>,
) -> Self {
Self {
audio_player_static,
}
}
#[doc(hidden)]
pub fn __audio_player_static(&self) -> &'static AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ> {
self.audio_player_static
}
}
#[cfg(target_os = "none")]
struct RpAudioOutputSink<'a, PIO: Instance + 'static> {
pio_i2s_out: &'a mut PioI2sOut<'static, PIO, 0>,
}
#[cfg(target_os = "none")]
impl<PIO: Instance + 'static> AudioOutputSink<SAMPLE_BUFFER_LEN> for RpAudioOutputSink<'_, PIO> {
async fn write_stereo_words(
&mut self,
stereo_words: &[u32; SAMPLE_BUFFER_LEN],
stereo_word_count: usize,
) -> core::result::Result<(), ()> {
self.pio_i2s_out
.write(&stereo_words[..stereo_word_count])
.await;
Ok(())
}
}
#[cfg(target_os = "none")]
#[doc(hidden)]
pub async fn device_loop<
const MAX_CLIPS: usize,
const SAMPLE_RATE_HZ: u32,
PIO: PioIrqMap,
DMA: ChannelInstance + DmaIrqMap,
DataPin: Pin + PioPin,
BitClockPin: Pin + PioPin,
WordSelectPin: Pin + PioPin,
>(
audio_player_static: &'static AudioPlayerStatic<MAX_CLIPS, SAMPLE_RATE_HZ>,
pio: Peri<'static, PIO>,
dma: Peri<'static, DMA>,
data_pin: Peri<'static, DataPin>,
bit_clock_pin: Peri<'static, BitClockPin>,
word_select_pin: Peri<'static, WordSelectPin>,
) -> ! {
let mut pio = Pio::new(pio, <PIO as PioIrqMap>::irqs());
let pio_i2s_out_program = PioI2sOutProgram::new(&mut pio.common);
let mut pio_i2s_out = PioI2sOut::new(
&mut pio.common,
pio.sm0,
dma,
<DMA as DmaIrqMap>::irqs(),
data_pin,
bit_clock_pin,
word_select_pin,
SAMPLE_RATE_HZ,
BIT_DEPTH_BITS,
&pio_i2s_out_program,
);
pio_i2s_out.start();
let _pio_i2s_out_program = pio_i2s_out_program;
let mut sample_buffer = [0_u32; SAMPLE_BUFFER_LEN];
loop {
let mut audio_command = audio_player_static.wait().await;
loop {
match audio_command {
AudioCommand::Play {
audio_clips,
at_end,
} => {
audio_player_static.mark_playing();
let next_audio_command = match at_end {
AtEnd::Loop => loop {
let mut rp_audio_output_sink = RpAudioOutputSink {
pio_i2s_out: &mut pio_i2s_out,
};
if let Some(next_audio_command) = play_clip_sequence_once(
&mut rp_audio_output_sink,
&audio_clips,
&mut sample_buffer,
audio_player_static,
)
.await
{
break Some(next_audio_command);
}
},
AtEnd::Stop => {
let mut rp_audio_output_sink = RpAudioOutputSink {
pio_i2s_out: &mut pio_i2s_out,
};
play_clip_sequence_once(
&mut rp_audio_output_sink,
&audio_clips,
&mut sample_buffer,
audio_player_static,
)
.await
}
};
if let Some(next_audio_command) = next_audio_command {
audio_command = next_audio_command;
continue;
}
audio_player_static.mark_stopped();
}
AudioCommand::Stop => audio_player_static.mark_stopped(),
}
break;
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! audio_player {
($($tt:tt)*) => { $crate::__audio_player_impl! { $($tt)* } };
}
#[doc(hidden)]
#[macro_export]
macro_rules! __audio_player_impl {
(
$name:ident {
$($fields:tt)*
}
) => {
$crate::__validate_keyword_fields_expr! {
macro_name: "audio_player!",
allowed_macro: $crate::__audio_player_allowed_field,
fields: [ $($fields)* ]
}
$crate::__audio_player_impl! {
@__fill_defaults
vis: pub(self),
name: $name,
data_pin: _UNSET_,
bit_clock_pin: _UNSET_,
word_select_pin: _UNSET_,
sample_rate_hz: _UNSET_,
pio: PIO0,
dma: DMA_CH0,
max_clips: 16,
max_volume: $crate::audio_player::Volume::MAX,
initial_volume: $crate::audio_player::Volume::MAX,
fields: [ $($fields)* ]
}
};
(
$vis:vis $name:ident {
$($fields:tt)*
}
) => {
$crate::__validate_keyword_fields_expr! {
macro_name: "audio_player!",
allowed_macro: $crate::__audio_player_allowed_field,
fields: [ $($fields)* ]
}
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: _UNSET_,
bit_clock_pin: _UNSET_,
word_select_pin: _UNSET_,
sample_rate_hz: _UNSET_,
pio: PIO0,
dma: DMA_CH0,
max_clips: 16,
max_volume: $crate::audio_player::Volume::MAX,
initial_volume: $crate::audio_player::Volume::MAX,
fields: [ $($fields)* ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ data_pin: $din_pin_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $din_pin_value,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ sample_rate_hz: $sample_rate_hz_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz_value,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ bit_clock_pin: $bclk_pin_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bclk_pin_value,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ word_select_pin: $lrc_pin_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $lrc_pin_value,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ pio: $pio_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio_value,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ dma: $dma_value:ident $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma_value,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ max_clips: $max_clips_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips_value,
max_volume: $max_volume,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ max_volume: $max_volume_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume_value,
initial_volume: $initial_volume,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:tt,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ initial_volume: $initial_volume_value:expr $(, $($rest:tt)* )? ]
) => {
$crate::__audio_player_impl! {
@__fill_defaults
vis: $vis,
name: $name,
data_pin: $data_pin,
bit_clock_pin: $bit_clock_pin,
word_select_pin: $word_select_pin,
sample_rate_hz: $sample_rate_hz,
pio: $pio,
dma: $dma,
max_clips: $max_clips,
max_volume: $max_volume,
initial_volume: $initial_volume_value,
fields: [ $($($rest)*)? ]
}
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: _UNSET_,
bit_clock_pin: $bit_clock_pin:tt,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ ]
) => {
compile_error!("audio_player! requires data_pin");
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:ident,
bit_clock_pin: _UNSET_,
word_select_pin: $word_select_pin:tt,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ ]
) => {
compile_error!("audio_player! requires bit_clock_pin");
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:ident,
bit_clock_pin: $bit_clock_pin:ident,
word_select_pin: _UNSET_,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ ]
) => {
compile_error!("audio_player! requires word_select_pin");
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:ident,
bit_clock_pin: $bit_clock_pin:ident,
word_select_pin: $word_select_pin:ident,
sample_rate_hz: _UNSET_,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ ]
) => {
compile_error!("audio_player! requires sample_rate_hz");
};
(@__fill_defaults
vis: $vis:vis,
name: $name:ident,
data_pin: $data_pin:ident,
bit_clock_pin: $bit_clock_pin:ident,
word_select_pin: $word_select_pin:ident,
sample_rate_hz: $sample_rate_hz:expr,
pio: $pio:ident,
dma: $dma:ident,
max_clips: $max_clips:expr,
max_volume: $max_volume:expr,
initial_volume: $initial_volume:expr,
fields: [ ]
) => {
$crate::__paste! {
static [<$name:upper _AUDIO_PLAYER_STATIC>]:
$crate::audio_player::AudioPlayerStatic<$max_clips, { $sample_rate_hz }> =
$crate::audio_player::AudioPlayerRp::<$max_clips, { $sample_rate_hz }>::new_static_with_max_volume_and_initial_volume(
$max_volume,
$initial_volume,
);
static [<$name:upper _AUDIO_PLAYER_CELL>]: ::static_cell::StaticCell<$name> =
::static_cell::StaticCell::new();
#[doc = concat!(
"Audio player generated by [`audio_player!`](macro@crate::audio_player).\n\n",
"See the [audio_player module documentation](mod@crate::audio_player) for usage and examples."
)]
$vis struct $name {
player: $crate::audio_player::AudioPlayerRp<$max_clips, { $sample_rate_hz }>,
}
#[doc = concat!(
"Trait-object clip source type at [`",
stringify!($name),
"::SAMPLE_RATE_HZ`](struct@",
stringify!($name),
").\n\n",
"Use this in signatures like `&'static ",
stringify!([<$name Playable>]),
"` instead of repeating `dyn Playable<{ ",
stringify!($name),
"::SAMPLE_RATE_HZ }>`."
)]
$vis type [<$name Playable>] =
dyn $crate::audio_player::Playable<{ $sample_rate_hz }>;
impl $name {
pub const SAMPLE_RATE_HZ: u32 = $sample_rate_hz;
pub const MAX_CLIPS: usize = $max_clips;
pub const INITIAL_VOLUME: $crate::audio_player::Volume = $initial_volume;
pub const MAX_VOLUME: $crate::audio_player::Volume = $max_volume;
pub fn new(
data_pin: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$data_pin>>,
bit_clock_pin: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$bit_clock_pin>>,
word_select_pin: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$word_select_pin>>,
pio: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$pio>>,
dma: impl Into<::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$dma>>,
spawner: ::embassy_executor::Spawner,
) -> $crate::Result<&'static Self> {
let token = [<$name:snake _audio_player_task>](
&[<$name:upper _AUDIO_PLAYER_STATIC>],
pio.into(),
dma.into(),
data_pin.into(),
bit_clock_pin.into(),
word_select_pin.into(),
);
spawner.spawn(token?);
let player =
$crate::audio_player::AudioPlayerRp::new(&[<$name:upper _AUDIO_PLAYER_STATIC>]);
Ok([<$name:upper _AUDIO_PLAYER_CELL>].init(Self { player }))
}
}
impl $crate::audio_player::AudioPlayer<{ $sample_rate_hz }> for $name {
const SAMPLE_RATE_HZ: u32 = $sample_rate_hz;
const MAX_CLIPS: usize = $max_clips;
const INITIAL_VOLUME: $crate::audio_player::Volume = $initial_volume;
const MAX_VOLUME: $crate::audio_player::Volume = $max_volume;
fn play<I>(&self, audio_clips: I, at_end: $crate::audio_player::AtEnd)
where
I: IntoIterator<Item = &'static dyn $crate::audio_player::Playable<{ $sample_rate_hz }>>,
{
$crate::audio_player::__audio_player_play(
self.player.__audio_player_static(),
audio_clips,
at_end,
);
}
fn stop(&self) {
$crate::audio_player::__audio_player_stop(self.player.__audio_player_static());
}
async fn wait_until_stopped(&self) {
$crate::audio_player::__audio_player_wait_until_stopped(
self.player.__audio_player_static(),
)
.await;
}
fn set_volume(&self, volume: $crate::audio_player::Volume) {
$crate::audio_player::__audio_player_set_volume(
self.player.__audio_player_static(),
volume,
);
}
fn volume(&self) -> $crate::audio_player::Volume {
$crate::audio_player::__audio_player_volume(self.player.__audio_player_static())
}
}
#[::embassy_executor::task]
async fn [<$name:snake _audio_player_task>](
audio_player_static: &'static $crate::audio_player::AudioPlayerStatic<$max_clips, { $sample_rate_hz }>,
pio: ::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$pio>,
dma: ::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$dma>,
data_pin: ::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$data_pin>,
bit_clock_pin: ::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$bit_clock_pin>,
word_select_pin: ::embassy_rp::Peri<'static, ::embassy_rp::peripherals::$word_select_pin>,
) -> ! {
$crate::audio_player::device_loop::<
$max_clips,
{ $sample_rate_hz },
::embassy_rp::peripherals::$pio,
::embassy_rp::peripherals::$dma,
::embassy_rp::peripherals::$data_pin,
::embassy_rp::peripherals::$bit_clock_pin,
::embassy_rp::peripherals::$word_select_pin,
>(audio_player_static, pio, dma, data_pin, bit_clock_pin, word_select_pin).await
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __audio_player_allowed_field {
(data_pin, $macro_name:literal) => {};
(sample_rate_hz, $macro_name:literal) => {};
(bit_clock_pin, $macro_name:literal) => {};
(word_select_pin, $macro_name:literal) => {};
(pio, $macro_name:literal) => {};
(dma, $macro_name:literal) => {};
(max_clips, $macro_name:literal) => {};
(max_volume, $macro_name:literal) => {};
(initial_volume, $macro_name:literal) => {};
($field:ident, $macro_name:literal) => {
compile_error!(concat!(
$macro_name,
" unknown field; expected `data_pin`, `sample_rate_hz`, `bit_clock_pin`, `word_select_pin`, `pio`, `dma`, `max_clips`, `max_volume`, or `initial_volume`"
));
};
}
#[doc(inline)]
pub use audio_player;
#[doc(inline)]
pub use tone;