beep_evdev/
beep.rs

1use std::io::Result;
2use std::thread::sleep;
3
4use evdev::{Device, EventType, InputEvent, SoundCode};
5
6use crate::Note;
7
8/// Allows to beep the PC speaker.
9pub trait Beep {
10    /// Beep the PC speaker at the given frequency.
11    ///
12    /// # Errors
13    ///
14    /// Returns an [`Error`] if beeping the PC speaker fails.
15    ///
16    /// # Examples
17    /// ```
18    /// use beep_evdev::{Beep, DEFAULT_FILE};
19    /// use std::{thread, time};
20    /// use evdev::Device;
21    ///
22    /// let mut pcspkr = Device::open(DEFAULT_FILE).unwrap();
23    /// pcspkr.beep(440).expect("could not beep");
24    /// thread::sleep(time::Duration::from_millis(500));
25    /// pcspkr.beep(880).expect("could not beep");
26    /// thread::sleep(time::Duration::from_millis(500));
27    /// pcspkr.beep(0).expect("could not beep");
28    fn beep(&mut self, hertz: u16) -> Result<()>;
29
30    /// Play the given note on the PC speaker.
31    ///
32    /// # Errors
33    ///
34    /// Returns an [`Error`] if beeping the PC speaker fails.
35    ///
36    /// # Examples
37    /// ```
38    /// use evdev::Device;
39    /// use beep_evdev::{Note, Beep, DEFAULT_FILE};
40    ///
41    /// let mut pcspkr = Device::open(DEFAULT_FILE)
42    ///     .unwrap()
43    ///     .note(&Note::default())
44    ///     .expect("could not play melody :-(");
45    /// ```
46    fn note(&mut self, note: &Note) -> Result<()> {
47        if note.repeats() > 0 {
48            self.beep(note.frequency())?;
49            sleep(note.length());
50            self.beep(0)?;
51        }
52
53        for _ in 1..note.repeats() {
54            sleep(note.delay());
55            self.beep(note.frequency())?;
56            sleep(note.length());
57            self.beep(0)?;
58        }
59
60        Ok(())
61    }
62
63    /// Play the given melody on the PC speaker.
64    ///
65    /// # Errors
66    ///
67    /// Returns an [`Error`] if beeping the PC speaker fails.
68    ///
69    /// # Examples
70    /// ```
71    /// use evdev::Device;
72    /// use beep_evdev::{Beep, Note, DEFAULT_FILE};
73    ///
74    /// let melody = vec![
75    ///     (659, 120).into(),
76    ///     (622, 120).into(),
77    ///     (659, 120).into(),
78    ///     (622, 120).into(),
79    ///     (659, 120).into(),
80    ///     (94, 120).into(),
81    ///     (587, 120).into(),
82    ///     (523, 120).into(),
83    ///     (440, 120).into(),
84    ///     (262, 120).into(),
85    ///     (330, 120).into(),
86    ///     (440, 120).into(),
87    ///     (494, 120).into(),
88    ///     (330, 120).into(),
89    ///     (415, 120).into(),
90    ///     (494, 120).into(),
91    ///     (523, 120).into(),
92    ///     (330, 120).into(),
93    ///     (659, 120).into(),
94    ///     (622, 120).into(),
95    ///     (659, 120).into(),
96    ///     (622, 120).into(),
97    ///     (659, 120).into(),
98    ///     (494, 120).into(),
99    ///     (587, 120).into(),
100    ///     (523, 120).into(),
101    ///     (440, 120).into(),
102    ///     (262, 120).into(),
103    ///     (330, 120).into(),
104    ///     (440, 120).into(),
105    ///     (494, 120).into(),
106    ///     (330, 120).into(),
107    ///     (523, 120).into(),
108    ///     (494, 120).into(),
109    ///     (440, 120).into(),
110    /// ];
111    ///
112    /// Device::open(DEFAULT_FILE)
113    ///     .expect("could not open pcspkr device")
114    ///     .play(&melody)
115    ///     .expect("could not play melody :-(");
116    /// ```
117    fn play<T>(&mut self, melody: T) -> Result<()>
118    where
119        T: AsRef<[Note]>,
120    {
121        for note in melody.as_ref() {
122            self.note(note)?;
123        }
124
125        Ok(())
126    }
127}
128
129impl Beep for Device {
130    fn beep(&mut self, hertz: u16) -> Result<()> {
131        self.send_events(&[InputEvent::new(
132            EventType::SOUND.0,
133            SoundCode::SND_TONE.0,
134            i32::from(hertz),
135        )])
136    }
137}