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}