Skip to main content

endbasic_std/sound/
mod.rs

1// EndBASIC
2// Copyright 2026 Julio Merino
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Affero General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program.  If not, see <https://www.gnu.org/licenses/>.
16
17//! Sound manipulation for the EndBASIC console.
18
19use async_trait::async_trait;
20use std::io;
21use std::time::Duration;
22
23pub(super) mod cmds;
24
25/// Default tone for the `beep` primitive.
26// If modifying this, don't forget to update the `BeepCommand` docstring.
27pub const BEEP_TONE: Tone = Tone::square(800, Duration::from_millis(250));
28
29/// Waveform to use when reproducing a tone.
30#[derive(Clone, Copy, Debug, Eq, PartialEq)]
31pub enum Waveform {
32    /// Square wave.
33    Square,
34}
35
36/// Description of a tone to reproduce.
37#[derive(Clone, Copy, Debug, Eq, PartialEq)]
38pub struct Tone {
39    /// Frequency of the tone in hertz.
40    pub frequency_hz: u32,
41
42    /// Duration of the tone.
43    pub duration: Duration,
44
45    /// Waveform of the tone.
46    pub waveform: Waveform,
47}
48
49impl Tone {
50    /// Constructs a square-wave tone.
51    pub const fn square(frequency_hz: u32, duration: Duration) -> Self {
52        Self { frequency_hz, duration, waveform: Waveform::Square }
53    }
54}
55
56/// Primitive audio operations.
57#[async_trait(?Send)]
58pub trait AudioOps {
59    /// Reproduces `tone` and returns once playback completes.
60    async fn play_tone(&mut self, tone: Tone) -> io::Result<()>;
61}
62
63/// Audio backend that always reports the feature as unsupported.
64pub struct NoopAudioOps;
65
66#[async_trait(?Send)]
67impl AudioOps for NoopAudioOps {
68    async fn play_tone(&mut self, _tone: Tone) -> io::Result<()> {
69        Err(io::Error::other("No audio support in this console"))
70    }
71}