Board logo

标题: [系统相关] 批处理一种新的响铃方式 [打印本页]

作者: qzwqzw    时间: 2025-3-7 09:40     标题: 批处理一种新的响铃方式

之前在xp下测试成功的echo 响铃方式
在win10下出现了问题
通过声卡扬声器发出的声音更加悠长顿挫
完全不是之前哪种短促单一的高频音调
而且会把多个响铃符号理解为一个响铃符号处理

经过一段时间测试
发现不同的主机和系统环境
发出来的声调可能不尽相同

为了找回之前哪种传统的声音
我试了多种方法
目前测试到使用方法
可以恢复短促单一可多次使用的响铃声
其主要原理是利用choice的无效选项字符触发响铃
  1. rem 响铃1次
  2. echo 1y|choice /t 10 /d y>nul
  3. rem 连续响铃5次
  4. echo 12345y|choice /t 10 /d y>nul
复制代码
看看大家还有什么新思路?
作者: 523066680    时间: 2025-3-7 10:32

本帖最后由 523066680 于 2025-3-7 10:51 编辑

这种大概是函数生成波形,通过win32的音频接口发声。

perl有一个 Auido::Beep 可以简单地播放指定频率/波形的声音
  1. #functional simple way
  2. use Audio::Beep;
  3. beep(880, 1000); # freq, duration
复制代码
---
然后追溯一下 Audio::Beep 的模块代码,是调用 Win32::API
  1. use strict;
  2. use Carp;
  3. use Win32::API;
  4. sub new {
  5.     my $class = shift;
  6.     my $player = Win32::API->new('kernel32', 'Beep', 'NN', 'N')
  7.         or croak "Cannot initialize " . __PACKAGE__ . " object";
  8.     return bless {
  9.         player  => $player
  10.     }, $class;
  11. }
  12. sub play {
  13.     my $self = shift;
  14.     my ($freq, $duration) = @_;
  15.     return $self->{player}->Call(sprintf("%.0f", $freq), $duration);
  16. }
复制代码
---
问一下kimi,结果更直接
  1. #include <windows.h>  // 包含Windows API的头文件
  2. #include <stdio.h>
  3. int main() {
  4.     // 调用Beep函数,参数分别为频率(Hz)和持续时间(毫秒)
  5.     Beep(800, 1000);  // 频率800Hz,持续时间1000ms(1秒)
  6.     printf("Beep sound played.\n");
  7.     return 0;
  8. }
复制代码

作者: 523066680    时间: 2025-3-7 11:39

唤起远古的记忆,折腾过一阵子音频,但是完全忘记了
  1. use Time::HiRes qw/time/;
  2. use Win32::Sound;
  3. # Create the object
  4. my $WAV = new Win32::Sound::WaveOut(44100, 8, 2);
  5. Win32::Sound::Volume('50%', '50%');
  6. my $data = "";
  7. my $samples = 44100; # 采样率
  8. my $freq = 800;      # 波的频率 -> 每秒震动的次数
  9. my $M_2PI = 2.0 * 3.1415926;
  10. for ( my $frame = 0.0; $frame < $samples; $frame += 1.0 )
  11. {
  12.     # (0.0 ~ 1.0) * 2PI * $freq 次周期震荡
  13.     my $rad = ($frame / $samples) * $M_2PI * $freq;
  14.     # 波的采样值,范围从 1 ~ 255
  15.     my $v = sin($rad) * 127 + 128;
  16.     # "pack" it twice for left and right
  17.     $data .= pack("CC", $v, $v);
  18. }
  19. printf "%.2f\n", time();
  20. $WAV->Load($data);       # get it
  21. $WAV->Write();           # hear it
  22. 1 until $WAV->Status();  # wait for completion
  23. printf "%.2f\n", time();
  24. $WAV->Save("sinus.wav"); # write to disk
  25. $WAV->Unload();          # drop it
复制代码

作者: qzwqzw    时间: 2025-3-7 11:41

本帖最后由 qzwqzw 于 2025-3-7 12:02 编辑

回复 2# 523066680


经网络搜索,beep函数在新版本windows下已不可用蜂鸣器,也是改用声卡+扬声器输出
而且似乎在Win32 API函数中已经修改了,要使用主板自带蜂鸣器还需要调用ring0层的IO函数
https://blog.csdn.net/weixin_44290011/article/details/112348304#

另外下面的链接里也提到了在win10下用windbg的本地内核调试方法
同时也是ring0层的思路,需要用到管理员权限
https://01.me/en/2016/12/beep-in-windows-10/

没有perl环境,我用C++环境下试验了下那个kimi给出的beep代码
确认在win10下C的beep也是用声卡扬声器发声的
频率和延时都是有效的

看来唯独是cmd下的这个响铃符号被转移到了媒体文件上
C:\Windows\media\Windows Foreground.wav
作者: Five66    时间: 2025-3-7 13:17

调用播放器播放响铃音频文件
作者: semiuel    时间: 2025-3-7 15:16

30年前我用QBASIC播放音乐
作者: qzwqzw    时间: 2025-3-7 16:21

调用播放器播放响铃音频文件
Five66 发表于 2025-3-7 13:17



    那倒不至于,CMD的所在的conhost.exe可以调用Win32 API播放,一个很常见的WAV还用不到媒体播放器的GUI+库
作者: qzwqzw    时间: 2025-3-7 16:27

30年前我用QBASIC播放音乐
semiuel 发表于 2025-3-7 15:16



    又一个暴露年龄段的

还记得从电脑期刊上抄过C语言编写的《月夜奔马图》,运行效果刚出来的那一刻,感觉震撼的无与伦比,一下子感觉那台破386也有了浪漫的气息
作者: smss    时间: 6 天前 06:03

  1. @echo off&setlocal enabledelayedexpansion
  2. (set S=212 212 190 212 159 169 212 212 190 212 142 159 212 212 106 126 159 169 190 119 119 126 159 142 159)&(set L=9 3 12 12 12 24 9 3 12 12 12 24 9 3 12 12 12 12 12 9 3 12 12 12 24)
  3. set "L= !L!"&for %%A in (%S%)do @for /f "tokens=1*" %%B in ("!L!")do @(set "L=%%C"&set/at=400000/%%A,d=%%B*20 2>nul&&powershell "[Console]::Beep(!t!,!d!)" 2>nul)
  4. pause
复制代码

作者: qzwqzw    时间: 6 天前 08:36

回复 9# smss


    powershell的[console]用法倒是第一次见到;感觉这段脚本不像临时写的,有些细节在这里根本用不到,比如set L= !L!,而且在脚本中也不需要那么多@。

搜了下,能见到的最早应用在PowerTip: Use PowerShell to Send Beep to Console

这里可以找到.net API关于Beep方法文档

另外在stackoverflow看到了另外一种ps的转义字符用法
  1. Write-Host -NoNewLine "`a"
复制代码
也才注意到使用echo ^G方法响铃,会在窗口标题栏显示响铃图标
作者: qzwqzw    时间: 6 天前 23:10

新发现了一个nircmd的方法
  1. nircmdc beep [Frequency] [Duration]
复制代码
而且还可以用它播放系统声音方案的配置声音
  1. nircmdc stdbeep
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2