#![cfg_attr(
not(bela_device),
allow(
dead_code,
reason = "only the fallback main is reachable off-device; the application code should still compile and lint"
)
)]
use core::f32::consts::TAU;
#[cfg(not(bela_device))]
use std::process::ExitCode;
use bela::{BelaApplication, BlockContext, RenderContext, SetupContext, ThreadInfo};
const FREQUENCY: f32 = 440.0;
const AMPLITUDE: f32 = 0.3;
struct Sine {
phase: f32,
phase_increment: f32,
}
impl Sine {
const fn new() -> Self {
Self {
phase: 0.0,
phase_increment: 0.0,
}
}
}
struct Phase {
first_frame: usize,
phase: f32,
}
impl BelaApplication for Sine {
type RenderState = Phase;
fn setup(&mut self, context: &SetupContext) -> bool {
self.phase_increment = TAU * FREQUENCY / context.audio_sample_rate();
true
}
fn create_render_state(&mut self, thread: ThreadInfo, context: &SetupContext) -> Phase {
Phase {
first_frame: thread.frame_range(context.audio_frames()).start,
phase: 0.0,
}
}
fn render_pre(&mut self, states: &mut [Phase], _context: &mut BlockContext) {
for state in states {
#[allow(
clippy::cast_precision_loss,
reason = "a frame index within a block is far below f32's exact integer range"
)]
let offset = state.first_frame as f32 * self.phase_increment;
state.phase = self.phase + offset;
}
}
fn render(&self, state: &mut Phase, context: &mut RenderContext) {
for frame in context.audio_frame_range() {
let sample = AMPLITUDE * state.phase.sin();
for channel in 0..context.audio_out_channels() {
context.audio_write(frame, channel, sample);
}
state.phase += self.phase_increment;
}
}
fn render_post(&mut self, _states: &mut [Phase], context: &mut BlockContext) {
#[allow(
clippy::cast_precision_loss,
reason = "a block's frame count is far below f32's exact integer range"
)]
let advanced = context.audio_frames() as f32 * self.phase_increment;
self.phase = (self.phase + advanced) % TAU;
}
}
#[cfg(bela_device)]
fn main() -> Result<(), bela::Error> {
bela::Bela::run(Sine::new(), &bela::Settings::new())
}
#[cfg(not(bela_device))]
fn main() -> ExitCode {
eprintln!("This example must be cross-compiled for Bela Gem (aarch64-unknown-linux-gnu).");
ExitCode::FAILURE
}