From 26f96d2a42eb0888892fe9dba5cbabd5b5156eaa Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 25 Aug 2023 20:26:18 +0300 Subject: [PATCH] Kernel+Userland: Add option for duration of /dev/beep producing sound --- Base/usr/share/man/man1/beep.md | 3 +++ Kernel/API/BeepInstruction.h | 1 + Kernel/Devices/Generic/PCSpeakerDevice.cpp | 4 +++- Userland/Libraries/LibCore/System.cpp | 4 ++-- Userland/Libraries/LibCore/System.h | 2 +- Userland/Utilities/beep.cpp | 4 +++- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Base/usr/share/man/man1/beep.md b/Base/usr/share/man/man1/beep.md index 422e13c783..dd08bb4f05 100644 --- a/Base/usr/share/man/man1/beep.md +++ b/Base/usr/share/man/man1/beep.md @@ -15,6 +15,7 @@ beep allows the user to beep the PC speaker. ## Options * `-f frequency`, `--beep-tone frequency`: Beep tone (frequency in Hz) +* `-n N`, `--duration N`: Duration (N in milliseconds) ## Notes @@ -28,6 +29,8 @@ will fail to use the PC speaker. $ beep # Use beep with tone of 1000Hz $ beep -f 1000 +# Use beep with tone of 1000Hz for 1 second +$ beep -f 1000 -n 1000 ``` ## See also diff --git a/Kernel/API/BeepInstruction.h b/Kernel/API/BeepInstruction.h index 29ea3c21b2..28bbbce0f4 100644 --- a/Kernel/API/BeepInstruction.h +++ b/Kernel/API/BeepInstruction.h @@ -10,4 +10,5 @@ struct BeepInstruction { u16 tone; + u16 milliseconds_duration; }; diff --git a/Kernel/Devices/Generic/PCSpeakerDevice.cpp b/Kernel/Devices/Generic/PCSpeakerDevice.cpp index d17431923c..1b41ff8f02 100644 --- a/Kernel/Devices/Generic/PCSpeakerDevice.cpp +++ b/Kernel/Devices/Generic/PCSpeakerDevice.cpp @@ -48,9 +48,11 @@ ErrorOr PCSpeakerDevice::write(OpenFileDescription&, u64, UserOrKernelBu TRY(buffer.read(&instruction, sizeof(BeepInstruction))); if (instruction.tone < 20 || instruction.tone > 20000) return Error::from_errno(EINVAL); + if (instruction.milliseconds_duration == 0) + return Error::from_errno(EINVAL); #if ARCH(X86_64) PCSpeaker::tone_on(instruction.tone); - auto result = Thread::current()->sleep(Duration::from_nanoseconds(200'000'000)); + auto result = Thread::current()->sleep(Duration::from_milliseconds(instruction.milliseconds_duration)); PCSpeaker::tone_off(); if (result.was_interrupted()) return Error::from_errno(EINTR); diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index eb44deb85f..935a4b73f5 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -149,12 +149,12 @@ namespace Core::System { #ifdef AK_OS_SERENITY -ErrorOr beep(u16 tone) +ErrorOr beep(u16 tone, u16 milliseconds_duration) { static Optional beep_fd; if (!beep_fd.has_value()) beep_fd = TRY(Core::System::open("/dev/beep"sv, O_RDWR)); - BeepInstruction instruction { tone }; + BeepInstruction instruction { tone, milliseconds_duration }; TRY(Core::System::write(beep_fd.value(), Span(&instruction, sizeof(BeepInstruction)))); return {}; } diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index b035faaa92..08e9f20e8f 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -51,7 +51,7 @@ namespace Core::System { #ifdef AK_OS_SERENITY -ErrorOr beep(u16 tone = 440); +ErrorOr beep(u16 tone = 440, u16 milliseconds_duration = 200); ErrorOr pledge(StringView promises, StringView execpromises = {}); ErrorOr unveil(StringView path, StringView permissions); ErrorOr unveil_after_exec(StringView path, StringView permissions); diff --git a/Userland/Utilities/beep.cpp b/Userland/Utilities/beep.cpp index 9ea32ad92e..c21d73ca4c 100644 --- a/Userland/Utilities/beep.cpp +++ b/Userland/Utilities/beep.cpp @@ -11,9 +11,11 @@ ErrorOr serenity_main(Main::Arguments arguments) { Optional tone; + Optional milliseconds_duration; Core::ArgsParser args_parser; args_parser.add_option(tone, "Beep tone", "beep-tone", 'f', "Beep tone (frequency in Hz)"); + args_parser.add_option(milliseconds_duration, "Duration", "duration", 'n', "Duration (in milliseconds)"); args_parser.parse(arguments); - TRY(Core::System::beep(tone.value_or(440))); + TRY(Core::System::beep(tone.value_or(440), milliseconds_duration.value_or(200))); return 0; }