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}